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