Koobz866
Koobz866

Reputation: 196

Copying and writing to a WAV file in C

I'm having trouble writing to a WAV file that I'm essentially trying to copy. Have a function that will take in and read the WAV file successfully printing out all the header information and storing the data block, which is then passed into the write function to write the information to a new WAV file. But when I go to listen to the copied file it's essentially 2 seconds of white noise and then nothing, whereas the original contains 13 seconds of speech.

Here is the write function:

int write_pcm_wavefile(pcm_wavefile_header_type *header, char *data, char *filename)
{
  FILE *my_File;
  char str[100];
  char *file_output_location = "copy/";
  int hold = header->Subchunk2Size;

  strcpy(str, file_output_location);
  strcat(str, filename);

  my_File = fopen(str, "wb");
  fwrite(header, 1, 44, my_File);
  fwrite(data, 1, hold, my_File);
  fclose(my_File);
  printf("\n");
  return 0;
}

And here is the read function:

int read_pcm_wavefile(pcm_wavefile_header_type *header, char **data, char *filename)
{
    unsigned char buffer4[4];
    unsigned char buffer2[2];
    unsigned char badCheck = 1;
    unsigned char pcmCheck = 1;
    FILE *my_File;
    my_File=fopen(filename, "rb");

    //ChunkID
    fread(header, sizeof(header->ChunkID), 1, my_File);
    if (header->ChunkID[0] != 'R' || header->ChunkID[1] != 'I' || header->ChunkID[2] != 'F' || header->ChunkID[3] != 'F')
        badCheck = 0;

    //Chunk Size
    fread(buffer4, sizeof(buffer4), 1, my_File);
    header->ChunkSize  = buffer4[0] |
                            (buffer4[1]<<8) |
                            (buffer4[2]<<16) |
                            (buffer4[3]<<24);
    //Format
    fread(header->Format, sizeof(header->Format), 1, my_File);
    if (header->Format[0] != 'W' || header->Format[1] != 'A' || header->Format[2] != 'V' || header->Format[3] != 'E')
            badCheck = 0;

    //SubChunk1ID
    fread(header->Subchunk1ID, sizeof(header->Subchunk1ID), 1, my_File);
    if (header->Subchunk1ID[0] != 'f' || header->Subchunk1ID[1] != 'm' || header->Subchunk1ID[2] != 't' || header->Subchunk1ID[3] != ' ')
            badCheck = 0;

    //SubChunk1Size
    fread(buffer4, sizeof(buffer4), 1, my_File);
    header->Subchunk1Size  = buffer4[0] |
                            (buffer4[1]<<8) |
                            (buffer4[2]<<16) |
                            (buffer4[3]<<24);
    //Audio Format

    fread(buffer2, sizeof(buffer2), 1, my_File);
    header->AudioFormat = buffer2[0] | (buffer2[1] << 8);
    if (header->AudioFormat != 1)
            pcmCheck = 0;
    //Num Channels

    fread(buffer2, sizeof(buffer2), 1, my_File);
    header->NumChannels = buffer2[0] | (buffer2[1] << 8);

    //Sample Rate

    fread(buffer4, sizeof(buffer4), 1, my_File);
    header->SampleRate  = buffer4[0] |
                            (buffer4[1]<<8) |
                            (buffer4[2]<<16) |
                            (buffer4[3]<<24);
    //Byte Rate

    fread(buffer4, sizeof(buffer4), 1, my_File);
    header->ByteRate  = buffer4[0] |
                            (buffer4[1]<<8) |
                            (buffer4[2]<<16) |
                            (buffer4[3]<<24);

    //Block Align

    fread(buffer2, sizeof(buffer2), 1, my_File);
    header->BlockAlign = buffer2[0] | (buffer2[1] << 8);

    //Bits Per Sample

    fread(buffer2, sizeof(buffer2), 1, my_File);
    header->BitsPerSample = buffer2[0] | (buffer2[1] << 8);

    if (pcmCheck == 1)
    {
        //SubChunk2ID
        fread(header->Subchunk2ID, sizeof(header->Subchunk2ID), 1, my_File);
        if (header->Subchunk2ID[0] != 'd' || header->Subchunk2ID[1] != 'a' || header->Subchunk2ID[2] != 't' || header->Subchunk2ID[3] != 'a')
                    badCheck = 0;

        //SubChunk2Size
        fread(buffer4, sizeof(buffer4), 1, my_File);
        header->Subchunk2Size  = buffer4[0] |
                (buffer4[1]<<8) |
                (buffer4[2]<<16) |
                (buffer4[3]<<24);
        if (header->Subchunk2Size != (header->ChunkSize - (header->Subchunk1Size + 8 + 8 + 4)))
            badCheck = 0;
        if (header->Subchunk2Size % 2 == 1 && header->Subchunk2Size == (header->ChunkSize - (header->Subchunk1Size + 8 + 8 + 4 + 1)))
            badCheck = 1;
    }

    //Print
    if (badCheck == 0)
    {
        printf("There was an issue with the file \n");
    }
    else
    {
        printf("Chunk ID = ");
        for(int i = 0; i < 4; i++)
            printf("%c", header->ChunkID[i]);
        printf("\n");

        printf("Chunk Size = %u bytes \n", (header->ChunkSize));

        printf("Chunk Format = ");
        for(int i = 0; i < 4; i++)
            printf("%c", header->Format[i]);
        printf("\n");

        printf("Subchunk1ID = ");
        for(int i = 0; i < 4; i++)
            printf("%c", header->Subchunk1ID[i]);
        printf("\n");

        printf("Subchunk1 Size = %u bytes \n", (header->Subchunk1Size));
        printf("Audio Format = %u   (0x%04x) \n", header->AudioFormat, header->AudioFormat);
        printf("Num Channels = %u \n", header->NumChannels);
        printf("Sample Rate = %u \n", (header->SampleRate));
        printf("Byte Rate = %u \n", (header->ByteRate));
        printf("Block Align = %u \n", header->BlockAlign);
        printf("Bits Per Sample = %u \n", header->BitsPerSample);
        if (pcmCheck == 1)
        {
            printf("Subchunk2ID = ");
                    for(int i = 0; i < 4; i++)
                            printf("%c", header->Subchunk2ID[i]);
                    printf("\n");
            printf("Subchunk2 Size = %u bytes \n", (header->Subchunk2Size));
        }

        char *buffer1 = (char *)malloc(header->Subchunk2Size);

        if (buffer1 == 0)
        {
            printf("There was an issue with this file \n");
            fclose(my_File);
            return -1;
        }
        *data = buffer1;
        fclose(my_File);
        free(buffer1);
    }
    printf("\n");
    return 0;
}

Upvotes: 0

Views: 2134

Answers (2)

Koobz866
Koobz866

Reputation: 196

Figured out the issue was I never read the file into data to begin with...that should of been something I picked up earlier thanks for the help

Upvotes: 0

4386427
4386427

Reputation: 44256

This part seems strange:

   char *buffer1 = (char *)malloc(header->Subchunk2Size);

    if (buffer1 == 0)
    {
        printf("There was an issue with this file \n");
        fclose(my_File);
        return -1;
    }

    *data = buffer1;   // *data now points to the memory allocated above

    fclose(my_File);

    free(buffer1);     // Here you free the memory - that seems strange....

First you allocate some memory and save the pointer to it in *data.

But then you free the memory so *data is no longer pointing to memory held by the program.

Further it seems strange that you never write any data to the allocated memory.

Upvotes: 2

Related Questions