1

The input file is in.wav. I have to read chunks (succeeded) and to read samples to normalize the audio file...

The problem is that it crashes while trying to fing the max and min values of .wav file's samples. It will just find the minimum value and the maximum one in the array, but it crashes... Tell me what is wrong, please.

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#define hdr_SIZE 64

typedef struct FMT
{
    char        SubChunk1ID[4];
    int         SubChunk1Size;
    short int   AudioFormat;
    short int   NumChannels;
    int         SampleRate;
    int         ByteRate;
    short int   BlockAlign;
    short int   BitsPerSample;

} fmt;

typedef struct DATA
{
    char        Subchunk2ID[4];
    int         Subchunk2Size;
    int         Data[441000]; 
} data;

typedef struct HEADER
{
    char        ChunkID[4];
    int         ChunkSize;
    char        Format[4];
    fmt         S1;
    data        S2;
} header;



int main()
{
    FILE *input = fopen( "in.wav", "rb");   /// nameIn

    if(input == NULL)
    {
        printf("Unable to open wave file (input)\n");
        exit(EXIT_FAILURE);
    }

    FILE *output = fopen( "out.wav", "wb"); /// nameOut
    header hdr;


    fread(&hdr, sizeof(char), hdr_SIZE, input); 
    /* NOTE: Chunks has been copied successfully. */


    /*###############################*/                                  
    /*##### UPDATE (char *ptr;) #####*/
    /*###############################*/
    char *ptr;  // 'int' was written here instead of 'char'. That's was a stupid mistake...
    long n = hdr.S2.Subchunk2Size;


    /// COPYING SAMPLES...
    ptr = malloc(sizeof(hdr.S2.Subchunk2Size));
    while ( n-- != 0 )
    {
        fread(&ptr, 1, 1, input);  // Continues reading after the least 'stop' place. 
    }                              // I was being told here (on "stack") that it is so...


    n = hdr.S2.Subchunk2Size; // Resetting 'n'.
    int min = ptr[0], max = ptr[0], i;

    /* THE PROBLEM IS HERE: */
    for ( i = 0; i < n; i++ )
        {
            if ( ptr[i] < min )     // If the next elements is less than previous, swap them.
                min = ptr[i];
            if ( ptr[i] > max ) // If the next elements is bigger than previous, swap them.
                max = ptr[i];
    }

    printf("> > >%d__%d\n", min, max);    // Displaying of 'min' and 'max'.

    fclose(input);
    fclose(output);

    return 0;
}

UPDATE:

EUREKA! This is all because of 8-bits per sample! I must manipulate with them ( with samples ) as with a type of char. (see my "### UPDATE ###"-comment in the code)

yulian
  • 1,601
  • 3
  • 21
  • 49
  • Padding bytes... Padding bytes everywhere! –  May 09 '13 at 18:43
  • Have you tried running your code through a debugger? (Also, you could start with `i = 1` since you've already set `min` and `max` to `ptr[0]`) – Kninnug May 09 '13 at 18:44
  • Regarding your update, `min` is set to the first element of the dynamically allocated array to which `ptr` is initialized. – jxh May 09 '13 at 19:18
  • Oh... EUREKA! This is all because of 8-bits per sample! I must manipulate with them ( with samples ) as with a type of char. (see my "update"-comment in the code) – yulian May 09 '13 at 19:28

3 Answers3

1

This code:

    /// COPYING SAMPLES...
    ptr = malloc(sizeof(hdr.S2.Subchunk2Size));
    while ( n-- != 0 )
    {
        fread(&ptr, 1, 1, input);  // Continues reading after the least 'stop' place. 
    }                              // I was being told here (on "stack") that it is so...

Overwrites the first byte of the ptr variable n times. This corrupts ptr's value. Even if you fixed it to read into the allocated buffer instead (by removing the &), you would only be rewriting the first byte of the allocated memory.

What you probably intended was:

    fread(ptr, 1, n, input);

Notice the while loop is not needed. But, that would be a guess on my part regarding your true intentions.

jxh
  • 69,070
  • 8
  • 110
  • 193
1

You are corrupting your malloc()ed ptr with:

fread(&ptr, 1, 1, input); /* overwrite the content of ptr */

and so the program crash if it tries to use ptr. Use:

fread(ptr, 1, 1, input);

Or better: no while loop, and use:

  fread(ptr, 1, n, inout);
xtof pernod
  • 862
  • 5
  • 7
1

As pointed by others, ptr is not incremented in this block,

while ( n-- != 0 )
{
    fread(&ptr, 1, 1, input);  // FIXME, ptr not incremented 
}

But you are are trying to store 1 byte data as integer; is this what you intend ??

VoidPointer
  • 3,037
  • 21
  • 25