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