tapiwave.c
来自「一个tapi开发的很好的语音通信程序」· C语言 代码 · 共 1,109 行 · 第 1/3 页
C
1,109 行
printf("mmioOpen failed to open file.\n");
return FALSE;
}
// Locate a 'RIFF' chunk with a 'WAVE' form type to make sure it's a WAVE file.
mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmResult = mmioDescend(hmmio, &mmckinfoParent, NULL, MMIO_FINDRIFF))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("mmioDescend RIFF WAVE returned %s\r\n", szBuff);
mmioClose(hmmio, 0);
return FALSE;
}
// Now, find the format chunk (form type 'fmt '). It should be
// a subchunk of the 'RIFF' parent chunk.
mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
MMIO_FINDCHUNK))
{
printf("Wave file corrupt.\n");
mmioClose(hmmio, 0);
return FALSE;
}
// Get the size of the format chunk, allocate and lock memory for it.
dwFmtSize = mmckinfoSubchunk.cksize;
pFormat = LocalAlloc(LPTR, LOWORD(dwFmtSize));
if (!pFormat)
{
printf("Memory error.\n");
mmioClose(hmmio, 0);
return FALSE;
}
// Read the format chunk.
if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != (LONG) dwFmtSize)
{
printf("mmioRead: failed to read FMT chunk.\n");
LocalFree( pFormat );
mmioClose(hmmio, 0);
return FALSE;
}
printf("wFormatTag = %lu\n", (DWORD) pFormat->wFormatTag);
printf("nChannels = %lu\n", (DWORD) pFormat->nChannels );
printf("nSamplesPerSec = %lu\n", (DWORD) pFormat->nSamplesPerSec);
printf("nAvgBytesPerSec = %lu\n", (DWORD) pFormat->nAvgBytesPerSec);
printf("nBlockAlign = %lu\n", (DWORD) pFormat->nBlockAlign);
printf("wBitsPerSample = %lu\n", (DWORD) pFormat->wBitsPerSample);
printf("cbSize = %lu\n", (DWORD) pFormat->cbSize);
if (WAVE_MAPPER == WaveInID)
mmResult = waveInOpen(&hWaveIn, WaveInID, pFormat, 0, 0L,
WAVE_FORMAT_QUERY);
else
mmResult = waveInOpen(&hWaveIn, WaveInID, pFormat, 0, 0L,
dwWaveMapped | WAVE_FORMAT_QUERY);
if (mmResult)
{
waveInGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveInOpen while QUERY returned %s\r\n", szBuff);
LocalFree( pFormat );
mmioClose(hmmio, 0);
}
else
printf("Valid WaveIn format.\n");
// Make sure a waveform output device supports this format.
if (WAVE_MAPPER == WaveOutID)
mmResult = waveOutOpen(&hWaveOut, WaveOutID, pFormat, 0, 0L,
WAVE_FORMAT_QUERY);
else
mmResult = waveOutOpen(&hWaveOut, WaveOutID, pFormat, 0, 0L,
dwWaveMapped | WAVE_FORMAT_QUERY);
if (mmResult)
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutOpen while QUERY returned %s\r\n", szBuff);
LocalFree( pFormat );
mmioClose(hmmio, 0);
return FALSE;
}
// Ascend out of the format subchunk.
mmioAscend(hmmio, &mmckinfoSubchunk, 0);
// Find the data subchunk.
mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
MMIO_FINDCHUNK))
{
printf("mmioDescend: No DATA chunk.\n");
LocalFree( pFormat );
mmioClose(hmmio, 0);
return FALSE;
}
// Get the size of the data subchunk.
dwDataSize = mmckinfoSubchunk.cksize;
if (dwDataSize == 0L)
{
printf("Data chunk actually has no data.\n");
LocalFree( pFormat );
mmioClose(hmmio, 0);
return FALSE;
}
printf("Size of data is %lu\n",dwDataSize);
// Open a waveform output device.
if (WaveOutID == WAVE_MAPPER)
mmResult = waveOutOpen(&hWaveOut, WaveOutID,
pFormat, 0 /* (UINT)hwndApp */, 0L, 0/*| CALLBACK_WINDOW*/);
else
mmResult = waveOutOpen(&hWaveOut, WaveOutID,
pFormat, 0 /* (UINT)hwndApp */, 0L, 0 /*WAVE_MAPPED*/ /*| CALLBACK_WINDOW*/);
if (mmResult)
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutOpen returned %s\r\n", szBuff);
LocalFree( pFormat );
mmioClose(hmmio, 0);
return FALSE;
}
// Save block alignment info for later use.
wBlockSize = pFormat->nBlockAlign;
// We're done with the format header, free it.
LocalFree( pFormat );
// Allocate and lock memory for the waveform data.
lpData = LocalAlloc(LPTR, dwDataSize );
if (!lpData)
{
printf("Memory problems.\n");
mmioClose(hmmio, 0);
return FALSE;
}
// Read the waveform data subchunk.
if(mmioRead(hmmio, lpData, dwDataSize) != (LONG) dwDataSize)
{
printf("Failed to read waveform data subchunk.\n");
LocalFree( lpData );
mmioClose(hmmio, 0);
return FALSE;
}
// We're done with the file, close it.
mmioClose(hmmio, 0);
/* If you need instance data for a waveform data block, allocate some
* memory and store the pointer in lpWaveHdr->dwUser, before the call
* to waveOutPrepareHeader(). The code inside the #if 0 / #endif, and
* the commented-out lpWaveHdr->dwUser = ... illustrate this.
* Don't forget to free the instance memory when you're done with it,
* or on error bailout.
*/
#if 0
lpYourData = LocalAlloc(LPTR, sizeof(YOURDATA));
if (!lpYourData)
{
printf("Memory issues.\n");
StopConnectedStuff();
return FALSE;
}
#endif
// Here is the infinite loop test with multiple buffers
// note that this test doesn't clean up memory when its done.
if (dwWaveBuffers)
{
LPWAVEHDR * lpWaveHdrs = NULL;
DWORD i;
DWORD dwWaveIndex = 0;
// Round this up to the next nearest whole wBlockSize value;
dwWaveBuffSize += wBlockSize -1;
dwWaveBuffSize -= dwWaveBuffSize % wBlockSize;
printf("Allocating %lu buffers of size %lu\n", dwWaveBuffers, dwWaveBuffSize);
// allocate our array of wave header pointers
lpWaveHdrs = (LPWAVEHDR *) LocalAlloc(LPTR, (DWORD) sizeof(LPWAVEHDR) * dwWaveBuffers);
if (!lpWaveHdrs)
{
printf("Memory issues.\n");
StopConnectedStuff();
return FALSE;
}
// initiate all the buffers
for(i = 0; (i < dwWaveBuffers) && !(bReadyToEnd || bDropped); i++)
{
// allocate each wave header
if (!(lpWaveHdrs[i] = (LPWAVEHDR) LocalAlloc(LPTR, (DWORD) sizeof(WAVEHDR))))
{
printf("Memory issues.\n");
StopConnectedStuff();
return FALSE;
}
// Set up each WAVEHDR structure
lpWaveHdrs[i]->lpData = LocalAlloc(LPTR, (DWORD) dwWaveBuffSize);
lpWaveHdrs[i]->dwBufferLength = dwWaveBuffSize;
lpWaveHdrs[i]->dwFlags = 0L;
lpWaveHdrs[i]->dwLoops = 0L;
if (dwWaveIndex + dwWaveBuffSize >= dwDataSize)
{
memcpy(lpWaveHdrs[i]->lpData, &lpData[dwWaveIndex], dwDataSize-dwWaveIndex);
lpWaveHdrs[i]->dwBufferLength = dwDataSize-dwWaveIndex;
dwWaveIndex =0;
printf("End of wave file reached in buffer %lu. Duplicating.\n", i);
}
else
{
memcpy(lpWaveHdrs[i]->lpData, &lpData[dwWaveIndex], dwWaveBuffSize);
dwWaveIndex += dwWaveBuffSize;
}
// prepare each WAVEHDR
if(mmResult = waveOutPrepareHeader(hWaveOut, lpWaveHdrs[i], sizeof(WAVEHDR)))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutPrepareHeader returned %s\r\n", szBuff);
StopConnectedStuff();
return FALSE;
}
}
// force each of the buffers into the driver.
for(i = 0; (i < dwWaveBuffers) && !(bReadyToEnd || bDropped); i++)
{
// Then the data block can be sent to the output device.
if (mmResult = waveOutWrite(hWaveOut, lpWaveHdrs[i], sizeof(WAVEHDR)))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutWrite returned %s\r\n", szBuff);
StopConnectedStuff();
return FALSE;
}
if (!(lpWaveHdrs[i]->dwFlags & WHDR_INQUEUE))
{
printf("waveOutWrite %lu not queued.", i);
break;
}
printf("Initial waveOutWrite buffer %lu succeeded!.\n", i);
}
// now wait for each buffer to finish
if (i == dwWaveBuffers)
i = 0;
while(!(bReadyToEnd || bDropped))
{
if (lpWaveHdrs[i]->dwFlags & WHDR_DONE)
{
lpWaveHdrs[i]->dwFlags = 0L;
if (mmResult = waveOutWrite(hWaveOut, lpWaveHdrs[i], sizeof(WAVEHDR)))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutWrite returned %s\r\n", szBuff);
StopConnectedStuff();
return FALSE;
}
printf("waveOutWrite buffer %lu succeeded!.\n", i);
i++;
if (i >= dwWaveBuffers)
i=0;
}
PumpMessages(FALSE);
Sleep(0);
}
StopConnectedStuff();
return FALSE;
} // end of the infinite loop buffer test
// Allocate a waveform data header. The WAVEHDR must be
// globally allocated and locked.
lpWaveHdr = (LPWAVEHDR)LocalAlloc(LPTR, (DWORD) sizeof(WAVEHDR));
if (!lpWaveHdr)
{
printf("Memory issues.\n");
StopConnectedStuff();
return FALSE;
}
// Set up WAVEHDR structure and prepare it to be written to wave device.
lpWaveHdr->lpData = lpData;
lpWaveHdr->dwBufferLength = dwDataSize;
lpWaveHdr->dwFlags = 0L;
lpWaveHdr->dwLoops = 0L;
printf("dwDatasize %lu\n",dwDataSize);
// lpWaveHdr->dwUser = (DWORD) lpYourData; // save instance data ptr
if(mmResult = waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutPrepareHeader returned %s\r\n", szBuff);
StopConnectedStuff();
return FALSE;
}
// Then the data block can be sent to the output device.
if (mmResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutWrite returned %s\r\n", szBuff);
}
else
{
printf("waveOutWrite succeeded!.\n");
while (!(lpWaveHdr->dwFlags & WHDR_DONE))
{
PumpMessages(FALSE);
if (bReadyToEnd || bDropped)
break;
Sleep(0); // Release the rest of my time slice.
}
}
StopConnectedStuff();
return FALSE;
}
void StopConnectedStuff()
{
MMRESULT mmResult;
if (lpWaveHdr)
{
if(mmResult = waveOutUnprepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR) ))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutUnprepareHeader returned %s\r\n", szBuff);
}
LocalFree( lpWaveHdr );
lpWaveHdr = NULL;
}
if (mmResult = waveOutReset(hWaveOut))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutReset returned %s\r\n", szBuff);
}
Sleep(500); // Give it 1/2 sec to actually reset.
if(mmResult = waveOutClose(hWaveOut))
{
waveOutGetErrorText(mmResult, szBuff, sizeof(szBuff));
printf("waveOutClose returned %s\r\n", szBuff);
}
Sleep(500); // Give it 1/2 sec to clean up.
LocalFree( lpData );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?