0

My code is just copying the header but doesn't change the volume at the second loop.

// TODO: Copy header from the input file to the output file

uint8_t header[HEADER_SIZE];
uint8_t* header_p=malloc(HEADER_SIZE * sizeof(uint8_t));
while(fread(&header_p,sizeof(header[HEADER_SIZE]),1,input))
{
    fwrite(&header_p,sizeof(header[HEADER_SIZE]),1,output);
}

// TODO: Read samples from the input file and write updated data to the output file

int16_t buffer;

while(fread(&buffer,sizeof(buffer),1,input))
{
    buffer =(int16_t)(buffer*factor);
    fwrite(&buffer,sizeof(buffer),1,output);
}
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
snowr
  • 55
  • 1
  • 6
  • 2
    I don't know the format for .wav files, but `malloc(sizeof(uint8_t))` looks like very few bytes allocated (one single byte). – pmg Sep 30 '20 at 08:59
  • yeah I edited it, but again nothing changes the problem is at the second loop. – snowr Sep 30 '20 at 09:06
  • 2
    1 open the output file in a hexeditor and check if the data looks as you expect it to. 2 Hand craft an example and check if looks and works as expected. – Simson Sep 30 '20 at 09:10
  • 1
    Are you sure that this WAV file is with 16 bit per sample? And why you define static array with size `HEADER_SIZE` and then do `malloc` for the same size - I don't see any modifications. You can use `header` buffer instead of `header_p`. – i486 Sep 30 '20 at 09:15
  • 1
    How many `HEADER` elements do you expect to find in one file? You read/write the whole file in first loop until the remaining bytes are less than 1 header. – Gerhardh Sep 30 '20 at 09:19
  • I expect to write just the first 44 bytes of wav file and modify the data samples to increase or decrease the volume. – snowr Sep 30 '20 at 09:21
  • If the data is PCM to increase the volume multiply the sample with a multiplier greater than 1 – Colin Sep 30 '20 at 09:22
  • If you only expect 1 header, why do you use a loop that will read much more than 1 header – Gerhardh Sep 30 '20 at 10:37
  • `sizeof(header[HEADER_SIZE])` This is not what you want. `header[HEADER_SIZE]` a single `char` right after the last element of the `header`. What you need is `sizeof(header)` or simply `HEADER_SIZE` – Gerhardh Sep 30 '20 at 11:35

1 Answers1

2

If a particular WAV file consists only of a header followed by 16-bit signed values representing the sound data, your error would be in the first while loop. This loop continues to copy sizeof(header[HEADER_SIZE]) (which is actually the size of one element in header which is 1) chunks from input to output until the end of the file has reached, the second while loop will not be entered.

Just copy the header once, and use a more appropriate scaling algorithm to fix some other issues. For example:

uint8_t header[HEADER_SIZE];
/* There is only one header, so parse it just once */
if (fread(&header[0], sizeof(header), 1, input)) {
    fwrite(&header[0], sizeof(header), 1, output);
}

/* Assuming 16-bit signed integer PCM payload */
int16_t sample;
while(fread(&sample, sizeof(sample), 1, input)) {
    /* Round value to nearest number */
    double scaledValue = floor((sample * factor) + 0.5);

    /* Clamp new value */
    if (scaledValue >= INT16_MAX) {
        sample = INT16_MAX;
    } else if (scaledValue <= INT16_MIN) {
        sample = INT16_MIN;
    } else {
        sample = (int16_t)scaledValue;
    }
    fwrite(&sample, sizeof(sample), 1, output);
}

However the .wav file format is not as simple as that and has multiple variations, 16-bit signed PCM values is just one of them. Also the size and the format of the sample data is given in header, you will need to parse the header carefully and act accordingly. For more information on the .wav file format, I guess these are a good starting point:

Elijan9
  • 1,269
  • 2
  • 17
  • 18
  • This should work but my output file says it's corrupted – snowr Sep 30 '20 at 09:55
  • 1
    @snowr I added a third link describing the the PCM 16-bit WAVE file format byte-by-byte. Your "header" should be about 44 bytes if you include the RIFF header part, the WAVE fmt part and the chunk id and size, but it will only work if you only have one chunk in your file. But please properly parse the WAV data instead, at least taking account of the chunk id's and sizes... – Elijan9 Sep 30 '20 at 11:59
  • it works but I also deleted that "+ 0.5"- distortion to pass the tests. THANKS, A LOT! – snowr Sep 30 '20 at 12:11
  • 1
    That + 0.5 is to improve rounding, but I forgot this was a signed int range, so I should subtract 0.5 for negative values. See also https://stackoverflow.com/questions/9695329/c-how-to-round-a-double-to-an-int I'll update my answer with - 0.5 for negative values. – Elijan9 Sep 30 '20 at 12:45
  • yeah, I get it now. But because of my file, I had to delete it. Sorry, misunderstanding you. – snowr Sep 30 '20 at 12:55