0

So I have this assignment about convolution, and at one part I'm asked to convolute the data of two .wav audio files and see the result. I have managed to load all the header information properly. However when I try to run the code I get this error:

Exception thrown at 0x00007FFE1E5B602E (ucrtbased.dll) in project_name.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. occurred

My code relevant to this issue follows up. I have a comment pointing out the line where my it's more likely for my problem to be:

typedef struct  WAV_HEADER {
    char                RIFFChunkID[4];
    unsigned long       RIFFChunkSize;
    char                Format[4];
    char                FormatSubchunkID[4];
    unsigned long       FormatSubchunkSize;
    unsigned short      AudioFormat;
    unsigned short      Channels;
    unsigned long       SamplesRate;
    unsigned long       ByteRate;
    unsigned short      BlockAlign;
    unsigned short      BitsPerSample;
    char                DataSubchunkID[4];
    unsigned long       DataSubchunkSize;
    double*             Data; 
}wav_head;
WAV_HEADER wav_READ(std::string filename) {
    wav_head read;
    FILE* TOREAD;

    //Construct filepath
    std::string filepath = "<<path>>\" + filename + ".wav";
    const char* path = filepath.c_str();

    //Open file
    TOREAD = fopen(path, "r");
    if (!TOREAD) { std::cout << "Error while reading file.\n"; exit(-1); }

    //READ RIIF CHUNK---------
    fread(&read.RIFFChunkID, sizeof(char), 4, TOREAD);
    fread(&read.RIFFChunkSize, sizeof(long), 1, TOREAD);
    fread(&read.Format, sizeof(char), 4, TOREAD);

    //READ FORMAT CHUNK-------
    fread(&read.FormatSubchunkID, sizeof(char), 4, TOREAD);
    fread(&read.FormatSubchunkSize, sizeof(long), 1, TOREAD);
    fread(&read.AudioFormat, sizeof(short), 1, TOREAD);
    fread(&read.Channels, sizeof(short), 1, TOREAD);
    fread(&read.SamplesRate, sizeof(long), 1, TOREAD);
    fread(&read.ByteRate, sizeof(long), 1, TOREAD);
    fread(&read.BlockAlign, sizeof(short), 1, TOREAD);
    fread(&read.BitsPerSample, sizeof(short), 1, TOREAD);

    //READ DATA CHUNK---------
    fread(&read.DataSubchunkID, sizeof(char), 4, TOREAD);
    fread(&read.DataSubchunkSize, sizeof(long), 1, TOREAD);

    int data_el = read.DataSubchunkSize / sizeof(short);   //
    read.Data = new double[data_el];                       // Here probably lies the problem.
    fread(&read.Data, sizeof(double),data_el, TOREAD);     //

    fclose(TOREAD);

    return read;
}

Now I have converted the wav file I want to analyse into text using matlab, and I've seen that there are (let's say) n elements/numbers in the data section, which is then corrected by the DataSubchunkSize variable which 2n ( n * sizeof(short) ). So these numbers are correct. Therefore I can't see what exactly is my mistake.

P.S. I have seen this post:

C++ Reading the Data part of a WAV file

and I have actually used it a lot to write my code. However It doesn't fully cover me on what to do in my case.

ALSO, I know that there is a library that can do that job for me, however I'd like to do it this way. I'll use this lib as a final resort!

Cheers!

Fjolfrin
  • 33
  • 1
  • 7
  • 2
    I think you need to take a step back and read a little more about the address-of operator `&`. If you use it on a pointer you get a pointer *to the pointer*. And you don't need to use it on arrays (it's semantically wrong actually). – Some programmer dude Oct 29 '19 at 10:13
  • 3
    `fread(&read.Data,...` ===> `fread(read.Data, ...` - the allocation immediately preceding that line should be a dead-giveaway. – WhozCraig Oct 29 '19 at 10:15
  • 3
    Why are you loading sizeof(short) elements into a double array? If they're signed 16 bit samples in the .wav and you want to convert them to doubles afterwards you should probably read them into a short array first and then copy them into the double array afterwards, probably scaling them as you do (IIRC double/float audio values are usually processed as -1 to +1? although if you're just processing the samples here then that doesn't matter) – Rup Oct 29 '19 at 10:16
  • @Someprogrammerdude you were right on this one, silly of me. I fixed it and at least I get shown that something actually exists in my array. – Fjolfrin Oct 29 '19 at 10:26
  • @WhozCraig also, the same (previous comment) – Fjolfrin Oct 29 '19 at 10:26
  • @Rup so you're saying that I should make the Data array a short array, and still use sizeof(short) when I try to load the data into the array? (And of course normalize to double later) – Fjolfrin Oct 29 '19 at 10:27
  • For a data_el you computed from sizeof(short), yes I think so. – Rup Oct 29 '19 at 10:30
  • @Rup all is well and the Data array has the correct number of elements. However after some elements the value of Data[i] is always -12851. Something is clearly wrong in loading the data to the array. – Fjolfrin Oct 29 '19 at 10:48
  • Yes, that's 0xCDCD which the VC++ debug runtime uses for [memory allocated but not overwritten](https://stackoverflow.com/a/370362/243245). Can you check the return value of fread - did you get data_el shorts read? – Rup Oct 29 '19 at 10:53
  • Note: You should use a `std::vector` if `read.BitsPerSample==16`, but you need to consider what to do if it's not 16. – MSalters Oct 29 '19 at 11:28
  • Ok @MSalters, I have tried both int16_t and double, and the end result is a vector with the correct size (@Rup), but the elements have the value 1 for some time, and then go to 0. The data part of the wav file is composed of doubles n such as -1 <= n <= 1, as I have seen using Matlab. I have tried some other combinations of data types in the fread command but I still end up with 1s and 0s. Any ideas? – Fjolfrin Oct 31 '19 at 10:45
  • @Fjolfrin: You need to interpret the header to know the data format. What is the `BitsPerSample` of your actual WAV file? Also, load the file in Audacity and see how the wave form looks there. – MSalters Oct 31 '19 at 18:43
  • @MSalters it's 16 BpS, as you said, thus I'm using the int16_t as you suggested. I also have a view of the waveform. It's definitely not 1s followed by 0s. – Fjolfrin Nov 01 '19 at 20:22

0 Answers0