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