[英]How to play G726 ADPCM buffer?
我想播放從IP攝像機接收到的音頻。 壓縮音頻數據的格式為G726 ADPCM。
我已經在互聯網上搜索了幾天,但還沒有完成。
我嘗試了許多方法來播放它。 試圖解碼為PCM並建立標頭以創建Wave文件,但都失敗了(也許我在執行此操作時有一些錯誤)。
但是今天,我找到了用於從PC錄制和播放波形音頻的代碼。
這是代碼:
// ADPCM.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <MMSystem.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
const int NUMPTS = 8000*10;//44100 * 10;
int sampleRate = 8000;//44100;
short int waveIn[NUMPTS];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;
result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);
if(result)
{
char fault[256];
waveInGetErrorTextA(result, fault, 256);
MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
return 1;
}
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = 2 * NUMPTS;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
if(result)
{
MessageBoxA(NULL, "Failed to read block from device", NULL, MB_OK | MB_ICONEXCLAMATION);
return 1;
}
result = waveInStart(hWaveIn);
if(result)
{
MessageBoxA(NULL, "Failed to start recording", NULL, MB_OK | MB_ICONEXCLAMATION);
return 1;
}
cout << "Recording..." << endl;
Sleep((NUMPTS/sampleRate) * 1000); //Sleep while recording
cout << "Playing..." << endl;
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
{
MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
}
waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr));
Sleep((NUMPTS/sampleRate) * 1000); //Sleep for as long as there was recorded
waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR));
waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
waveInClose(hWaveIn);
waveOutClose(hWaveOut);
return 0;
}
我將PCM數據存儲在緩沖區中,並且我想修改上面的代碼以播放它,因此我將其編輯為以下代碼:
const int NUMPTS = 4000;//44100 * 10;
int sampleRate = 8000;//44100;
CHAR waveIn[NUMPTS];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = sampleRate/2;//2 * sampleRate;
pFormat.nBlockAlign = 1;//2;
pFormat.wBitsPerSample = 4;//16;
pFormat.cbSize = 0;
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = 2 * NUMPTS;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
memcpy(WaveInHdr.lpData, myPCMBuffer, NUMPTS);
waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr));
waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR));
waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
waveInClose(hWaveIn);
waveOutClose(hWaveOut);
但是,在調用waveOutUnprepareHeader()時,拋出了消息“運行時檢查失敗#3-變量'hWaveIn'正在使用,沒有初始化”。
如何初始化hWaveIn?
這是我第一次使用Wave音頻,因此我很愚蠢。
您能告訴我正確的方法嗎?
要初始化hWaveIn,請打開音頻設備:
MMRESULT waveInOpen(
LPHWAVEIN phwi,
UINT uDeviceID,
LPCWAVEFORMATEX pwfx,
DWORD dwCallback,
DWORD dwInstance,
DWORD fdwOpen
);
范例 :
result = waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat,
0L, 0L, WAVE_FORMAT_DIRECT);
if (result)
{
char fault[256];
waveInGetErrorText(result, fault, 256);
Application->MessageBox(fault, "Failed to open waveform input device.",
MB_OK | MB_ICONEXCLAMATION);
return;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.