How to write mic data to .wav file ?
-
Good morning, I have trouble creating a wave file from the data stream I got from the microphone input. The recording seems to go quite well but know I´m stuck at the task of converting that data into a wave file. I recorded the mic data into a WAVEHDR structure like this ...
const int NUMPTS = 44100 * 10; // 10 seconds
int sampleRate = 44100;
short int waveIn[NUMPTS]; // 'short int' is a 16-bit type; I request 16-bit samples below
// for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit typesHWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;int main( int argc, char *argv[] )
{
// Specify recording parameters
WAVEFORMATEX pFormat;
pFormat.wFormatTag=WAVE_FORMAT_PCM; // simple, uncompressed format
pFormat.nChannels=1; // 1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate; // 44100
pFormat.nAvgBytesPerSec=sampleRate*2; // = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.nBlockAlign=2; // = n.Channels * wBitsPerSample/8
pFormat.wBitsPerSample=16; // 16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;result = waveInOpen(&hWaveIn, WAVE\_MAPPER,&pFormat, 0L, 0L, WAVE\_FORMAT\_DIRECT); if (result) { char fault\[256\]; waveInGetErrorText(result, fault, 256); return 1; } // Set up and prepare header for input WaveInHdr.lpData = (LPSTR)waveIn; WaveInHdr.dwBufferLength = NUMPTS\*2; WaveInHdr.dwBytesRecorded=0; WaveInHdr.dwUser = 0L; WaveInHdr.dwFlags = 0L; WaveInHdr.dwLoops = 0L; waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)); // Insert a wave input buffer result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)); if (result) { return 1; } // Commence sampling input result = waveInStart(hWaveIn); if (result) { return 1; } // Wait until finished recording do { // record for 10 seconds } while (waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR))==WAVERR\_STILLPLAYING); waveInClose(hWaveIn); save(); std::cin.get(); return 0;
}
... and now I am trying to store the data to a wave file like this:
bool save()
{
int subchunk2size = WaveInHdr.dwBufferLength*1*2;fstream myFile ("test.wav", ios::out | ios::binary); // write the wav file per the wav file format myFile.seekp (0, ios::beg); myFile.write ("RIFF", 4); // chunk id myFile.write ((char\*) 36+subchunk2size, 4); // chunk size (36 + SubChunk2Size)
-
Good morning, I have trouble creating a wave file from the data stream I got from the microphone input. The recording seems to go quite well but know I´m stuck at the task of converting that data into a wave file. I recorded the mic data into a WAVEHDR structure like this ...
const int NUMPTS = 44100 * 10; // 10 seconds
int sampleRate = 44100;
short int waveIn[NUMPTS]; // 'short int' is a 16-bit type; I request 16-bit samples below
// for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit typesHWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;int main( int argc, char *argv[] )
{
// Specify recording parameters
WAVEFORMATEX pFormat;
pFormat.wFormatTag=WAVE_FORMAT_PCM; // simple, uncompressed format
pFormat.nChannels=1; // 1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate; // 44100
pFormat.nAvgBytesPerSec=sampleRate*2; // = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.nBlockAlign=2; // = n.Channels * wBitsPerSample/8
pFormat.wBitsPerSample=16; // 16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;result = waveInOpen(&hWaveIn, WAVE\_MAPPER,&pFormat, 0L, 0L, WAVE\_FORMAT\_DIRECT); if (result) { char fault\[256\]; waveInGetErrorText(result, fault, 256); return 1; } // Set up and prepare header for input WaveInHdr.lpData = (LPSTR)waveIn; WaveInHdr.dwBufferLength = NUMPTS\*2; WaveInHdr.dwBytesRecorded=0; WaveInHdr.dwUser = 0L; WaveInHdr.dwFlags = 0L; WaveInHdr.dwLoops = 0L; waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)); // Insert a wave input buffer result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)); if (result) { return 1; } // Commence sampling input result = waveInStart(hWaveIn); if (result) { return 1; } // Wait until finished recording do { // record for 10 seconds } while (waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR))==WAVERR\_STILLPLAYING); waveInClose(hWaveIn); save(); std::cin.get(); return 0;
}
... and now I am trying to store the data to a wave file like this:
bool save()
{
int subchunk2size = WaveInHdr.dwBufferLength*1*2;fstream myFile ("test.wav", ios::out | ios::binary); // write the wav file per the wav file format myFile.seekp (0, ios::beg); myFile.write ("RIFF", 4); // chunk id myFile.write ((char\*) 36+subchunk2size, 4); // chunk size (36 + SubChunk2Size)
Well, nevermind. I just fixed it :). Modified the save function like this:
bool save()
{
int bitsPerSample = 16;
int subchunk1size = 16;
int numChannels = 1;
int subchunk2size = WaveInHdr.dwBufferLength*numChannels;
int chunksize = 36+subchunk2size;
int audioFormat = 1;
int byteRate = sampleRate*numChannels*bitsPerSample/8;
int blockAlign = numChannels*bitsPerSample/8;fstream myFile ("test.wav", ios::out | ios::binary); // write the wav file per the wav file format myFile.seekp (0, ios::beg); myFile.write ("RIFF", 4); // chunk id myFile.write ((char\*) &chunksize, 4); // chunk size (36 + SubChunk2Size)) myFile.write ("WAVE", 4); // format myFile.write ("fmt ", 4); // subchunk1ID myFile.write ((char\*) &subchunk1size, 4); // subchunk1size (16 for PCM) myFile.write ((char\*) &audioFormat, 2); // AudioFormat (1 for PCM) myFile.write ((char\*) &numChannels, 2); // NumChannels myFile.write ((char\*) &sampleRate, 4); // sample rate myFile.write ((char\*) &byteRate, 4); // byte rate (SampleRate \* NumChannels \* BitsPerSample/8) myFile.write ((char\*) &blockAlign, 2); // block align (NumChannels \* BitsPerSample/8) myFile.write ((char\*) &bitsPerSample, 2); // bits per sample myFile.write ("data", 4); // subchunk2ID myFile.write ((char\*) &subchunk2size, 4); // subchunk2size (NumSamples \* NumChannels \* BitsPerSample/8) myFile.write (WaveInHdr.lpData, WaveInHdr.dwBufferLength); // data return true;
}
Cheers Souldrift