I’m trying to write a code for an audio reverse filter that would reverse audio wav files for cs50 course (new to programming). I managed to complete the whole task and tried it on an input file and sound reversed to me however the check50 function states that my file wasn’t properly reversed. It’s hard for me to spot the problem when I don’t know what the problem is. I was hoping anyone would be able to spot an obvious problem that I’m missing.
I just kept reading through the code and couldn’t find a specific problem. I tried reversing my output file and it sounds exactly like the input file to me but can’t be sure if it’s actually identical under the hood.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "wav.h"
int check_format(WAVHEADER header);
int get_block_size(WAVHEADER header);
int main(int argc, char *argv[])
{
// Ensure proper usage
// TODO #1
if (argc != 3)
{
printf("Usage: ./reverse inputfilename.wav outputfilename.wav\n");
return 1;
}
// Open input file for reading
// TODO #2
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open %s.\n", argv[1]);
return 1;
}
// Read header
// TODO #3
WAVHEADER *buffer = malloc(1 * sizeof(WAVHEADER));
fread(buffer, sizeof(WAVHEADER), 1, input);
// Use check_format to ensure WAV format
// TODO #4
if (check_format(*buffer) == 1)
{
printf("input file format not supported\n");
return 1;
}
// Open output file for writing
// TODO #5
FILE *output = fopen(argv[2], "w");
if (output == NULL)
{
fclose(input);
printf("Could not create %s.\n", argv[2]);
return 5;
}
// Write header to file
// TODO #6
fwrite(buffer, sizeof(WAVHEADER), 1, output);
// Use get_block_size to calculate size of block
// TODO #7
int block_size = get_block_size(*buffer);
// Write reversed audio to file
// TODO #8
FILE *temp = malloc(block_size);
fseek(input, -1 * block_size, SEEK_END);
fread(temp, block_size, 1, input);
fwrite(temp, block_size, 1, output);
while (ftell(input) > 44 || ftell(input) == 44)
{
fseek(input, -2 * block_size, SEEK_CUR);
fread(temp, block_size, 1, input);
fwrite(temp, block_size, 1, output);
}
fclose(input);
fclose(output);
free(temp);
free(buffer);
}
int check_format(WAVHEADER header)
{
// TODO #4
if (header.format[0] != 'W' || header.format[1] != 'A' || header.format[2] != 'V' || header.format[3] != 'E')
{
return 1;
}
return 0;
}
int get_block_size(WAVHEADER header)
{
// TODO #7
int answer = 0;
answer = (header.bitsPerSample / 8) * header.numChannels;
return answer;
}
>Solution :
I was thinking that
while (ftell(input) > 44 || ftell(input) == 44)
{
fseek(input, -2 * block_size, SEEK_CUR);
fread(temp, block_size, 1, input);
fwrite(temp, block_size, 1, output);
}
could be
while (ftell(input) >= sizeof(WAVHEADER))
but I realised it’s the wrong end condition, because when it’s at the first data record you’ll then seek to, and read/write, an imaginary previous one.
So I suggest
while (ftell(input) - 2 * block_size >= sizeof(WAVHEADER))