2011.03.31 By Pafone
这次来编译soundfileplayer,新建一个工程。像EMIPLIB-1.0.0的使用(一)那样在工程属性加入include的目录、库目录和库,还要额外加一个库winmm.lib,这个库不用指定路径。
编译:
1.编译时,说出找不到unistd.h,注释掉即可,原因在上篇文章已经说过。
2. 链接错
1>正在链接...
1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外部符号 __imp__waveOutOpen@24
1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外部符号 __imp__waveOutClose@4
1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外部符号 __imp__waveOutUnprepareHeader@12
1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外部符号 __imp__waveOutReset@4
1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外部符号 __imp__waveOutWrite@12
1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外部符号 __imp__waveOutPrepareHeader@12
通过网上查找 , 知要加入winmm.lib这个库。
运行测试:
在生成.exe目录内放一个wav文件并改名为soundfile.wav,必须用这个名,因为在代码中已经写死。运行soundfileplayer.exe便可以听到声音了。
程序讲解:
soundfileplayer.cpp
- int main(void)
- {
- MIPTime interval(0.050); // We'll use 50 millisecond intervals
- MIPAverageTimer timer(interval);
- MIPWAVInput sndFileInput;
- MIPSampleEncoder sampEnc;
- #ifndef WIN32
- MIPOSSInputOutput sndCardOutput;
- #else
- MIPWinMMOutput sndCardOutput;
- #endif
- MyChain chain("Sound file player");
- bool returnValue;
-
- // We'll open the file 'soundfile.wav'
-
- returnValue = sndFileInput.open("soundfile.wav", interval);
- checkError(returnValue, sndFileInput);
-
- // Get the parameters of the soundfile. We'll use these to initialize
- // the soundcard output component further on.
-
- int samplingRate = sndFileInput.getSamplingRate();
- int numChannels = sndFileInput.getNumberOfChannels();
-
- // Initialize the soundcard output
- returnValue = sndCardOutput.open(samplingRate, numChannels, interval);
- checkError(returnValue, sndCardOutput);
-
- // Initialize the sample encoder
- #ifndef WIN32
- // The OSS component can use several encoding types. We'll ask
- // the component to which format samples should be converted.
- returnValue = sampEnc.init(sndCardOutput.getRawAudioSubtype());
- #else
- // The WinMM output component uses signed little endian 16 bit samples.
- returnValue = sampEnc.init(MIPRAWAUDIOMESSAGE_TYPE_S16LE);
- #endif
- checkError(returnValue, sampEnc);
-
- // Next, we'll create the chain
- returnValue = chain.setChainStart(&timer);
- checkError(returnValue, chain);
-
- returnValue = chain.addConnection(&timer, &sndFileInput);
- checkError(returnValue, chain);
-
- returnValue = chain.addConnection(&sndFileInput, &sampEnc);
- checkError(returnValue, chain);
-
- returnValue = chain.addConnection(&sampEnc, &sndCardOutput);
- checkError(returnValue, chain);
-
- // Start the chain
-
- returnValue = chain.start();
- checkError(returnValue, chain);
-
- // We'll wait until enter is pressed
-
- getc(stdin);
-
- returnValue = chain.stop();
- checkError(returnValue, chain);
-
- // We'll let the destructors of the components take care
- // of their de-initialization.
-
- return 0;
- }
链的建立:
由以下代码可知, 链是这样的 timer –> sndfileInput –> sampEnc –> sndCardOutput
simplechain.cpp part0
- // Next, we'll create the chain
- returnValue = chain.setChainStart(&timer);
- checkError(returnValue, chain);
-
- returnValue = chain.addConnection(&timer, &sndFileInput);
- checkError(returnValue, chain);
-
- returnValue = chain.addConnection(&sndFileInput, &sampEnc);
- checkError(returnValue, chain);
-
- returnValue = chain.addConnection(&sampEnc, &sndCardOutput);
- checkError(returnValue, chain);
需要讲下的是sampEnc,这个是MIPSampleEncoder类,在mipsampleencoder.h中
/** Changes the sample encoding of raw audio messages.
* This component can be used to change the sample encoding of raw audio messages.
* It accepts all raw audio messages and produces similar raw audio messages, using
* a predefined encoding type.
*/
是用来改变原始声音数据编码的。因为声卡输入的格式为16位unsigned,而wavfile提供的数据不一定是这个,所以要加入这一sampEnc环节。
注:测试时必须用soundfile.wav这个文件名,因为代码已经写死