-
Notifications
You must be signed in to change notification settings - Fork 0
/
MPI_Audio.cpp
126 lines (98 loc) · 3.11 KB
/
MPI_Audio.cpp
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// MPI_Audio.cpp
//
#include "MPI_Audio.h"
void MPI_Audio::start( void )
{
// fire it up
// we can't do this in the constructor because we need to be sure the
// MPI_Application constructor returns before we can start calling
// MPI_Application::getInstance(). the audio callback could fire and try
// to call this before we're out of the MPI_Application constructor.
try {
audio_->setStreamCallback(&MPI_AudioCallback::callback, NULL);
audio_->startStream();
}
catch (RtError &error) {
error.printMessage();
}
}
void MPI_Audio::addSynth( MPI_AudioSynth *synth )
{
// append the synth to the synth list
synthList_.push_back( synth );
}
void MPI_Audio::removeSynth( MPI_AudioSynth *synth )
{
// remove the synth from the list
// find the synth in the list
std::list<MPI_AudioSynth*>::iterator cursyn;
cursyn = find( synthList_.begin(), synthList_.end(), synth );
// assert that we were able to find the synth
assert( cursyn != synthList_.end() );
// remove it
synthList_.erase( cursyn );
}
void MPI_Audio::tickBuffer( double *buffer, int bufferSize ) const
{
// Tick an entire buffer's worth of samples and write out to the given
// buffer. Vectorized code -- cheapest loop on the inside
int i = 0;
double *curbufpos = NULL;
// zero out the buffer
// the buffer contains stereo interleaved samples, so clear out both the
// left and right samples.
curbufpos = buffer;
for ( i = 0; i < bufferSize; i++ ) {
*curbufpos++ = 0.0;
*curbufpos++ = 0.0;
}
// for each synth, add in its contribution
// the buffer contains stereo interleaved samples, so write to both the
// left and the right channels
std::list<MPI_AudioSynth*>::const_iterator synth;
double tickvalue = 0.0;
for ( synth = synthList_.begin(); synth != synthList_.end(); ++synth ) {
if ( (*synth)->isActive() ) {
curbufpos = buffer;
for ( i = 0; i < bufferSize; i++ ) {
tickvalue = (*synth)->tick();
*curbufpos++ += tickvalue;
*curbufpos++ += tickvalue;
}
}
}
}
MPI_Audio::MPI_Audio()
{
audio_ = NULL;
int channels = 2;
int sampleRate = 44100;
int bufferSize = 256; // 256 sample frames
int nBuffers = 4; // number of internal buffers used by device
int device = 0; // 0 indicates the default or first available device
// allocate an RtAudio instance
try {
audio_ = new RtAudio(device, channels, 0, 0, RTAUDIO_FLOAT64,
sampleRate, &bufferSize, nBuffers);
}
catch (RtError &error) {
error.printMessage();
}
}
MPI_Audio::~MPI_Audio()
{
try {
// Stop and close the stream
audio_->stopStream();
audio_->closeStream();
}
catch (RtError &error) {
error.printMessage();
}
delete audio_;
// make sure the synth list is empty -- these should all have been
// deallocated before destroying the MPI_Audio object.
assert( synthList_.empty() );
}
// vim:sw=4:et:cindent: