Introduction
Those who deal with voiceprints and prompts often should have prerecorded waves for testing/development, and sometimes you want to output a "joined wave", and even more better - get it dynamically. This article tries to solve this problem and create merged wave output "on the fly".
Background
It would be good for you to have a brief overview about wave format.
Using the code
The main points of CWave
class are it's constructor :
CWave(string fileName) throw(LPCSTR);
and operator+
CWave operator+(const CWave& w) const throw(LPCSTR);
The concatenation is implemented as follows:
CWave CWave::operator+ (const CWave &w) const{
if (fmt.wFormatTag!=w.fmt.wFormatTag)
throw "Can't concatenate waves with different format tags";
CWave ret_val;
ret_val.fmt = w.fmt;
ret_val.riff = w.riff;
ret_val.data = w.data;
ret_val.data.dataSIZE= data.dataSIZE+w.data.dataSIZE;
ret_val.extraParamLength = w.extraParamLength;
ret_val.extraParam = w.extraParam;
ret_val.wave = new BYTE[ret_val.data.dataSIZE];
memcpy(ret_val.wave,wave,data.dataSIZE);
memcpy(ret_val.wave+data.dataSIZE,w.wave,w.data.dataSIZE);
string folder = getFileFolder(fileName);
string title1 = getFileTitle(fileName);
string title2 = getFileTitle(w.fileName);
ret_val.fileName = folder;
ret_val.fileName.append(title1);
ret_val.fileName.append(title2);
ret_val.fileName.append(".wav");
return ret_val;
}
The usage is very simple:
CWave wave1("a1.wav");
CWave wave("b7.wav");
CWave wave3(wave1+wave2);
wave3.saveToFile();
Limitations
For the time being the CWave
class can deal with PCM waves, extraParams and "fact" chunks in wave header. You can parse another chunks if your waves contain ones. Also, the two wave files must have the same encoding format.