154 lines
4.3 KiB
C++
Executable File
154 lines
4.3 KiB
C++
Executable File
/* Copyright (C) 2013 Mamadou DIOP
|
|
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
|
|
*
|
|
* This file is part of Open Source Doubango Framework.
|
|
*
|
|
* DOUBANGO is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* DOUBANGO is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with DOUBANGO.
|
|
*/
|
|
#include "plugin_audio_dsp_utils.h"
|
|
#include "tsk_debug.h"
|
|
|
|
#include <uuids.h>
|
|
#include <Dmo.h>
|
|
#include <Mfapi.h>
|
|
#include <assert.h>
|
|
|
|
bool AudioDSPUtils::g_bStarted = false;
|
|
|
|
HRESULT AudioDSPUtils::Startup()
|
|
{
|
|
if(!g_bStarted) {
|
|
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
if(SUCCEEDED(hr) || hr == 0x80010106) { // 0x80010106 when called from managed code (e.g. Boghe) - More info: http://support.microsoft.com/kb/824480
|
|
hr = MFStartup(MF_VERSION);
|
|
}
|
|
g_bStarted = SUCCEEDED(hr);
|
|
return hr;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT AudioDSPUtils::Shutdown()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT AudioDSPUtils::CreatePCMAudioType(
|
|
UINT32 sampleRate, // Samples per second
|
|
UINT32 bitsPerSample, // Bits per sample
|
|
UINT32 cChannels, // Number of channels
|
|
IMFMediaType **ppType // Receives a pointer to the media type.
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
IMFMediaType *pType = NULL;
|
|
|
|
// Calculate derived values.
|
|
UINT32 blockAlign = cChannels * (bitsPerSample >> 3);
|
|
UINT32 bytesPerSecond = blockAlign * sampleRate;
|
|
|
|
// Create the empty media type.
|
|
CHECK_HR(hr = MFCreateMediaType(&pType));
|
|
|
|
// Set attributes on the type.
|
|
CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio));
|
|
|
|
CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, cChannels));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, sampleRate));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, blockAlign));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bytesPerSecond));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE));
|
|
|
|
CHECK_HR(hr = pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE));
|
|
|
|
*ppType = pType;
|
|
(*ppType)->AddRef();
|
|
|
|
bail:
|
|
SafeRelease(&pType);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT AudioDSPUtils::CreateMediaSample(
|
|
DWORD cbData, // Maximum buffer size
|
|
IMFSample **ppSample // Receives the sample
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(!ppSample) {
|
|
CHECK_HR(hr = E_POINTER);
|
|
}
|
|
|
|
IMFSample *pSample = NULL;
|
|
IMFMediaBuffer *pBuffer = NULL;
|
|
|
|
CHECK_HR(hr = MFCreateSample(&pSample));
|
|
CHECK_HR(hr = MFCreateMemoryBuffer(cbData, &pBuffer));
|
|
CHECK_HR(hr = pSample->AddBuffer(pBuffer));
|
|
|
|
*ppSample = pSample;
|
|
(*ppSample)->AddRef();
|
|
|
|
bail:
|
|
SafeRelease(&pSample);
|
|
SafeRelease(&pBuffer);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT AudioDSPUtils::MoInitMediaType(
|
|
UINT32 sampleRate, // Samples per second
|
|
UINT32 bitsPerSample, // Bits per sample
|
|
UINT32 cChannels, // Number of channels
|
|
DMO_MEDIA_TYPE *pType // The media type to initialize. Must be freed using MoFreeMediaType.
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WAVEFORMATEX *pWAV = NULL;
|
|
|
|
if(!pType) {
|
|
CHECK_HR(hr = E_POINTER);
|
|
}
|
|
|
|
pType->majortype = MEDIATYPE_Audio;
|
|
pType->subtype = MEDIASUBTYPE_PCM;
|
|
pType->lSampleSize = 0;
|
|
pType->bFixedSizeSamples = TRUE;
|
|
pType->bTemporalCompression = FALSE;
|
|
pType->formattype = FORMAT_WaveFormatEx;
|
|
|
|
CHECK_HR(hr = ::MoInitMediaType(pType, sizeof(WAVEFORMATEX)));
|
|
|
|
pWAV = (WAVEFORMATEX*)pType->pbFormat;
|
|
pWAV->wFormatTag = WAVE_FORMAT_PCM;
|
|
pWAV->nChannels = 1;
|
|
pWAV->nSamplesPerSec = sampleRate;
|
|
pWAV->nBlockAlign = cChannels * (bitsPerSample >> 3);
|
|
pWAV->nAvgBytesPerSec = pWAV->nBlockAlign * pWAV->nSamplesPerSec;
|
|
pWAV->wBitsPerSample = bitsPerSample;
|
|
pWAV->cbSize = 0;
|
|
|
|
bail:
|
|
return hr;
|
|
}
|