📄 wavecn_com 世纪音频 - 音频应用 - 基于wavex低级音频函数的实时语音通信.htm
字号:
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>为录音设备准备缓存:<SPAN> waveInPrepareHeader</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>为输入设备增加缓存:<SPAN> waveInAddBuffer</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>启动录音:<SPAN>
waveInStart</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>清除缓存:
<SPAN>waveInUnprepareHeader</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>停止录音:<SPAN>
waveInReset</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>关闭录音设备:
<SPAN>waveInClose</SPAN></P></DIV>
<P style="TEXT-ALIGN: center" align=center>图<SPAN>3.1
</SPAN>录音流程</P>
<P> 在这个过程中,会产生很多<SPAN>WM_WIM_***</SPAN>格式的<SPAN>WINDOWS</SPAN>消息。程序通过捕获这些消息对缓存,数据和设备进行处理,具体可见后面章节。录音设备打开时,可以指定消息的响应方式:回掉函数,线程<SPAN>ID</SPAN>,<SPAN>WINDOWS</SPAN>窗口句柄或事件句柄等。</P>
<DIV
style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: navy 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 1pt; BORDER-LEFT: navy 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: navy 1pt solid">
<P class=SourceCode><SPAN>MMRESULT waveInOpen(</SPAN></P>
<P class=SourceCode><SPAN> LPHWAVEIN phwi,
//</SPAN>输入设备句柄<SPAN>
</SPAN></P>
<P class=SourceCode><SPAN> UINT uDeviceID,
//</SPAN>输入设备<SPAN>ID</SPAN></P>
<P class=SourceCode><SPAN> LPWAVEFORMATEX pwfx,
//</SPAN>录音格式指针<SPAN> </SPAN></P>
<P class=SourceCode><SPAN> DWORD
dwCallback,
//</SPAN>处理消息的回调函数或窗口句柄,线程<SPAN>ID</SPAN>等</P>
<P class=SourceCode><SPAN> DWORD dwCallbackInstance,
//</SPAN>通常为<SPAN>0 </SPAN></P>
<P class=SourceCode><SPAN> DWORD fdwOpen
//</SPAN>处理消息方式的符号位</P>
<P class=SourceCode><SPAN>);</SPAN></P></DIV>
<P> 调用<SPAN>WaveX </SPAN>低级音频函数<SPAN>API</SPAN>启动声卡输出的基本操作步骤如下图所示:</P>
<DIV
style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>打开输出设备: <SPAN>waveOutOpen</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>为输出设备准备缓存:
<SPAN>waveOutPrepareHeader</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>写数据导输出设备缓存:
<SPAN>waveOutWrite</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>清除输出缓存: <SPAN>waveOutUnprepareHeader</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>停止输出:
<SPAN>waveOutReset</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>关闭输出设备: <SPAN>waveOutClose</SPAN></P></DIV>
<P style="TEXT-ALIGN: center" align=center>图<SPAN>3.2
</SPAN>播放流程</P>
<P> 同录音一样,在音频输出过程中也有一系列的消息,程序通过捕获这些消息对缓存,数据和设备进行处理。具体操作见后面章节。</P>
<H1><A id=_Toc162973510 name=_Toc162973510><SPAN>6 </SPAN>消息及处理</A></H1>
<P> <SPAN>WINDOWS</SPAN>下提供消息映射实现事件的处理。低级音频函数处理声音数据块也正要归功于<SPAN>WINDOW</SPAN>的消息映射机制。</P>
<P> 图<SPAN>6.1 </SPAN>和<SPAN>6.2</SPAN>分别描述了声卡录音和播放过程中产生的消息:</P>
<DIV
style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
WM_WIM_OPEN</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│<SPAN> </SPAN>↘</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│ <SPAN> </SPAN>音频输入 设备打开消息</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
WM_WIM_DATA</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│<SPAN> </SPAN>↘</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│<SPAN> </SPAN>缓冲录满或停止录音消息</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
WM_WIM_CLOSE</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│<SPAN> </SPAN>↘ </P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>↓<SPAN> </SPAN>音频输入
设备关闭消息</P></DIV>
<P style="TEXT-ALIGN: center" align=center><SPAN>6.1
</SPAN>录音过程消息</P>
<DIV
style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
WM_WOM_OPEN</SPAN></P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│<SPAN> </SPAN>↘</P>
<P class=TextGraph
style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; BACKGROUND: #ccffcc; PADDING-BOTTOM: 0pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0pt; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"><SPAN>
</SPAN>│ <SPAN> </SPAN>音频输出 设备打开消息</P>
<P class=TextGraph
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -