I am trying to use the KissFFT Library with this 11 second 44kHz .wav sample file as a test input.
However as I process the file with a window size of 512, I am getting only 1 output value. Which is weird, the 11 sec .wav file at 44kHz should not give 1 value as an output with a windows size of 512. A smaller windows like 16 would give me 5 values, which is still a low count.
Does anyone know what I am doing wrong?
This is my code:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#define WIN 512
int main()
{
char *music_file = "C:/MSin44W16-13.wav";
FILE *in;
char buf[WIN * 2];
int nfft = WIN, i, fx;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
in = fopen(music_file, "r");
if (!in) {
printf("unable to open file: %s\n", music_file);
perror("Error");
return 1;
}
fx = 0;
while (fread(buf, 1, WIN * 2, in))
{
for (i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
free(cfg);
scanf("%d");
return 0;
}
This is the output I get:
42.7577
This is the Updated Code version, but I am getting errors at compile:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include "kiss_fft.h"
#include "sndfile.h"
#define WIN 512
int main()
{
char *music_file = "C:/voice.wav";
SNDFILE *infile;
SF_INFO sfinfo;
//int readcount;
short buf[WIN * 2];
int nfft = WIN;
double intensity = 0;
kiss_fft_cfg cfg;
kiss_fft_cpx cx_in[WIN];
kiss_fft_cpx cx_out[WIN];
short *sh;
cfg = kiss_fft_alloc(nfft, 0, 0, 0);
if (!( infile = sf_open(music_file, SFM_READ, &sfinfo) ))
{ /* Open failed so print an error message. */
printf("Not able to open input file %s.\n", "input.wav");
/* Print the error message fron libsndfile. */
sf_perror(NULL);
return 1;
}
while ((sf_read_short(infile, buf, WIN)))//fread(buf, 1, WIN * 2, in)
{
//system("cls");
for (int i = 0;i<WIN;i++) {
sh = (short *)&buf[i * 2];
cx_in[i].r = (float) (((double)*sh) / 32768.0);
cx_in[i].i = 0.0;
}
kiss_fft(cfg, cx_in, cx_out);
//Display the value of a position
int position = 511;
intensity = sqrt(pow(cx_out[position].r, 2) + pow(cx_out[position].i, 2));
printf("%9.4f\n", intensity);
//Display all values
/*
for (i = 0;i<WIN;i++) {
//printf("Joe: cx_out[i].r:%f\n", cx_out[i].r);
//printf("Joe: cx_out[i].i:%f\n", cx_out[i].i);
intensity = sqrt(pow(cx_out[i].r,2) + pow(cx_out[i].i,2));
printf("%d - %9.4f\n", i, intensity);
}
*/
}
sf_close(infile);
free(cfg);
int temp;
scanf_s("%d", &temp);
return 0;
}
I followed the steps on this post:
"error LNK2019: unresolved external symbol" error in Visual Studio 2010
And I still get these errors:
The problem does not comes from KissFFT, but rather from the fact that you are trying to read a binary wave file opened in ASCII mode on the line:
in = fopen(music_file, "r");
As you later try to read data with fread you eventually hit an invalid character. In your specific sample file, the 215th character read is the Substitute Character (hex value 0x1A), which is interpreted as an end of file marker by your C runtime library. Correspondingly, fread stops filling in more data and eventually return 0 (at the second iteration with WIN set to 512 and a little later with WIN set to 16).
To get around this problem, you should open the file in binary more with:
in = fopen(music_file, "rb");
Note that this will ensure the binary data is read as-is into your input buffer, but would not decode the wave file header for you. To properly read and decode a wave file and get meaningful data in, you should look into using an audio library (such as libsndfile to name one). If you must roll your own wave file reader you should read the specifications and/or check out one of many tutorials on the topic.
Related
I'm working with an EFM32wg280f256 and I would like to debug the code that I'm writing in the following manner: opening a file in SD memory and write the content of the buffers I'm using.
This is a minimal example of my attempt:
#include <stdbool.h>
#include "ff.h"
#include <stdio.h>
#include <complex.h>
#include "arm_math.h"
#include "audioMoth.h"
#define NUMBER_OF_SAMPLES_IN_BUFFERS_DATA 4
static float32_t* buffersDATA[12];
int main(void) {
//Create buffers
buffersDATA[0] = (float32_t*)AM_EXTERNAL_SRAM_START_ADDRESS;
for (int i = 1; i < 12; i += 1) {
buffersDATA[i] = buffersDATA[i - 1] + NUMBER_OF_SAMPLES_IN_BUFFERS_DATA;
}
//Example of collected data
float32_t var0[] = {-29.499557,-67.498978,-54.499176,-53.499191};
//Pass collected data to one of created buffers
for (int j = 0; j <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; j+= 1){
*(buffersDATA[0]+j) = var0[j];
}
//Initialize file system
AudioMoth_enableFileSystem();
// Write text file
FIL fpt;
f_open(&fpt,"dataVAR.txt", FA_CREATE_ALWAYS | FA_WRITE);
for (int i = 0; i <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; i+= 1){
char str[8];
sprintf(str, "%d, ", (int)var0[i]);
f_puts(str,&fpt);
}
f_close(&fpt);
// Write another text file
FIL fptr;
f_open(&fptr,"data.txt", FA_CREATE_ALWAYS | FA_WRITE);
for (int i = 0; i <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; i+= 1){
char str[8];
sprintf(str, "%d, ", (int)*(buffersDATA[0]+i));
f_puts(str,&fptr);
}
f_close(&fptr);
}
Typecasting is because sprintf does not support float values, but integer is enough for me to know if I am doing OK or not.
When I open dataVAR.txt:
-29, -67, -54, -53,
But data.txt:
0, 0, 0, 0,
when they should be the same.
I've tried the same in a executable (adapting it) to verify that I am correctly passing the values (it seems so).
Where is the problem?
Thanks in advance.
Ok, the problem was that I didn't initialize communication between the microcontroller and the external chip of SRAM.
I did and all worked as expected.
I need a way to play certain musical notes in my C program on Linux.
When using windows, it is possible to #include <dos.h> and use straight forward functions like sound(note/frequency), delay(time in ms), and the self explaining nosound().
Is there anything parallel on Linux?
Thanks
I like the tip above concerning libao - I just gave it a try and it works nicely. Here is a similar level of complexity using OpenAL to synthesize a raw audio buffer in PCM format then to render as audio
// sudo apt-get install libopenal-dev
// gcc -o openal_play_monday openal_play_monday.c -lopenal -lm
#include <stdio.h>
#include <stdlib.h> // gives malloc
#include <math.h>
#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#elif __linux
#include <AL/al.h>
#include <AL/alc.h>
#include <unistd.h>
#endif
ALCdevice * openal_output_device;
ALCcontext * openal_output_context;
ALuint internal_buffer;
ALuint streaming_source[1];
int al_check_error(const char * given_label) {
ALenum al_error;
al_error = alGetError();
if(AL_NO_ERROR != al_error) {
printf("ERROR - %s (%s)\n", alGetString(al_error), given_label);
return al_error;
}
return 0;
}
void MM_init_al() {
const char * defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
openal_output_device = alcOpenDevice(defname);
openal_output_context = alcCreateContext(openal_output_device, NULL);
alcMakeContextCurrent(openal_output_context);
// setup buffer and source
alGenBuffers(1, & internal_buffer);
al_check_error("failed call to alGenBuffers");
}
void MM_exit_al() {
ALenum errorCode = 0;
// Stop the sources
alSourceStopv(1, & streaming_source[0]); // streaming_source
int ii;
for (ii = 0; ii < 1; ++ii) {
alSourcei(streaming_source[ii], AL_BUFFER, 0);
}
// Clean-up
alDeleteSources(1, &streaming_source[0]);
alDeleteBuffers(16, &streaming_source[0]);
errorCode = alGetError();
alcMakeContextCurrent(NULL);
errorCode = alGetError();
alcDestroyContext(openal_output_context);
alcCloseDevice(openal_output_device);
}
void MM_render_one_buffer() {
/* Fill buffer with Sine-Wave */
// float freq = 440.f;
float freq = 100.f;
float incr_freq = 0.1f;
int seconds = 4;
// unsigned sample_rate = 22050;
unsigned sample_rate = 44100;
double my_pi = 3.14159;
size_t buf_size = seconds * sample_rate;
// allocate PCM audio buffer
short * samples = malloc(sizeof(short) * buf_size);
printf("\nhere is freq %f\n", freq);
int i=0;
for(; i<buf_size; ++i) {
samples[i] = 32760 * sin( (2.f * my_pi * freq)/sample_rate * i );
freq += incr_freq; // change freq just to make things interesting
if (100.0 > freq || freq > 5000.0) {
incr_freq *= -1.0f; // toggle direction of freq increment
}
}
/* upload buffer to OpenAL */
alBufferData( internal_buffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
al_check_error("populating alBufferData");
free(samples);
/* Set-up sound source and play buffer */
// ALuint src = 0;
// alGenSources(1, &src);
// alSourcei(src, AL_BUFFER, internal_buffer);
alGenSources(1, & streaming_source[0]);
alSourcei(streaming_source[0], AL_BUFFER, internal_buffer);
// alSourcePlay(src);
alSourcePlay(streaming_source[0]);
// ---------------------
ALenum current_playing_state;
alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
al_check_error("alGetSourcei AL_SOURCE_STATE");
while (AL_PLAYING == current_playing_state) {
printf("still playing ... so sleep\n");
sleep(1); // should use a thread sleep NOT sleep() for a more responsive finish
alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
al_check_error("alGetSourcei AL_SOURCE_STATE");
}
printf("end of playing\n");
/* Dealloc OpenAL */
MM_exit_al();
} // MM_render_one_buffer
int main() {
MM_init_al();
MM_render_one_buffer();
}
If you want to take OpenAL further ... take a gander at this
https://github.com/scottstensland/render-audio-openal
Out of the box OpenAL plays a buffer of PCM audio just fine ... however it leaves as an exercise the ability to play a stream. In that github repo I wrote an audio server using OpenAL which implements playing streaming audio ... enjoy
Windows uses its own one and only sound architecture, therefore you can access the sound() routine.
Different linux machines, depending on the packages installed, may require different approaches.
Maybe the utility beep (out of this question on stackexchange) can guide you to the right direction
one way
including
#include<conio.h>
and in side main() or where you want to use call print("\a")
printf("\a");
2nd way
including header file
#include <windows.h>
and calling function
Beep(500, 500);
Beep(freq, dur); where freq =beep frequency which is int and dutation in also int
I wrote a C code which extracts data from a binary file which has size around 1 GB. There are 101 (0 to 100)configurations and the C code extracts data for a selected configuration and writes the output in a file. To compile the C code, I give user defined configuration number like this in the terminal:
gcc binary2textperconfig.c -o f.out
./f.out proton-p000-1.bin out1.txt
Then it asks for configuration number:
Enter the configuration number:
After that the data is written in file "out0.txt". Now I want to run this code for all 101 configurations and write those data to files "out0.txt", "out1.txt",...., "out100.txt" etc. I don't know how to do this without typing the configuration numbers 101 times in the terminal. Could any one please help me? Here is my C-code:
#include <stdio.h>
#include<complex.h>
#include<math.h>
#include <stdlib.h>
#include <gsl/gsl_sf_gamma.h>
#include <gsl/gsl_matrix.h>
typedef double complex dcomplex;
//Data is converted to Bigendian using io-general
double constructfloat(char bytes[sizeof(double)/2], int order)
{
double dRes;
char *pc;
int i;
if (order == 0)
for(i=0, pc = (char*) &dRes; i<=sizeof(double)-1 ; i++, pc++)
(*pc) = bytes[i];
else
for(i=sizeof(double)-1, pc = (char*) &dRes; i>=0; i--, pc++)
(*pc) = bytes[i];
return dRes;
}
int main(int argc, char *argv[]){
int configcount = 101;
int mcount = 14;
int tcount = 64;
int d1count = 4;
int d2count = 4;
int pcount = 45;
int userci;
int usermi;
int userpi;
// number of complex numbers per configuration
int unitcountperconfig =(mcount*tcount*d1count*d2count*pcount);
// initialize loop index variables
int ci = 0; //config
int mi = 0; //mass
int ti = 0;
int d1i = 0;
int d2i = 0;
int pi = 0; //momentum
// for holding the result of read operation ( how many units have been read)
int result;
// for holding the data read from file
char * cbuff;
// input file handle from where binary data is read
FILE * fin = fopen(argv[1],"rb");
// if the input file cannot be read for reading, close opened file handles, show an error message to the user, and exit
if (fin==NULL)
{
fputs ("Error opening input file\n",stderr);
exit (1);
}
FILE * fout = fopen(argv[2],"wt");
// if the output file cannot be opened for writing, close opened file handles, show an error message to the user, and exit
if (fout==NULL)
{
fclose(fin);
fputs ("Error opening output file\n",stderr);
exit (1);
}
// take input from the user
// take input from the user
printf("Enter the configuration number: ");
scanf("%d",&userci);
// allocate memory to contain the chunk of data for a time slice:
cbuff = (char*)malloc(sizeof(dcomplex)*unitcountperconfig );
// show error message and exit if memory allocation failed
if(cbuff == NULL)
{
fputs("Buffer allocation failed.", stderr);
exit(1);
}
// variable to hold a complex number read from the file
dcomplex aComplexNumber;
dcomplex sumpertimeslice[tcount];
// loop on time slices
for( ci = 0; ci< configcount ; ci++){
// index of the complex number being read
unsigned int cNumberIdx = 0;
// debugging message
printf("reading data for configuration: %d\n",ci);
// perform read operation to read the desired chunk of data
result = fread(cbuff, sizeof(char), sizeof(dcomplex)*unitcountperconfig, fin );
// if size of data successfully read is not equal to what we wanted to read, notify the user and exit
if (result != sizeof(dcomplex)*unitcountperconfig) {
fputs ("data reading error\n",stderr);
exit (3);
}
double realP;
double imagP;// variable to hold real and imaginary part of the complex number
double realPSum;
double imagPSum;// variable to hold sum of real and sum of imaginary part of the current sum per time slice
for (mi =0; mi< mcount ; mi++){
for (ti =0; ti< tcount ; ti++){
// array to hold trace for each time slice
sumpertimeslice[ti] = 0.0 + 0.0*_Complex_I;
for (d1i =0; d1i < d1count ; d1i++){
for (d2i =0; d2i < d2count ; d2i++){
for (pi =0; pi < pcount ; pi++){
aComplexNumber = constructfloat( &cbuff[cNumberIdx], 0 ) + constructfloat( &cbuff[cNumberIdx+ ((int)sizeof(dcomplex))/2 ], 0 )*_Complex_I;
if (ci== userci)
{
cNumberIdx += (int)sizeof(dcomplex);
if (cimag(aComplexNumber)>0)
{fprintf( fout, "%d,%d,%d,%d,%d,%d,%e+%ei\n" ,ci+1, mi+1,ti+1, d1i+1,d2i+1,pi+1,creal( aComplexNumber ),cimag( aComplexNumber ) );}
else
{fprintf( fout, "%d,%d,%d,%d,%d,%d,%e%ei\n" ,ci+1, mi+1,ti+1, d1i+1,d2i+1,pi+1,creal( aComplexNumber ),cimag( aComplexNumber ) );}
}
}
}
}
}
}
}
// free the allocated memory
free(cbuff);
// close the opened file handles
fclose(fin);
fclose(fout);
//fclose(complexNumberFileP);
}
Use the seq utility to generate a list of number between 0 & 100, and send it as a string to stdin.
for CNUMBER in $(seq 0 100); do
./f.out proton-p000-1.bin out${CNUMBER}.txt <<< "${CNUMBER}"
done
or
for CNUMBER in $(seq 0 100); do
echo $CNUMBER | ./f.out proton-p000-1.bin out${CNUMBER}.txt
done
I am trying to implement a simple audio delay in C.
i previously made a test delay program which operated on a printed sinewave and worked effectively.
I tried incorporating my delay as the process in the SFProcess - libsndfile- replacing the sinewave inputs with my audio 'data' input.
I nearly have it but instead of a clean sample delay I am getting all sorts of glitching and distortion.
Any ideas on how to correct this?
#include <stdio.h>
#include </usr/local/include/sndfile.h>//libsamplerate libsamplerate
//#include </usr/local/include/samplerate.h>
#define BUFFER_LEN 1024 //defines buffer length
#define MAX_CHANNELS 2 //defines max channels
static void process_data (double *data, double*circular,int count, int numchannels, int circular_pointer );
enum {DT_PROGNAME,ARG_INFILE,ARG_OUTFILE,ARG_NARGS, DT_VOL};
int main (int argc, const char * argv[])//Main
{
static double data [BUFFER_LEN]; // the buffer that carries the samples
double circular [44100] = {0}; // the circular buffer for the delay
for (int i = 0; i < 44100; i++) { circular[i] = 0; } // zero the circular buffer
int circular_pointer = 0; // where we currently are in the circular buffer
//float myvolume; // the volume entered by the user as optional 3rd argument
SNDFILE *infile, *outfile;
SF_INFO sfinfo;
int readcount;
const char *infilename = NULL;
const char *outfilename = NULL;
if(argc < ARG_NARGS) {
printf("usage: %s infile outfile\n",argv[DT_PROGNAME]);
return 1;
}
//if(argc > ARG_NARGS) {
//
// myvolume = argv[DT_VOL];
//};
infilename = argv[ARG_INFILE];
outfilename = argv[ARG_OUTFILE];
if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
{printf ("Not able to open input file %s.\n", infilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
};
if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)))
{ printf ("Not able to open output file %s.\n", outfilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
} ;
while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
{ process_data (data, circular, readcount, sfinfo.channels, circular_pointer) ;
sf_write_double (outfile, data, readcount) ;
};
sf_close (infile) ;
sf_close (outfile) ;
printf("the sample rate is %d\n", sfinfo.samplerate);
return 0;
}
static void process_data (double *data, double *circular, int count, int numchannels, int circular_pointer) {
//int j,k;
//float vol = 1;
int playhead;
int wraparound = 10000;
float delay = 1000; // delay time in samples
for (int ind = 0; ind < BUFFER_LEN; ind++){
circular_pointer = fmod(ind,wraparound); // wrap around pointer
circular[circular_pointer] = data[ind];
playhead = fmod(ind-delay, wraparound); // read the delayed signal
data[ind] = circular[playhead]; // output delayed signal
circular[ind] = data[ind]; // write the incoming signal
};
//volume
/*for (j=0; j<numchannels; j++) {
for (k=0; k<count; k++){
data[k] = data[k]*-vol;*/
//}printf ("the volume is %f", vol);
return;
}
There are a few issues with your code that are causing you to access out of your array bounds and to not read\write your circular buffer in the way intended.
I would suggest reading http://en.wikipedia.org/wiki/Circular_buffer to get a better understanding of circular buffers.
The main issues your code is suffering:
circular_pointer should be initialised to the delay amount (essentially the write head is starting at 0 so there is never any delay!)
playhead and circular_buffer are not updated between calls to process_data (circular_buffer is passed by value...)
playhead is reading from negative indices. The correct playhead calculation is
#define MAX_DELAY 44100
playhead++;
playhead = playhead%MAX_DELAY;
The second write to circular_buffer at the end of process_data is unnecessary and incorrect.
I would strongly suggest spending some time running your code in a debugger and closely watching what your playhead and circular_pointer are doing.
Mike
At least one problem is that you pass circular_pointer by value, not by reference. When you update it in the function, it's back to the same value next time you call the function.
I think you are on the right track, here, but if you want something that's structured a bit better, you might also want to checkout this answer:
how to add echo effect on audio file using objective-c
delay in sample can be put as 100 ms would be sufficient
I'm running a piece of C code that takes information from 10 Dynamixel servo motors ( ID, position, angle , load-torque ) and prints them to the screen as well as writes it to a log file ( watchdog_log.txt).
#include <stdio.h>
#include <stdlib.h>
#include <termio.h>
#include <unistd.h>
#include <string.h>
#include <dynamixel.h>
#include <math.h>
#include <dynamixelAX.h>
#include "utils_v2.h"
#include "low_level_v2AX.h"
#include "low_level_v2.h"
// Control table address
#define P_GOAL_POSITION_L 30
#define P_GOAL_POSITION_H 31
#define P_PRESENT_POSITION_L 36
#define P_PRESENT_POSITION_H 37
#define P_MOVING 46
// Defulat setting
#define DEFAULT_BAUDNUM 34 // 1Mbps
#define DEFAULT_BAUDNUM_AX 1
#define DEFAULT_ID 1
int main()
{
FILE *fp;
/* Get actuator ID from command line argument */
int baudnum = 34;
int baudnum_AX = 1;
int deviceIndex = 0;
int deviceIndex_AX = 1;
int current;
float load, angle;
int i=0;
int MOTOR_CHAIN[13]={-1,1,1,0,0,0,-1,1,1,0,0,0,-1};
int MOTOR_CHAIN_AX[18]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
int MOTOR_HOME[13]={404,444,3216,2037,2289,512,860,661,879,3474,1747,512}; //0, 6 and 12 are dummy
int MOTOR_HOME_AX[18]={512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,};
char report[1000];
char buffer[50];
strcpy(report,"***********\n");
/* Initialise Open USB2Dynamixel */
if( dxl_initialize(deviceIndex, baudnum) == 0 )
{
printf( "Failed to open USB2Dynamixel!-chain'0'\n" );
printf( "Press Enter key to terminate...\n" );
}
else
printf( "Successfully opened USB2Dynamixel 0!\n" );
if( dxl_initializeAX(deviceIndex_AX, baudnum_AX) == 0 )
{
printf( "Failed to open USB2Dynamixel!-chain'1'\n" );
printf( "Press Enter key to terminate...\n" );
}
else
printf( "Successfully opened USB2Dynamixel 1!\n" );
/* Ping all devices */
printf("Pinging devices...");
for( i=0; i<=12; i++)
{
dxl_ping(i);
if (dxl_get_result() == COMM_RXSUCCESS)
{
current = (fabs(dxl_read_word(i, 0x34)-512)*10);
load = dxl_read_word(i, 0x28);
if (load>=1024)
load=(load-1024)*0.1;
else load=load*0.1;
int theta = dxl_read_word(i, 36);
angle = counttoangle(MOTOR_CHAIN[i], MOTOR_HOME[i], theta);
printf("ID: %d success, Load: %3.1f, Count = %d, Angle = %3.2f\n", i, load, theta, angle) ;
sprintf(buffer,"ID: %d success, Load: %3.1f, Count = %d, Angle = %3.2f\n",i, load, theta, angle);
strcat(report,buffer);
}
else printf("ID: %d failure\n",i);
}
//File operations
strcat(report,"***********\n\n\n");
fp = fopen("watchdog_log.txt","w"); /* append file (add text to a file or create a file if it does not exist.*/
fprintf(fp,"%s",report); /*writes to file*/
fclose(fp); /*done!*/**
/* Close device */
dxl_terminateAX();
return 0;
}
I am running the code every one second using 'watch' command on Ubuntu to constantly monitor the output of the code on the screen.
watch -n 1 ./watchdog
The output on the terminal is normal when file operations are not done. But when file writing is done, the terminal gives bizzare outputs:
Normal Output
Bizzare Output
Any help on the above problem will be appreciated.
At first glance probles is in your variables:
char report[1000];
char buffer[50];
they are overflowed whe you are working with them.
for example
sprintf(buffer,"ID: %d success, Load: %3.1f, Count = %d, Angle = %3.2f\n",i, load, theta, angle);
The minimum size of the string is greater than 50 bytes!
So you can try increase the size of your string vars or calc needed size and allocate them in heap ...