reference

This documentation is automatically generated from the openFrameworks source code using doxygen and refers to the most recent release, version 0.12.0.

ofMediaFoundationSoundPlayer.h
Go to the documentation of this file.
1#pragma once
2
3#include "ofSoundBaseTypes.h"
4#include "ofEvents.h"
5
6#include <mfidl.h>
7#include <mfapi.h>
8#include <mfreadwrite.h>
9#include <wrl.h>
10#include <xaudio2.h>
11
12#include <list>
13
14// https://github.com/microsoft/DirectXTK/blob/main/Audio/AudioEngine.cpp
15
16namespace of {
18 public:
19 virtual void OnSourceReaderEvent(HRESULT hrStatus, DWORD dwStreamIndex,
20 DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample* pSample) = 0;
21 };
22}
23
25public:
26 static bool InitMediaFoundation();
27 static bool CloseMediaFoundation();
28 static int GetNumInstances();
29
30 class AsyncCallback : public IMFAsyncCallback {
31 public:
32 AsyncCallback(std::function<void()> aCallBack) {
33 mCallBack = aCallBack;
34 }
35 virtual ~AsyncCallback() = default;
36
37 IFACEMETHODIMP GetParameters(_Out_ DWORD* flags, _Out_ DWORD* queue) {
38 *flags = 0;// MFASYNC_BLOCKING_CALLBACK;
39 *queue = MFASYNC_CALLBACK_QUEUE_MULTITHREADED;
40 return S_OK;
41 }
42
43 STDMETHODIMP Invoke(IMFAsyncResult* pResult) {
44 mCallBack();
45 return S_OK;
46 }
47
48 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObj) {
49 if (!ppvObj) return E_INVALIDARG;
50 *ppvObj = NULL;
51 if (riid == IID_IMFAsyncCallback) {
52 *ppvObj = (LPVOID)this;
53 AddRef();
54 return NOERROR;
55 }
56 return E_NOINTERFACE;
57 }
58
59 ULONG STDMETHODCALLTYPE AddRef() {
60 InterlockedIncrement(&m_refCount);
61 return m_refCount;
62 }
63
64 ULONG STDMETHODCALLTYPE Release() {
65 ULONG count = InterlockedDecrement(&m_refCount);
66 if (0 == m_refCount) {
67 delete this;
68 }
69 return count;
70 }
71
72 protected:
73 std::function<void()> mCallBack;
74 ULONG m_refCount = 0;
75 };
76
77 //----------------------------------------------
78 static void CallAsyncBlocking(std::function<void()> aCallBack);
79
80protected:
81 static int sNumMFInstances;
82};
83
85public:
86
87 static void SetMasterVolume(float apct);
88
91
92 bool load(const of::filesystem::path& fileName, bool stream = false) override;
93 void unload() override;
94
95 void play() override;
96 void stop() override;
97
98 void setVolume(float vol) override;
99 void setPan(float apan) override; // -1 = left, 1 = right
100 void setSpeed(float spd) override;
101 void setPaused(bool bP) override;
102 void setLoop(bool bLp) override;
103 void setMultiPlay(bool bMp) override;
104 void setPosition(float pct) override; // 0 = start, 1 = end;
105 void setPositionMS(int ms) override;
106
107 float getPosition() const override;
108 int getPositionMS() const override;
109 bool isPlaying() const override;
110 float getSpeed() const override;
111 float getPan() const override;
112 bool isLoaded() const override;
113 float getVolume() const override;
114
116 uint32_t getDurationMS() { return mDurationMS; }
117
118protected:
119
120 void OnSourceReaderEvent(HRESULT hrStatus, DWORD dwStreamIndex,
121 DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample* pSample) override;
122
123 bool mBAddedUpdateEvent = false;
124 void update(ofEventArgs& args);
125 void addUpdateListener();
127
129 template <typename T>
130 void operator()(T* p) {
131 if (p) {
132 p->Release();
133 }
134 }
135 };
136
138 void operator()(IXAudio2SourceVoice* p) {
139 if (p) {
140 std::ignore = p->Stop(0);
141 std::ignore = p->FlushSourceBuffers();
142 p->DestroyVoice();
143 }
144 }
145 };
146
147
148 using UniqueVoice = std::unique_ptr< IXAudio2SourceVoice, MyVoiceDeleterFunctor >;
149
150 void _clearExtraVoices();
151 void _setPan(IXAudio2SourceVoice* avoice, float apan);
152 bool _readToBuffer(IMFSourceReader* areader);
153
154 static int sNumInstances;
155
156 static bool sInitXAudio2();
157 static bool sCloseXAudio2();
158
159 static bool sInitAudioSystems();
160 static void sCloseAudioSystems();
161
162 bool mBStreaming = false;
163 unsigned short mNumChannels = 0;
164 unsigned long mSampleRate = 44000;
165 std::vector<BYTE> mBuffer;
166 WAVEFORMATEX mWaveFormatEx;
167
168 Microsoft::WRL::ComPtr<IMFSourceReader> mSrcReader;
169 static Microsoft::WRL::ComPtr< IXAudio2> sXAudio2;
170 static std::shared_ptr<IXAudio2MasteringVoice> sXAudioMasteringVoice;
171
173 //std::vector< std::shared_ptr<IXAudio2SourceVoice> > mExtraVoices;
174 std::list< std::pair<unsigned int, IXAudio2SourceVoice*> > mExtraVoices;
175
176 bool mBLoaded = false;
177 bool mBIsPlaying = false;
178 float mVolume = 1.0f;
179 float mPan = 0.0f;
180 float mSpeed = 1.0f;
181 float mPosPct = 0.0f;
182 bool mBMultiPlay = false;
183 bool mBLoop = false;
184
185 bool mBCanSeek = false;
187 uint32_t mDurationMS = 0;
188
189 // 2 = INT_16, 3 = INT_24 and 4 = FLOAT_32
190 // TODO: Adjust this based on file loaded
191 unsigned char mBytesPerSample = 2;
192 uint64_t mTotalNumFrames = 0;
193 size_t mBufferIndex = 0;
195 uint64_t mNumSamplesStored = 0;
196
197 unsigned int MAX_BUFFER_COUNT = 3;
198 std::vector< std::vector<BYTE> > mStreamBuffers;
200
201
202 // https://github.com/walbourn/directx-sdk-samples/blob/main/XAudio2/XAudio2MFStream/XAudio2MFStream.cpp
203 struct StreamingVoiceContext : public IXAudio2VoiceCallback {
204 STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32) override {}
205 STDMETHOD_(void, OnVoiceProcessingPassEnd)() override {}
206 STDMETHOD_(void, OnStreamEnd)() override {}
207 STDMETHOD_(void, OnBufferStart)(void*) override {}
208 STDMETHOD_(void, OnBufferEnd)(void*) override {
209 SetEvent(hBufferEndEvent);
210 }
211 STDMETHOD_(void, OnLoopEnd)(void*) override {}
212 STDMETHOD_(void, OnVoiceError)(void*, HRESULT) override {}
213 HANDLE hBufferEndEvent;
215#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
216 hBufferEndEvent(CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE))
217#else
218 hBufferEndEvent(CreateEvent(nullptr, FALSE, FALSE, nullptr))
219#endif
220 {}
222 CloseHandle(hBufferEndEvent);
223 }
224 };
225
226
227 std::shared_ptr<StreamingVoiceContext> mVoiceContext;
228 bool mBEndOfStream = false;
229
230 CRITICAL_SECTION m_critSec;
231
232 class SourceReaderCallback : public IMFSourceReaderCallback {
233 public:
234 STDMETHOD(QueryInterface) (REFIID iid, _COM_Outptr_ void** ppv) override {
235 if (!ppv)
236 return E_POINTER;
237
238 if (__uuidof(IMFSourceReaderCallback) == iid) {
239 *ppv = this;
240 return S_OK;
241 }
242 *ppv = nullptr;
243 return E_NOINTERFACE;
244 }
245
246 // we are managing this, do don't worry about these
247 STDMETHOD_(ULONG, AddRef)() override {return 0;}
248 STDMETHOD_(ULONG, Release)() override {return 0;}
249
250 STDMETHOD(OnReadSample)(_In_ HRESULT hrStatus, _In_ DWORD dwStreamIndex, _In_ DWORD dwStreamFlags, _In_ LONGLONG llTimestamp, _In_opt_ IMFSample* pSample) override {
251 UNREFERENCED_PARAMETER(dwStreamIndex);
252 if (mCB) {
253 mCB->OnSourceReaderEvent(hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, pSample);
254 }
255 status = hrStatus;
256 return S_OK;
257 }
258
259 STDMETHOD(OnFlush)(_In_ DWORD) override {return S_OK;}
260 STDMETHOD(OnEvent)(_In_ DWORD, _In_ IMFMediaEvent*) override {return S_OK;}
261
263 mCB = acb;
264 }
265 HRESULT status;
269
270 };
271
272
273 std::shared_ptr<SourceReaderCallback> mSrcReaderCallback;
274 std::mutex mSrcReaderMutex;
276};
Definition ofSoundBaseTypes.h:161
Definition ofEvents.h:119
Definition ofMediaFoundationSoundPlayer.h:232
STDMETHOD_(ULONG, Release)() override
Definition ofMediaFoundationSoundPlayer.h:248
STDMETHOD() OnFlush(_In_ DWORD) override
Definition ofMediaFoundationSoundPlayer.h:259
virtual ~SourceReaderCallback()
Definition ofMediaFoundationSoundPlayer.h:268
SourceReaderCallback()
Definition ofMediaFoundationSoundPlayer.h:267
STDMETHOD() QueryInterface(REFIID iid, _COM_Outptr_ void **ppv) override
Definition ofMediaFoundationSoundPlayer.h:234
of::MFSourceReaderNotifyCallback * mCB
Definition ofMediaFoundationSoundPlayer.h:266
STDMETHOD_(ULONG, AddRef)() override
Definition ofMediaFoundationSoundPlayer.h:247
void setCB(of::MFSourceReaderNotifyCallback *acb)
Definition ofMediaFoundationSoundPlayer.h:262
HRESULT status
Definition ofMediaFoundationSoundPlayer.h:265
STDMETHOD() OnReadSample(_In_ HRESULT hrStatus, _In_ DWORD dwStreamIndex, _In_ DWORD dwStreamFlags, _In_ LONGLONG llTimestamp, _In_opt_ IMFSample *pSample) override
Definition ofMediaFoundationSoundPlayer.h:250
STDMETHOD() OnEvent(_In_ DWORD, _In_ IMFMediaEvent *) override
Definition ofMediaFoundationSoundPlayer.h:260
Definition ofMediaFoundationSoundPlayer.h:84
std::vector< BYTE > mBuffer
Definition ofMediaFoundationSoundPlayer.h:165
Microsoft::WRL::ComPtr< IMFSourceReader > mSrcReader
Definition ofMediaFoundationSoundPlayer.h:168
float getPan() const override
Definition ofMediaFoundationSoundPlayer.cpp:808
bool mBIsPlaying
Definition ofMediaFoundationSoundPlayer.h:177
bool mBCanSeek
Definition ofMediaFoundationSoundPlayer.h:185
bool _readToBuffer(IMFSourceReader *areader)
Definition ofMediaFoundationSoundPlayer.cpp:1003
void setSpeed(float spd) override
Definition ofMediaFoundationSoundPlayer.cpp:679
bool mBRequestNewReaderSample
Definition ofMediaFoundationSoundPlayer.h:275
void OnSourceReaderEvent(HRESULT hrStatus, DWORD dwStreamIndex, DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample) override
Definition ofMediaFoundationSoundPlayer.cpp:823
bool mBLoaded
Definition ofMediaFoundationSoundPlayer.h:176
size_t mBufferIndex
Definition ofMediaFoundationSoundPlayer.h:193
bool mBEndOfStream
Definition ofMediaFoundationSoundPlayer.h:228
std::shared_ptr< StreamingVoiceContext > mVoiceContext
Definition ofMediaFoundationSoundPlayer.h:227
uint32_t getDurationMS()
Definition ofMediaFoundationSoundPlayer.h:116
bool load(const of::filesystem::path &fileName, bool stream=false) override
Definition ofMediaFoundationSoundPlayer.cpp:189
void _clearExtraVoices()
Definition ofMediaFoundationSoundPlayer.cpp:933
uint64_t mTotalNumFrames
Definition ofMediaFoundationSoundPlayer.h:192
unsigned int MAX_BUFFER_COUNT
Definition ofMediaFoundationSoundPlayer.h:197
float mVolume
Definition ofMediaFoundationSoundPlayer.h:178
void play() override
Definition ofMediaFoundationSoundPlayer.cpp:527
unsigned short mNumChannels
Definition ofMediaFoundationSoundPlayer.h:163
void unload() override
Definition ofMediaFoundationSoundPlayer.cpp:382
std::mutex mSrcReaderMutex
Definition ofMediaFoundationSoundPlayer.h:274
void setPan(float apan) override
Definition ofMediaFoundationSoundPlayer.cpp:662
float getPosition() const override
Definition ofMediaFoundationSoundPlayer.cpp:788
void setVolume(float vol) override
Definition ofMediaFoundationSoundPlayer.cpp:648
bool mBAddedUpdateEvent
Definition ofMediaFoundationSoundPlayer.h:123
bool mBStreaming
Definition ofMediaFoundationSoundPlayer.h:162
static void sCloseAudioSystems()
Definition ofMediaFoundationSoundPlayer.cpp:166
ofMediaFoundationSoundPlayer()
Definition ofMediaFoundationSoundPlayer.cpp:178
CRITICAL_SECTION m_critSec
Definition ofMediaFoundationSoundPlayer.h:230
int currentStreamBuffer
Definition ofMediaFoundationSoundPlayer.h:199
void setPositionMS(int ms) override
Definition ofMediaFoundationSoundPlayer.cpp:783
static bool sInitXAudio2()
Definition ofMediaFoundationSoundPlayer.cpp:111
float getSpeed() const override
Definition ofMediaFoundationSoundPlayer.cpp:803
UniqueVoice mVoice
Definition ofMediaFoundationSoundPlayer.h:172
static Microsoft::WRL::ComPtr< IXAudio2 > sXAudio2
Definition ofMediaFoundationSoundPlayer.h:169
~ofMediaFoundationSoundPlayer()
Definition ofMediaFoundationSoundPlayer.cpp:182
int getPositionMS() const override
Definition ofMediaFoundationSoundPlayer.cpp:793
std::vector< std::vector< BYTE > > mStreamBuffers
Definition ofMediaFoundationSoundPlayer.h:198
float mPosPct
Definition ofMediaFoundationSoundPlayer.h:181
double mDurationSeconds
Definition ofMediaFoundationSoundPlayer.h:186
uint32_t mDurationMS
Definition ofMediaFoundationSoundPlayer.h:187
void _setPan(IXAudio2SourceVoice *avoice, float apan)
Definition ofMediaFoundationSoundPlayer.cpp:945
unsigned long mSampleRate
Definition ofMediaFoundationSoundPlayer.h:164
std::list< std::pair< unsigned int, IXAudio2SourceVoice * > > mExtraVoices
Definition ofMediaFoundationSoundPlayer.h:174
WAVEFORMATEX mWaveFormatEx
Definition ofMediaFoundationSoundPlayer.h:166
static bool sCloseXAudio2()
Definition ofMediaFoundationSoundPlayer.cpp:137
static bool sInitAudioSystems()
Definition ofMediaFoundationSoundPlayer.cpp:156
static std::shared_ptr< IXAudio2MasteringVoice > sXAudioMasteringVoice
Definition ofMediaFoundationSoundPlayer.h:170
void setLoop(bool bLp) override
Definition ofMediaFoundationSoundPlayer.cpp:712
float getDurationSeconds()
Definition ofMediaFoundationSoundPlayer.h:115
void setMultiPlay(bool bMp) override
Definition ofMediaFoundationSoundPlayer.cpp:721
float mSpeed
Definition ofMediaFoundationSoundPlayer.h:180
static int sNumInstances
Definition ofMediaFoundationSoundPlayer.h:154
float getVolume() const override
Definition ofMediaFoundationSoundPlayer.cpp:818
void setPosition(float pct) override
Definition ofMediaFoundationSoundPlayer.cpp:734
void addUpdateListener()
Definition ofMediaFoundationSoundPlayer.cpp:917
void setPaused(bool bP) override
Definition ofMediaFoundationSoundPlayer.cpp:687
bool isLoaded() const override
Definition ofMediaFoundationSoundPlayer.cpp:813
void update(ofEventArgs &args)
Definition ofMediaFoundationSoundPlayer.cpp:438
bool mBMultiPlay
Definition ofMediaFoundationSoundPlayer.h:182
uint64_t mNumSamplesAlreadyPlayed
Definition ofMediaFoundationSoundPlayer.h:194
uint64_t mNumSamplesStored
Definition ofMediaFoundationSoundPlayer.h:195
void removeUpdateListener()
Definition ofMediaFoundationSoundPlayer.cpp:925
unsigned char mBytesPerSample
Definition ofMediaFoundationSoundPlayer.h:191
std::unique_ptr< IXAudio2SourceVoice, MyVoiceDeleterFunctor > UniqueVoice
Definition ofMediaFoundationSoundPlayer.h:148
std::shared_ptr< SourceReaderCallback > mSrcReaderCallback
Definition ofMediaFoundationSoundPlayer.h:273
bool mBLoop
Definition ofMediaFoundationSoundPlayer.h:183
bool isPlaying() const override
Definition ofMediaFoundationSoundPlayer.cpp:798
void stop() override
Definition ofMediaFoundationSoundPlayer.cpp:624
static void SetMasterVolume(float apct)
Definition ofMediaFoundationSoundPlayer.cpp:102
float mPan
Definition ofMediaFoundationSoundPlayer.h:179
Definition ofMediaFoundationSoundPlayer.h:30
ULONG m_refCount
Definition ofMediaFoundationSoundPlayer.h:74
ULONG STDMETHODCALLTYPE AddRef()
Definition ofMediaFoundationSoundPlayer.h:59
IFACEMETHODIMP GetParameters(_Out_ DWORD *flags, _Out_ DWORD *queue)
Definition ofMediaFoundationSoundPlayer.h:37
ULONG STDMETHODCALLTYPE Release()
Definition ofMediaFoundationSoundPlayer.h:64
std::function< void()> mCallBack
Definition ofMediaFoundationSoundPlayer.h:73
AsyncCallback(std::function< void()> aCallBack)
Definition ofMediaFoundationSoundPlayer.h:32
STDMETHODIMP Invoke(IMFAsyncResult *pResult)
Definition ofMediaFoundationSoundPlayer.h:43
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
Definition ofMediaFoundationSoundPlayer.h:48
Definition ofMediaFoundationSoundPlayer.h:24
static int sNumMFInstances
Definition ofMediaFoundationSoundPlayer.h:81
static bool CloseMediaFoundation()
Definition ofMediaFoundationSoundPlayer.cpp:51
static int GetNumInstances()
Definition ofMediaFoundationSoundPlayer.cpp:67
static bool InitMediaFoundation()
Definition ofMediaFoundationSoundPlayer.cpp:35
static void CallAsyncBlocking(std::function< void()> aCallBack)
Definition ofMediaFoundationSoundPlayer.cpp:72
Definition ofEvents.cpp:625
ISampleGrabberCB IMediaSample * pSample
Definition ofDirectShowPlayer.cpp:38
Definition ofMediaFoundationSoundPlayer.h:17
virtual void OnSourceReaderEvent(HRESULT hrStatus, DWORD dwStreamIndex, DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample)=0
Definition ofMediaFoundationSoundPlayer.h:128
void operator()(T *p)
Definition ofMediaFoundationSoundPlayer.h:130
Definition ofMediaFoundationSoundPlayer.h:137
void operator()(IXAudio2SourceVoice *p)
Definition ofMediaFoundationSoundPlayer.h:138
Definition ofMediaFoundationSoundPlayer.h:203
STDMETHOD_(void, OnLoopEnd)(void *) override
Definition ofMediaFoundationSoundPlayer.h:211
STDMETHOD_(void, OnStreamEnd)() override
Definition ofMediaFoundationSoundPlayer.h:206
StreamingVoiceContext()
Definition ofMediaFoundationSoundPlayer.h:214
STDMETHOD_(void, OnBufferEnd)(void *) override
Definition ofMediaFoundationSoundPlayer.h:208
STDMETHOD_(void, OnBufferStart)(void *) override
Definition ofMediaFoundationSoundPlayer.h:207
virtual ~StreamingVoiceContext()
Definition ofMediaFoundationSoundPlayer.h:221
STDMETHOD_(void, OnVoiceProcessingPassEnd)() override
Definition ofMediaFoundationSoundPlayer.h:205
STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32) override
Definition ofMediaFoundationSoundPlayer.h:204