plugin_audio_dsp_utils.cxx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* Copyright (C) 2013 Mamadou DIOP
  2. * Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
  3. *
  4. * This file is part of Open Source Doubango Framework.
  5. *
  6. * DOUBANGO is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * DOUBANGO is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with DOUBANGO.
  18. */
  19. #include "plugin_audio_dsp_utils.h"
  20. #include "tsk_debug.h"
  21. #include <uuids.h>
  22. #include <Dmo.h>
  23. #include <Mfapi.h>
  24. #include <assert.h>
  25. bool AudioDSPUtils::g_bStarted = false;
  26. HRESULT AudioDSPUtils::Startup()
  27. {
  28. if(!g_bStarted) {
  29. HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  30. if(SUCCEEDED(hr) || hr == 0x80010106) { // 0x80010106 when called from managed code (e.g. Boghe) - More info: http://support.microsoft.com/kb/824480
  31. hr = MFStartup(MF_VERSION);
  32. }
  33. g_bStarted = SUCCEEDED(hr);
  34. return hr;
  35. }
  36. return S_OK;
  37. }
  38. HRESULT AudioDSPUtils::Shutdown()
  39. {
  40. return S_OK;
  41. }
  42. HRESULT AudioDSPUtils::CreatePCMAudioType(
  43. UINT32 sampleRate, // Samples per second
  44. UINT32 bitsPerSample, // Bits per sample
  45. UINT32 cChannels, // Number of channels
  46. IMFMediaType **ppType // Receives a pointer to the media type.
  47. )
  48. {
  49. HRESULT hr = S_OK;
  50. IMFMediaType *pType = NULL;
  51. // Calculate derived values.
  52. UINT32 blockAlign = cChannels * (bitsPerSample >> 3);
  53. UINT32 bytesPerSecond = blockAlign * sampleRate;
  54. // Create the empty media type.
  55. CHECK_HR(hr = MFCreateMediaType(&pType));
  56. // Set attributes on the type.
  57. CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio));
  58. CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM));
  59. CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, cChannels));
  60. CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, sampleRate));
  61. CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, blockAlign));
  62. CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bytesPerSecond));
  63. CHECK_HR(hr = pType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample));
  64. CHECK_HR(hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE));
  65. CHECK_HR(hr = pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE));
  66. *ppType = pType;
  67. (*ppType)->AddRef();
  68. bail:
  69. SafeRelease(&pType);
  70. return hr;
  71. }
  72. HRESULT AudioDSPUtils::CreateMediaSample(
  73. DWORD cbData, // Maximum buffer size
  74. IMFSample **ppSample // Receives the sample
  75. )
  76. {
  77. HRESULT hr = S_OK;
  78. if(!ppSample) {
  79. CHECK_HR(hr = E_POINTER);
  80. }
  81. IMFSample *pSample = NULL;
  82. IMFMediaBuffer *pBuffer = NULL;
  83. CHECK_HR(hr = MFCreateSample(&pSample));
  84. CHECK_HR(hr = MFCreateMemoryBuffer(cbData, &pBuffer));
  85. CHECK_HR(hr = pSample->AddBuffer(pBuffer));
  86. *ppSample = pSample;
  87. (*ppSample)->AddRef();
  88. bail:
  89. SafeRelease(&pSample);
  90. SafeRelease(&pBuffer);
  91. return hr;
  92. }
  93. HRESULT AudioDSPUtils::MoInitMediaType(
  94. UINT32 sampleRate, // Samples per second
  95. UINT32 bitsPerSample, // Bits per sample
  96. UINT32 cChannels, // Number of channels
  97. DMO_MEDIA_TYPE *pType // The media type to initialize. Must be freed using MoFreeMediaType.
  98. )
  99. {
  100. HRESULT hr = S_OK;
  101. WAVEFORMATEX *pWAV = NULL;
  102. if(!pType) {
  103. CHECK_HR(hr = E_POINTER);
  104. }
  105. pType->majortype = MEDIATYPE_Audio;
  106. pType->subtype = MEDIASUBTYPE_PCM;
  107. pType->lSampleSize = 0;
  108. pType->bFixedSizeSamples = TRUE;
  109. pType->bTemporalCompression = FALSE;
  110. pType->formattype = FORMAT_WaveFormatEx;
  111. CHECK_HR(hr = ::MoInitMediaType(pType, sizeof(WAVEFORMATEX)));
  112. pWAV = (WAVEFORMATEX*)pType->pbFormat;
  113. pWAV->wFormatTag = WAVE_FORMAT_PCM;
  114. pWAV->nChannels = 1;
  115. pWAV->nSamplesPerSec = sampleRate;
  116. pWAV->nBlockAlign = cChannels * (bitsPerSample >> 3);
  117. pWAV->nAvgBytesPerSec = pWAV->nBlockAlign * pWAV->nSamplesPerSec;
  118. pWAV->wBitsPerSample = bitsPerSample;
  119. pWAV->cbSize = 0;
  120. bail:
  121. return hr;
  122. }