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