MemFunCallbackStream.hxx (3315B)
1 #ifndef INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX 2 #define INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX 3 4 // --------------------------------------------------------------------------------------- 5 6 #include "portaudio.h" 7 8 #include "portaudiocpp/CallbackStream.hxx" 9 #include "portaudiocpp/CallbackInterface.hxx" 10 #include "portaudiocpp/StreamParameters.hxx" 11 #include "portaudiocpp/Exception.hxx" 12 #include "portaudiocpp/InterfaceCallbackStream.hxx" 13 14 // --------------------------------------------------------------------------------------- 15 16 namespace portaudio 17 { 18 19 20 ////// 21 /// @brief Callback stream using a class's member function as a callback. Template argument T is the type of the 22 /// class of which a member function is going to be used. 23 /// 24 /// Example usage: 25 /// @verbatim MemFunCallback<MyClass> stream = MemFunCallbackStream(parameters, *this, &MyClass::myCallbackFunction); @endverbatim 26 ////// 27 template<typename T> 28 class MemFunCallbackStream : public CallbackStream 29 { 30 public: 31 typedef int (T::*CallbackFunPtr)(const void *, void *, unsigned long, const PaStreamCallbackTimeInfo *, 32 PaStreamCallbackFlags); 33 34 // ------------------------------------------------------------------------------- 35 36 MemFunCallbackStream() 37 { 38 } 39 40 MemFunCallbackStream(const StreamParameters ¶meters, T &instance, CallbackFunPtr memFun) : adapter_(instance, memFun) 41 { 42 open(parameters); 43 } 44 45 ~MemFunCallbackStream() 46 { 47 close(); 48 } 49 50 void open(const StreamParameters ¶meters, T &instance, CallbackFunPtr memFun) 51 { 52 // XXX: need to check if already open? 53 54 adapter_.init(instance, memFun); 55 open(parameters); 56 } 57 58 private: 59 MemFunCallbackStream(const MemFunCallbackStream &); // non-copyable 60 MemFunCallbackStream &operator=(const MemFunCallbackStream &); // non-copyable 61 62 ////// 63 /// @brief Inner class which adapts a member function callback to a CallbackInterface compliant 64 /// class (so it can be adapted using the paCallbackAdapter function). 65 ////// 66 class MemFunToCallbackInterfaceAdapter : public CallbackInterface 67 { 68 public: 69 MemFunToCallbackInterfaceAdapter() {} 70 MemFunToCallbackInterfaceAdapter(T &instance, CallbackFunPtr memFun) : instance_(&instance), memFun_(memFun) {} 71 72 void init(T &instance, CallbackFunPtr memFun) 73 { 74 instance_ = &instance; 75 memFun_ = memFun; 76 } 77 78 int paCallbackFun(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, 79 const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags) 80 { 81 return (instance_->*memFun_)(inputBuffer, outputBuffer, numFrames, timeInfo, statusFlags); 82 } 83 84 private: 85 T *instance_; 86 CallbackFunPtr memFun_; 87 }; 88 89 MemFunToCallbackInterfaceAdapter adapter_; 90 91 void open(const StreamParameters ¶meters) 92 { 93 PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), 94 parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), &impl::callbackInterfaceToPaCallbackAdapter, 95 static_cast<void *>(&adapter_)); 96 97 if (err != paNoError) 98 throw PaException(err); 99 } 100 }; 101 102 103 } // portaudio 104 105 // --------------------------------------------------------------------------------------- 106 107 #endif // INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX