Reputation: 644
I'm working on an small tool that reads data from an wav file. This tool first extracts the header followed by separating the audio data into left and right channel. Audio files are just files with a sampling frequency of 44100Hz, 16Bit PCM and dual-channel.
After manipulating the data I want to write back the data to an output file and append 100 zeros on each channel. Here the problem occurs: first just half of the desired samples are append on each channel. Secondly the first half of the appended 'zeros' are random data.
See my code below
#include <stdlib.h>
#include <stdio.h>
#define BUFFSIZE 1024
#define NUM_ZEROS 100
#include <stdio.h>
#include <stdlib.h>
typedef struct header_file
{
char chunk_id[4];
int chunk_size;
char format[4];
char subchunk1_id[4];
int subchunk1_size;
short int audio_format;
short int num_channels;
int sample_rate;
int byte_rate;
short int block_align;
short int bits_per_sample;
char subchunk2_id[4];
int subchunk2_size;
} header;
typedef struct header_file* header_p;
int main(int argc, char** argv){
if( argc != 3 ){
printf("Wrong number of input arguments. Aborting.\n");
return -1;
}
char *inputFile = argv[1];
char *outputFile = argv[2];
FILE * infile = fopen(inputFile, "r+");
FILE * outfile = fopen(outputFile, "w+");
int count = 0; // For counting number of frames in wave file.
short int buff16[2*BUFFSIZE]; // short int used for 16 bit as input data format is 16 bit PCM audio
short int buffLeft[BUFFSIZE], buffRight[BUFFSIZE];
header_p meta = (header_p)malloc(sizeof(header)); // header_p points to a header struct that contains the wave file metadata fields
int nb, cnt; // variable storing number of bytes returned
printf("Buffers initialized.\n");
if (infile)
{
fread(meta, 1, sizeof(header), infile);
meta->subchunk2_size = meta->subchunk2_size + 2 * NUM_ZEROS;
fwrite(meta,1, sizeof(*meta), outfile);
while (!feof(infile))
{
nb = fread(buff16,1,BUFFSIZE,infile); // Reading data in chunks of BUFSIZE
count++; // Incrementing Number of frames
for(cnt = 0; cnt < nb/2; cnt++){
buffLeft[cnt] = buff16[2*cnt];
buffRight[cnt] = buff16[2*cnt+1];
}
/*
* TODO: INSERT SIGNAL PROCESSING PART
*/
for(cnt = 0; cnt < nb/2; cnt++){
buff16[2*cnt] = buffLeft[cnt];
buff16[2*cnt+1] = buffRight[cnt];
}
fwrite(buff16,1,nb,outfile);
}
for(cnt = 0; cnt < 2*NUM_ZEROS; cnt++){
buff16[cnt] = 0;
}
fwrite(buff16,1, 2*NUM_ZEROS,outfile);
printf("Number of frames in the input wave file are %d.\n", count);
}
fclose(infile);
fclose(outfile);
return 0;
}
Does somebody have an idea what I did wrong?
Upvotes: 2
Views: 3002
Reputation: 1506
You have
#define NUM_ZEROS 100
and
fwrite(buff16,1, 2*NUM_ZEROS,outfile);
Aim:
I want to write back the data to an output file and append 100 zeros on each channel.
I think it should be 100 SAMPLES at each channel. As you have 16bit PCM each sample is 2 bytes. So one channel needs 200 bytes (zeros) to be written. Stereo means 400 bytes.
Your fwrite saves just 2*NUM_ZEROS so 200 bytes - this is answer to part about missing samples.
Additionally you declare
short int buff16[2*BUFFSIZE];
while reading just half of it and using half of half (nb/2) for processing. Than write full buffer (actually half of declared) with upper half full of random garbage from memory.
Upvotes: 0
Reputation: 12404
Are you sure that only a part of the added zeros is garbage?
You mess up the data size for fread
and fwrite
Your buffers are short int
:
short int buff16[2*BUFFSIZE]; // BUFFSIZE*2*sizeof(short) bytes
You read only 1/4 of that size:
nb = fread(buff16,1,BUFFSIZE,infile); // BUFFSIZE bytes
This reads BUFSIZE
bytes as you only specify a size of 1 per element.
Instead of BUFFSIZE*2
shorts you only read BUFFSIZE
bytes.
The return value is number of read elements, i.e. bytes again.
In your buffer that amount of data is only sufficient for nb/2
elements but you access buff16[0]
.. buff16[nb-1]
where second half of it was not read from the file.
Luckily you also do not write the second half back into the new file as the
same error with length is also present there.
And finally the same problem is present when you append the zero values to the file.
tl;dr
Change your size parameter for fread
and fwrite
to sizeof(short int)
.
Upvotes: 1