DirectShow技术
DirectShow包含了音视频的内容,是音视频处理的框架。DirectShow会使用DirectSound等技术来管理设备,完成音频数据采集,音频播放等。DirectShow是面向程序应用开发的音视频处理开发框架。
DirectSound
音频输入采集
获取所有音频采集设备
- 相关函数DirectSoundCaptureEnumerate、DSEnumCallback
- DirectSound的这个接口并不能枚举获取到所有的音频输入设备,对于某些采集卡内置声道无法获取到
- DSEnumCallbak只能获取到设备的GUID、描述信息(设备显示的名称)、路径id。而且描述信息只有32个字符,可能无法显示完整的设备名称。
创建Capture、Buffer
- 介绍的链接
- 相关函数 DirectSoundCaptureCreate、IDirectSoundCapture8::CreateCaptureBuffer、WAVEFORMATEX
- 在创建Capture Buffer时需要传入WAVEFORMATEX结构体,并根据WAVEFORMATEX计算一个能够以sample对齐的buffer长度。成功创建Buffer之后,Buffer中的数据就是按照WAVEFORMATEX制定的格式保存。
HRESULT CreateCaptureBuffer(LPDIRECTSOUNDCAPTURE8 pDSC,
LPDIRECTSOUNDCAPTUREBUFFER8* ppDSCB8)
{
HRESULT hr;
DSCBUFFERDESC dscbd;
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
WAVEFORMATEX wfx =
{WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0};
// wFormatTag, nChannels, nSamplesPerSec, mAvgBytesPerSec,
// nBlockAlign, wBitsPerSample, cbSize
if ((NULL == pDSC) || (NULL == ppDSCB8)) return E_INVALIDARG;
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = wfx.nAvgBytesPerSec;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
if (SUCCEEDED(hr = pDSC->CreateCaptureBuffer(&dscbd, &pDSCB, NULL)))
{
hr = pDSCB->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)ppDSCB8);
pDSCB->Release();
}
return hr;
}
从Capture Buffer中读取数据
- 介绍的链接
- 相关函数 IDirectSoundCaptureBuffer8::GetCurrentPosition、IDirectSoundCaptureBuffer8::Lock、IDirectSoundCaptureBuffer8::Unlock、IDirectSoundNotify8::SetNotificationPositions
- 通过调用Lock函数获取Capture Buffer的内存地址,然后进行数据拷贝,拷贝完成后必须进行Unlock。
- Capture Buffer是一个循环Buffer。调用者保存上一次拷贝完成后的数据末尾的偏移量rpos1,之后每次读取之前调用GetCurrentPosition获取当前可读取的数据的末尾的偏移量rpos2,[rpos2, rpos1]区间内的数据就是需要拷贝的数据。注意因为Capture Buffer是循环Buffer,因此可能rpos2 < rpos1。
- 读取Capture Buffer的时机:
- 使用循环不断调用GetCurrentPosition,Lock,Unlock读取Buffer中的值
- 使用SetNotificationPositions设置事件(Event)触发的读取点。当Capture Buffer在某个Position可读时触发事件,此时再去读取。