2

I had this code which initially reads a .wav file to find out the number of samples in it. Using this size I was trying to make array of that size. After that I was reading the samples form same .wav file and was storing in that array, but out of 762880 samples it was reading only 7500 samples(approx.).

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>

void main(){
    FILE *fp;
    long n,i=0;
    float *data;
    FILE* inp =NULL;
    FILE* oup =NULL;
    float value =0;
    signed short ss;
      /* Open file */
    fp = fopen("k1s1.wav", "rb");
    fseek(fp, 0L, SEEK_END);
    n = ftell(fp);
    n=n/2-22;
    printf("n:%ld",n);
    fclose(fp);


    data=malloc(n*sizeof(float));


    inp = fopen("k1s1.wav","rb");
    oup = fopen("cs123.txt","wt");
    fseek (inp,44,SEEK_SET);// that didn't help getting the right result !!

    i=0;
    for(i=0;i<n;i++){
        fread(&ss, sizeof(signed short) ,1 , inp);
        //Now we have to convert from signed short to float:
        value=((float)ss)/(unsigned)0xFFFF;
        value= value* 2.0;
        value= value*100000;
        value= ceil(value);
        value= value/100000;
        fprintf(oup,"%f\n",value);
        data[i]=value;
        ///printf("%lf\t",value);

    }

    fclose(inp);
    fclose(oup);
    printf("done");

}

When I remove this line - "data[i]=value;" in for loop the programs works fine and i can see output in the file.I need to store these values in array as well for further computations. What could be the error?

Paras
  • 21
  • 1
  • 1
    There is room to argue that you should be error checking the `fopen()`, `malloc()`, `fread()` calls. However, if you're getting a sensible size for `n`, I don't immediately see the problem. I've not tried playing with the code. I observe that you could use `rewind(fp)` or `fseek(fp, 0L, SEEK_SET);` to avoid having to reopen the `.wav` file (using `fp` instead of `inp` thereafter). However, that's an optimization, not a cause of your trouble. – Jonathan Leffler Feb 12 '17 at 13:57
  • Does the compiler affect the output? – Paras Feb 12 '17 at 14:09
  • It's unlikely that the compiler would be a major factor here. The code is using standard C — apart from including ``, even though it uses none of its functions. Clearly, there's a chance that you're hitting a compiler issue, somehow. Which compiler are you using? (I've just compiled a version of your code with error checking on the key functions, and there didn't seem to be a problem. The first (only) `.wav` file I found on my machine had only 6152 samples in it, but I don't see why the size is a major factor. I was working on a Mac with macOS Sierra 10.12.3 and GCC 6.3.0.) – Jonathan Leffler Feb 12 '17 at 14:14
  • Oh, I did fix the return type of `main()` — see [What should `main()` return in C and C++?](http://stackoverflow.com/questions/204476/) — so the code would compile on my machine under my default (stringent) compiling options. – Jonathan Leffler Feb 12 '17 at 14:16
  • I was using TurboC++. It is giving this issue when the size is way too large. I tried a code with size of 100 and it worked fine. – Paras Feb 12 '17 at 14:24
  • 1
    TurboC++ is an antique, even archaic, compiler. Also, are you really using TurboC, or did you mistag this question? There is a chance that it has problems handling roughly 3 MiB in a memory allocation. OTOH, it's not grotesquely large — the machine should handle it, even if the compiler doesn't, and the library should report an error if 3 MiB is too big. I suppose you have to use that compiler — moving to a more modern compiler isn't an option? The danger might be that somehow the compiler is interpreting the size using a 16-bit value instead of 32-bit or 64-bit; that would cause trouble. – Jonathan Leffler Feb 12 '17 at 14:29
  • 1
    @Paras have you tried installing `gcc`? – RoadRunner Feb 12 '17 at 14:53

1 Answers1

-1

The code looks okay. What you could do is check the results from fseek and fread to confirm they are working as expected. As for fseek, technically it should be passed the result from ftell and not passed something calculated (but probably correct!).

I saw in the comments TurboC was mentioned. If that's the case, make sure to build using "small-code & big-data". If you're building with "small-code & small data", you could have problems like you're seeing with lots of data.

I'd probably write something like this:

#include <stdlib.h>
#include <stdio.h>

#define HEADER        22
#define INCREMENT     10000
#define CONVERSION    (2.0 / 65535.0)

int main() {
    FILE *inp = NULL, *oup = NULL;
    float *data = NULL, value;
    signed short header[HEADER], ss;
    long i = 0, j = 0;

    if ((inp = fopen("k1s1.wav", "rb")) && (oup = fopen("cs123.txt","wt"))) {
        if (fread(header, sizeof(header), 1, inp)) {
            while (fread(&ss, sizeof(signed short), 1, inp)) {
                value = ((float)ss) * CONVERSION;
                if (j == i) {
                    j += INCREMENT;
                    if (!(data = realloc(data, j * sizeof(float)))) {
                        fprintf(stderr, "FAILURE: realloc failure at %ld elements\n", j);
                        return EXIT_FAILURE;
                    }
                }
                data[i++] = value;
                fprintf(oup,"%.5f\n",value);
            }
            /* Release any extra memory */
            j = i;
            if (!(data = realloc(data, j * sizeof(float)))) {
                fprintf(stderr, "FAILURE: realloc failure at %ld elements\n", j);
                return EXIT_FAILURE;
            }
            for (i = 0; i < j; i++) {
                /* Can analyze data here */
            }
        } else {
            fprintf(stderr, "FAILURE: header not defined\n");
            return EXIT_FAILURE;
        }
    } else {
        fprintf(stderr, "FAILURE: files could not be opened\n");
        return EXIT_FAILURE;
    }

    /* Okay to use if the arguments are NULL */
    free(data);
    fclose(inp);
    fclose(oup);

    return EXIT_SUCCESS;
}

This solution avoids any uncertainty as to whether fseek, ftell, etc are working or not by not using them, and checks for more errors so you might be able to what's up if it fails in your test cases. Hope this helps.

Yimin Rong
  • 1,890
  • 4
  • 31
  • 48