Skip to content

Instantly share code, notes, and snippets.

@Pikachuxxxx
Last active April 26, 2021 20:07
Show Gist options
  • Save Pikachuxxxx/4a472b9efb8d2294d6791c7e2310344d to your computer and use it in GitHub Desktop.
Save Pikachuxxxx/4a472b9efb8d2294d6791c7e2310344d to your computer and use it in GitHub Desktop.
A code snippet to create and write audio data to .WAV audio file format
#include <iostream>
#include <cstdint>
/*******************************************************************************
WAVE File chunks overview
____________________________
| RIFF WAVE Chunk |
| groupID = 'RIFF' |
| riffType = 'WAVE' |
| __________________ |
| | Format Chunk | |
| | ckID = 'fmt ' | |
| |__________________| |
| __________________ |
| | Sound Data Chunk | |
| | ckID = 'data' | |
| |__________________| |
|__________________________|
*******************************************************************************/
/*
* Note:- Do not change the order of the variables as it represents the canonical format
* any changes or re-ordering of the variables order can result in corrupted .wav files
*/
struct SimpleWaveFileFormat
{
// RIFF Wave Chunk
unsigned char m_RIFFChunkID[4];
std::uint32_t m_RIFFChunkSize;
unsigned char m_Format[4];
// Format Chunk
unsigned char m_FormatChunkID[4];
std::uint32_t m_FormatChunkSize;
std::uint16_t m_AudioFormat;
std::uint16_t m_NumChannels;
std::uint32_t m_SampleRate;
std::uint32_t m_ByteRate;
std::uint16_t m_BlockAlign;
std::uint16_t m_BitsPerSample;
// Sound Data Chunk
unsigned char m_SoundChunkID[4];
std::uint32_t m_SoundChunkSize;
};
bool ExportWAVEFile(const char* fileName, void* soundData, std::int32_t sampleRate, std::int32_t bitsPerSample, std::int16_t numChannels, std::int32_t dataSize)
{
// Try opening the file
FILE *audioFile = fopen(fileName, "w+b"); // w+ => write as well as update after opening the file, b indicates open file as binary file
if (!audioFile)
{
std::cerr << "Error opening the file" << std::endl;
return false;
}
SimpleWaveFileFormat wavFileFormat;
// Fill RIFF Wave chunk data
memcpy(wavFileFormat.m_RIFFChunkID, "RIFF", 4); /* Group ID string */
wavFileFormat.m_RIFFChunkSize = dataSize + 4; /* +4 because we added a 4 byte string */
memcpy(wavFileFormat.m_Format, "WAVE", 4);
// Fill the Format Chunk
memcpy(wavFileFormat.m_FormatChunkID, "fmt ", 4);
wavFileFormat.m_FormatChunkSize = 16;
wavFileFormat.m_AudioFormat = 1;
wavFileFormat.m_NumChannels = numChannels;
wavFileFormat.m_SampleRate = sampleRate;
wavFileFormat.m_ByteRate = sampleRate * numChannels * bitsPerSample / 8;
wavFileFormat.m_BlockAlign = numChannels * bitsPerSample / 8;
wavFileFormat.m_BitsPerSample = bitsPerSample;
// Fill Sound Data Chunk
memcpy(wavFileFormat.m_SoundChunkID, "data", 4);
wavFileFormat.m_SoundChunkSize = dataSize;
// Write the file format to the file
fwrite(&wavFileFormat, sizeof(SimpleWaveFileFormat), 1, audioFile);
// Write the data to the file with the simple wav format style
fwrite(soundData, dataSize, 1, audioFile);
// Close the file and indicate success
fclose(audioFile);
return true;
}
@Pikachuxxxx
Copy link
Author

uint8_t* LoadWAVEFile(const char* filePath, SimpleWaveFileFormat& fileFormat)
{
    std::cout << "Here";
    FILE* fp = fopen(filePath,"rb");
    if (!fp) {
        printf("%s can't open audio file\n",filePath);
        exit(1);
    }

    // Read the data format information from the header file
    fread(&fileFormat, sizeof(SimpleWaveFileFormat), 1, fp);
    // Find how many bytes to read
    uint32_t bytesToRead=0;
    bytesToRead = fileFormat.m_SoundChunkSize - sizeof(SimpleWaveFileFormat);
    uint8_t* buf;
    for (; bytesToRead > 0; bytesToRead--)
    {
        fread(&buf, 1, 1, fp);
    }
    return buf;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment