Chris@55: #ifndef INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX Chris@55: #define INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX Chris@55: Chris@55: // --------------------------------------------------------------------------------------- Chris@55: Chris@55: #include "portaudio.h" Chris@55: Chris@55: #include "portaudiocpp/CallbackStream.hxx" Chris@55: #include "portaudiocpp/CallbackInterface.hxx" Chris@55: #include "portaudiocpp/StreamParameters.hxx" Chris@55: #include "portaudiocpp/Exception.hxx" Chris@55: #include "portaudiocpp/InterfaceCallbackStream.hxx" Chris@55: Chris@55: // --------------------------------------------------------------------------------------- Chris@55: Chris@55: namespace portaudio Chris@55: { Chris@55: Chris@55: Chris@55: ////// Chris@55: /// @brief Callback stream using a class's member function as a callback. Template argument T is the type of the Chris@55: /// class of which a member function is going to be used. Chris@55: /// Chris@55: /// Example usage: Chris@55: /// @verbatim MemFunCallback stream = MemFunCallbackStream(parameters, *this, &MyClass::myCallbackFunction); @endverbatim Chris@55: ////// Chris@55: template Chris@55: class MemFunCallbackStream : public CallbackStream Chris@55: { Chris@55: public: Chris@55: typedef int (T::*CallbackFunPtr)(const void *, void *, unsigned long, const PaStreamCallbackTimeInfo *, Chris@55: PaStreamCallbackFlags); Chris@55: Chris@55: // ------------------------------------------------------------------------------- Chris@55: Chris@55: MemFunCallbackStream() Chris@55: { Chris@55: } Chris@55: Chris@55: MemFunCallbackStream(const StreamParameters ¶meters, T &instance, CallbackFunPtr memFun) : adapter_(instance, memFun) Chris@55: { Chris@55: open(parameters); Chris@55: } Chris@55: Chris@55: ~MemFunCallbackStream() Chris@55: { Chris@55: close(); Chris@55: } Chris@55: Chris@55: void open(const StreamParameters ¶meters, T &instance, CallbackFunPtr memFun) Chris@55: { Chris@55: // XXX: need to check if already open? Chris@55: Chris@55: adapter_.init(instance, memFun); Chris@55: open(parameters); Chris@55: } Chris@55: Chris@55: private: Chris@55: MemFunCallbackStream(const MemFunCallbackStream &); // non-copyable Chris@55: MemFunCallbackStream &operator=(const MemFunCallbackStream &); // non-copyable Chris@55: Chris@55: ////// Chris@55: /// @brief Inner class which adapts a member function callback to a CallbackInterface compliant Chris@55: /// class (so it can be adapted using the paCallbackAdapter function). Chris@55: ////// Chris@55: class MemFunToCallbackInterfaceAdapter : public CallbackInterface Chris@55: { Chris@55: public: Chris@55: MemFunToCallbackInterfaceAdapter() {} Chris@55: MemFunToCallbackInterfaceAdapter(T &instance, CallbackFunPtr memFun) : instance_(&instance), memFun_(memFun) {} Chris@55: Chris@55: void init(T &instance, CallbackFunPtr memFun) Chris@55: { Chris@55: instance_ = &instance; Chris@55: memFun_ = memFun; Chris@55: } Chris@55: Chris@55: int paCallbackFun(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, Chris@55: const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags) Chris@55: { Chris@55: return (instance_->*memFun_)(inputBuffer, outputBuffer, numFrames, timeInfo, statusFlags); Chris@55: } Chris@55: Chris@55: private: Chris@55: T *instance_; Chris@55: CallbackFunPtr memFun_; Chris@55: }; Chris@55: Chris@55: MemFunToCallbackInterfaceAdapter adapter_; Chris@55: Chris@55: void open(const StreamParameters ¶meters) Chris@55: { Chris@55: PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), Chris@55: parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), &impl::callbackInterfaceToPaCallbackAdapter, Chris@55: static_cast(&adapter_)); Chris@55: Chris@55: if (err != paNoError) Chris@55: throw PaException(err); Chris@55: } Chris@55: }; Chris@55: Chris@55: Chris@55: } // portaudio Chris@55: Chris@55: // --------------------------------------------------------------------------------------- Chris@55: Chris@55: #endif // INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX