user-0 提问: 调用声卡做同步放音

回复:
user: user-1
content: void CSoundOut::PlayTaskFun() { #ifdef _WIN32 	/* 	* set up the WAVEFORMATEX structure. 	*/ 	WAVEFORMATEX wfx; /* look this up in your documentation */ 	wfx.nSamplesPerSec = 16000; /* sample rate */ 	wfx.wBitsPerSample = 16; /* sample size */ 	wfx.nChannels= 1; /* channels*/ 	wfx.cbSize = 0; /* size of _extra_ info */ 	wfx.wFormatTag = WAVE_FORMAT_PCM; 	wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3; 	wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; 	/* 	* try to open the default wave device. WAVE_MAPPER is 	* a constant defined in mmsystem.h, it always points to the 	* default wave device on the system (some people have 2 or 	* more sound cards). 	*/ 	_lockWaveOut.Lock(); 	_hWaveOutEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 	AIFASSERT(_hWaveOutEvent); 	if (_hWaveOutEvent) 	{ 		struct _WaveOutProc 		{ 			static void CALLBACK WaveOutProc(HWAVEOUT hWaveOut, UINT uMsg, HANDLE hEvent, DWORD dwParam1, DWORD dwParam2) 			{ 				if(uMsg == WOM_DONE) 				{ 					SetEvent(hEvent); 				} 			} 		};  		if(waveOutOpen(&_hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)_WaveOutProc::WaveOutProc, (DWORD_PTR)_hWaveOutEvent, CALLBACK_FUNCTION) == MMSYSERR_NOERROR) 		{ 			_lockWaveOut.Unlock(); 			WAVEHDR _whBlocks[2]; #else 	if (true) 	{ 		if (true) 		{ #endif 			while (_eventPlay.Wait(INFINITE) && _bActived) 			{ 				AIFASSERT(_pAsync); 				ISoundOutPlayAsync *pSoundOutPlayAsync = NULL; 				if (_pAsync) 				{ 					_pAsync->QueryInterface(&pSoundOutPlayAsync); 				} #ifdef _WIN32 				int nCurrent = 0; 				SetEvent(_hWaveOutEvent); 				for (int i = 0; (_bPlaying) && i < _nWaveID; ++i) 				{ 					int nWave = ((unsigned int *)_nWaveIDs[i])[-1]; 					char *pWave = (char *)_nWaveIDs[i]; 					//PlaySoundA(pWave, NULL, SND_MEMORY | SND_ASYNC); 					WAVEHDR *pWH = &_whBlocks[nCurrent]; 					if(pWH->dwFlags & WHDR_PREPARED) 					{ 						waveOutUnprepareHeader(_hWaveOut, pWH, sizeof (*pWH)); 					} 					ZeroMemory(pWH, sizeof (*pWH)); 					pWH->lpData = pWave; 					pWH->dwBufferLength = (DWORD)nWave; 					waveOutPrepareHeader(_hWaveOut, pWH, sizeof (*pWH)); 					waveOutWrite(_hWaveOut, pWH, sizeof (*pWH)); 					WaitForSingleObject(_hWaveOutEvent, INFINITE); 					nCurrent = nCurrent == 0 ? 1 : 0; 				} 				WaitForSingleObject(_hWaveOutEvent, INFINITE); #else 				PlayWave(_nWaveIDs, _nWaveID, _nChipSet, &_bPlaying, pSoundOutPlayAsync); #endif 				if (pSoundOutPlayAsync) 				{ 					pSoundOutPlayAsync->Release(); 				} 				if (!_bPlaying) 				{ // 如果是通过 Close 方法结束播放。 					// 那么设置等待事件，以便同时 Close 方法已经关闭完成。 					// 这里设置为空。 					// 因为整个播放线程是独立的， Close 方法可以立即返回。 				} 				else if (_pAsync) 				{ // 如果是正常播放完成。 					// 设置播放完成事件。 					_pAsync->SetEvent(); 				} 			} #ifdef _WIN32 			_lockWaveOut.Lock(); 			waveOutClose(_hWaveOut); 			_hWaveOut = NULL; 		} 		CloseHandle(_hWaveOutEvent); 		_hWaveOutEvent = NULL; 	} 	_lockWaveOut.Unlock(); #else 		} 	} #endif }

user: user-2
content: MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98 然后参考：MSDN98\SAMPLES\VC98\SDK\GRAPHICS\AUDIO\REVERSE\*.*

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:参考MSDN98里面的：Example of Writing Waveform Data The following example illustrates the steps required to allocate and set up a WAVEHDR structure and write a block of data to a waveform output device.   // Global variables.   HANDLE hData  = NULL;  // handle of waveform data memory  HPSTR  lpData = NULL;  // pointer to waveform data memory    void WriteWaveData(void)  {      HWAVEOUT    hWaveOut;      HGLOBAL     hWaveHdr;      LPWAVEHDR   lpWaveHdr;      HMMIO       hmmio;      UINT        wResult;      HANDLE      hFormat;      WAVEFORMAT  *pFormat;      DWORD       dwDataSize;       // Open a waveform device for output using window callback.       if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,                      (LPWAVEFORMAT)pFormat,                      (LONG)hwndApp, 0L, CALLBACK_WINDOW))      {          MessageBox(hwndApp,                     "Failed to open waveform output device.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          LocalUnlock(hFormat);          LocalFree(hFormat);          mmioClose(hmmio, 0);          return;      }        // Allocate and lock memory for the waveform data.        hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, dwDataSize );      if (!hData)      {          MessageBox(hwndApp, "Out of memory.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          mmioClose(hmmio, 0);          return;      }      if ((lpData = GlobalLock(hData)) == NULL)      {          MessageBox(hwndApp, "Failed to lock memory for data chunk.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          GlobalFree(hData);          mmioClose(hmmio, 0);          return;      }        // Read the waveform data subchunk.        if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LRESULT)dwDataSize)      {          MessageBox(hwndApp, "Failed to read data chunk.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          GlobalUnlock(hData);          GlobalFree(hData);          mmioClose(hmmio, 0);          return;      }        // Allocate and lock memory for the header.       hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,          (DWORD) sizeof(WAVEHDR));      if (hWaveHdr == NULL)      {          GlobalUnlock(hData);          GlobalFree(hData);          MessageBox(hwndApp, "Not enough memory for header.",              NULL, MB_OK | MB_ICONEXCLAMATION);          return;      }        lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);      if (lpWaveHdr == NULL)      {          GlobalUnlock(hData);          GlobalFree(hData);          MessageBox(hwndApp,              "Failed to lock memory for header.",              NULL, MB_OK | MB_ICONEXCLAMATION);          return;      }        // After allocation, set up and prepare header.        lpWaveHdr->lpData = lpData;      lpWaveHdr->dwBufferLength = dwDataSize;      lpWaveHdr->dwFlags = 0L;      lpWaveHdr->dwLoops = 0L;      waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));        // Now the data block can be sent to the output device. The      // waveOutWrite function returns immediately and waveform      // data is sent to the output device in the background.        wResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));      if (wResult != 0)      {          waveOutUnprepareHeader(hWaveOut, lpWaveHdr,                                 sizeof(WAVEHDR));          GlobalUnlock( hData);          GlobalFree(hData);          MessageBox(hwndApp, "Failed to write block to device",                     NULL, MB_OK | MB_ICONEXCLAMATION);          return;      }  }      ？我是网口数据传输。应该用二进制读取wav格式，这个程序不能用啊

user: user-0
content: 引用 楼主 zhanglusmile 的回复:in onreceivedData(STATTYPE *pStatparam,long* pByteSize,byte *byData) 这是我接受的数据byData,想调用底层声卡技术实现播放功能，大家有没有好的思路，我是先转化为wav,再播放，然而不是实时传输的，感觉不是很好，求好的思路我是网口数据传输。应该用二进制读取wav格式，这个程序不能用啊

user: user-2
content: 参考MSDN98里面的：Example of Writing Waveform Data The following example illustrates the steps required to allocate and set up a WAVEHDR structure and write a block of data to a waveform output device.   // Global variables.   HANDLE hData  = NULL;  // handle of waveform data memory  HPSTR  lpData = NULL;  // pointer to waveform data memory    void WriteWaveData(void)  {      HWAVEOUT    hWaveOut;      HGLOBAL     hWaveHdr;      LPWAVEHDR   lpWaveHdr;      HMMIO       hmmio;      UINT        wResult;      HANDLE      hFormat;      WAVEFORMAT  *pFormat;      DWORD       dwDataSize;       // Open a waveform device for output using window callback.       if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,                      (LPWAVEFORMAT)pFormat,                      (LONG)hwndApp, 0L, CALLBACK_WINDOW))      {          MessageBox(hwndApp,                     "Failed to open waveform output device.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          LocalUnlock(hFormat);          LocalFree(hFormat);          mmioClose(hmmio, 0);          return;      }        // Allocate and lock memory for the waveform data.        hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, dwDataSize );      if (!hData)      {          MessageBox(hwndApp, "Out of memory.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          mmioClose(hmmio, 0);          return;      }      if ((lpData = GlobalLock(hData)) == NULL)      {          MessageBox(hwndApp, "Failed to lock memory for data chunk.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          GlobalFree(hData);          mmioClose(hmmio, 0);          return;      }        // Read the waveform data subchunk.        if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LRESULT)dwDataSize)      {          MessageBox(hwndApp, "Failed to read data chunk.",                     NULL, MB_OK | MB_ICONEXCLAMATION);          GlobalUnlock(hData);          GlobalFree(hData);          mmioClose(hmmio, 0);          return;      }        // Allocate and lock memory for the header.       hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,          (DWORD) sizeof(WAVEHDR));      if (hWaveHdr == NULL)      {          GlobalUnlock(hData);          GlobalFree(hData);          MessageBox(hwndApp, "Not enough memory for header.",              NULL, MB_OK | MB_ICONEXCLAMATION);          return;      }        lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);      if (lpWaveHdr == NULL)      {          GlobalUnlock(hData);          GlobalFree(hData);          MessageBox(hwndApp,              "Failed to lock memory for header.",              NULL, MB_OK | MB_ICONEXCLAMATION);          return;      }        // After allocation, set up and prepare header.        lpWaveHdr->lpData = lpData;      lpWaveHdr->dwBufferLength = dwDataSize;      lpWaveHdr->dwFlags = 0L;      lpWaveHdr->dwLoops = 0L;      waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));        // Now the data block can be sent to the output device. The      // waveOutWrite function returns immediately and waveform      // data is sent to the output device in the background.        wResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));      if (wResult != 0)      {          waveOutUnprepareHeader(hWaveOut, lpWaveHdr,                                 sizeof(WAVEHDR));          GlobalUnlock( hData);          GlobalFree(hData);          MessageBox(hwndApp, "Failed to write block to device",                     NULL, MB_OK | MB_ICONEXCLAMATION);          return;      }  }      ？