dimanche 1 février 2015

Creating WAV file from data in real time - need assist

I am quite new to audio processing and my C++ programming skills are also on basic level. I have to create recording function and I receive data signal from device in form of callback. I would like someone to assist me with basic theory how should I manage WAV memory because I am lost. For now my code looks like this:


Functions I am currently using:



template <typename T>
void write(std::ofstream& stream, const T& t) {
stream.write((const char*)&t, sizeof(T));
}

template <typename T>
void writeFormat(std::ofstream& stream) {
write<short>(stream, 1);
}

template <>
void writeFormat<float>(std::ofstream& stream) {
write<short>(stream, 3);
}

template <typename SampleType>
void writeWAVData(
char const* outFile,
SampleType* buf,
size_t bufSize,
int sampleRate,
short channels)
{
std::ofstream stream(outFile, std::ios::binary|ios::app|ios::ate);

stream.write("RIFF", 4); // Start writting RIFF
write<int>(stream, 0); // (file-size)-8 - FOR NOW IGNORED
stream.write("WAVE", 4); // File type

stream.write("fmt ", 4); // Start Writting format chunk "fmt"
write<int>(stream, 16); // Chunk Data Size 16 + extra format bytes
writeFormat<SampleType>(stream); // Format (compression code)
write<short>(stream, channels); // Channels
write<int>(stream, sampleRate); // Sample Rate
write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate (byte/per sec)
write<short>(stream, channels * sizeof(SampleType)); // Frame size (block align)
write<short>(stream, 8 * sizeof(SampleType)); // Bits per sample

stream.write("data", 4); // Start writting chunk for extra format bytes
stream.write((const char*)&bufSize, 0); // - FOR NOW IGNORED
stream.write((const char*)buf, 0); // - FOR NOW IGNORED
}


General idea what I want to do is:



  1. Create *.wav file.

  2. Write header chunk.

  3. Add new data at the end of file as long user doesn't stop it.

  4. When user clicks stop, go back to the header memory and edit field under "RIFF" and "data" chunks with right value.


First Question: So I have buffer storing 256 samples so in loop, every 256 I try to write buffer with new data to the file like in code below. After reading *.wav documentaiton http://ift.tt/1LBrP9M I understand that *.wav file should have RIFF header at start of each chunk. But if I write buffer with 256 samples and place RIFF chunk before it what's difference if I would enter 512 samples instead? Does every sample need RIFF chunk before it?



for (int j = 0 ; j < buffSize ; j++)
{
if (j == buffSize-1)
writeWAVData("mySound0.wav", (int*)bufferInfos[0].buffers[doubleBufferIndex], buffSize, 44100, 1);
}


Where:



  • bufferInfos[] - holds table of various buffers but I want to save data from only one now

  • bufferInfos[0].buffers[doubleBufferIndex] - is a pointer to first buffer data block

  • doubleBufferIndex - index of pan, takes values 0-1, left, right, left, right etc


Second question: is about channel parameter because it's a bit confusing. My signal consists of values received in turns: left pan, right pan, left pan, right pan... so that would mean I have 2 channels - left and right?


Aucun commentaire:

Enregistrer un commentaire