0

Looking for a simple Windows native call to open and read a WAV file in C++ on Windows (without requiring third party libraries).

I can find

  1. mmio* functions - deprecated.
  2. Media Foundation - seems way more complicated as it "...Builds a DLL that is a COM server..."

But all of these are way more complicated than reading bytes from a local file.

I can write the code the parse the WAV format myself but would rather use something that's been running and tested a lot more than something I write ad hoc.

Does a Microsoft WAV file parser/reader exist that will allow me to;

  1. Open the file;
  2. Examine the header;
  3. Read the PCM Data.
Random
  • 11
  • 1
  • 4

1 Answers1

0

It's easy just comply with the WAVE file format, based on that, you can extract the data byte by byte and interpret it. So once you have the correct path of the file you can do something like this: This is a piece of code of my wav file reader in Android (not complete but has the main parts that read the pcm data out of wav file along with it's descriptors)

typedef struct wav_file {
    unsigned char chunkId[4];
    uint32_t chunkSize;
    unsigned char format[4];
    unsigned char subchunk1Id[4];
    uint32_t subchunk1Size;
    uint16_t audioFormat;
    uint16_t numChannels;
    uint32_t sampleRate;
    uint32_t byteRate;
    uint16_t blockAlign;
    uint16_t bitsPerSample;
    unsigned char subchunk2Id[4];
    uint32_t subchunk2Size;
    unsigned char * data;
} WavFile;    

void swap_endian16(uint16_t val) {
    val = (val<<8) | (val>>8);
}

void swap_endian32(uint32_t val) {
     val = (val<<24) | ((val<<8) & 0x00ff0000) |
      ((val>>8) & 0x0000ff00) | (val>>24);
}

WavError loadWavFile(char filePath[], WavFile * wavFile) {
    WavError rc = NO_ERROR;
    FILE *fp = fopen(filePath,"rb");
    printf("wavreader file Path = %s from %s", (fp ? "file opened" : "failed to open file"), filePath);
    if(!fp) {
        rc = CANNOT_OPEN_FILE_ERROR;
        goto out1;
    }

    //chunkId
    size_t len = fread(wavFile->chunkId, sizeof(unsigned char), 4, fp);
    wavFile->chunkId[len] = '\0';
    printf("wavreader len:%d chunkId: %s", (int) len , wavFile->chunkId);
    if (strcmp((const char *) wavFile->chunkId, "RIFF")) {
        rc = NOT_WAV_FILE_ERROR;
        goto out1;
    }

    //chunkSize
    fread(&wavFile->chunkSize, sizeof(uint32_t), 1, fp);
    swap_endian32(wavFile->chunkSize);
    printf("wavreader chunkSize: %d", wavFile->chunkSize);

    //format
    len = fread(wavFile->format, sizeof(unsigned char), 4, fp);
    wavFile->format[len] = '\0';
    printf("wavreader format: %s", wavFile->format);
    if (strcmp((const char *)wavFile->format,"WAVE")) {
       rc = FMT_ERROR;
       goto out1;
    }

    //subchunk1Id
    len = fread(wavFile->subchunk1Id, sizeof(unsigned char), 4, fp);
    wavFile->subchunk1Id[len] = '\0';
    printf("wavreader subchunk1Id: %s", wavFile->subchunk1Id);
    if (strcmp((const char *)wavFile->subchunk1Id,"fmt ")) {
        rc = FMT_ID_ERROR;
        goto out1;
    }

    //subchunk1Size
    fread(&wavFile->subchunk1Size, sizeof(uint32_t), 1, fp);
    swap_endian32(wavFile->subchunk1Size);
    printf("wavreader subchunk1Size: %d", wavFile->subchunk1Size);

    //audioFormat
    fread(&wavFile->audioFormat, sizeof(uint16_t), 1, fp);
    swap_endian16(wavFile->audioFormat);
    printf("wavreader audioFormat: %d", wavFile->audioFormat);

    //numChannels
    fread(&wavFile->numChannels, sizeof(uint16_t), 1, fp);
    swap_endian16(wavFile->numChannels);
    printf("wavreader numChannels: %d", wavFile->numChannels);

    //sampleRate
    fread(&wavFile->sampleRate, sizeof(uint32_t), 1, fp);
    swap_endian32(wavFile->sampleRate);
    printf("wavreader sampleRate: %d", wavFile->sampleRate);

    //byteRate
    fread(&wavFile->byteRate, sizeof(uint32_t), 1, fp);
    swap_endian32(wavFile->byteRate);
    printf("wavreader byteRate: %d", wavFile->byteRate);

    //blockAlign
    fread(&wavFile->blockAlign, sizeof(uint16_t), 1, fp);
    swap_endian16(wavFile->blockAlign);
    printf("wavreader blockAlign: %d", wavFile->blockAlign);

    //bitsPerSample
    fread(&wavFile->bitsPerSample, sizeof(uint16_t), 1, fp);
    swap_endian16(wavFile->bitsPerSample);
    printf("wavreader bitsPerSample: %d", wavFile->bitsPerSample);

    //subchunk2Id
    fread(wavFile->subchunk2Id, sizeof(unsigned char), 4, fp);
    wavFile->subchunk2Id[len] = '\0';
    printf("wavreader subchunk2Id: %s", wavFile->subchunk2Id);

    fread(&wavFile->subchunk2Size, sizeof(uint32_t), 1, fp);
    swap_endian32(wavFile->subchunk2Size);
    printf("wavreader subchunk2Size: %d", wavFile->subchunk2Size);

    wavFile->data = (unsigned char *) malloc (sizeof(unsigned char) * wavFile->subchunk2Size); //set aside sound buffer space
    fread(wavFile->data, sizeof(unsigned char), wavFile->subchunk2Size, fp); //read in our whole sound data chunk
    fclose(fp);
out1:
    return rc;
}

in wavFile->data you get the actual pcm data from the file.

PS: you should use this link as reference

vmallet
  • 479
  • 3
  • 11
alexm
  • 1,285
  • 18
  • 36