21
21
constexpr int32_t AUDIO_SAMPLE_RATE = 44100 ;
22
22
constexpr float PI2 = 2 .0f * M_PI;
23
23
constexpr int SILENCE_BEFORE_STOP = kMillisPerSecond * 5 ;
24
- constexpr int MAX_RAMP = 450 ;
24
+ constexpr int MAX_RAMP = 250 ;
25
+ constexpr int MAX_QUEUE_SIZE = 250 ;
25
26
constexpr int RAMP_SCALE = 10 ;
26
27
int instances = 0 ;
27
28
28
29
struct Sound {
29
- Sound (int blockSize, bool fadeIn, int frequency, int millis, int volume);
30
+ Sound (bool fadeIn, int frequency, int millis, int volume);
30
31
~Sound ();
31
32
32
33
bool ready () const ;
33
34
float sample ();
34
- void sync (Sound *previous, bool lastSound, int blockSize );
35
+ void sync (Sound *previous, bool lastSound);
35
36
36
37
private:
37
38
uint32_t _duration;
@@ -45,7 +46,7 @@ struct Sound {
45
46
float _phase;
46
47
};
47
48
48
- Sound::Sound (int blockSize, bool fadeIn, int frequency, int millis, int volume) :
49
+ Sound::Sound (bool fadeIn, int frequency, int millis, int volume) :
49
50
_duration(millis),
50
51
_samples(AUDIO_SAMPLE_RATE * millis / 1000 ),
51
52
_sampled(0 ),
@@ -61,10 +62,6 @@ Sound::Sound(int blockSize, bool fadeIn, int frequency, int millis, int volume)
61
62
_fadeIn = std::min ((int )_samples / RAMP_SCALE, MAX_RAMP);
62
63
} else if (frequency == 0 ) {
63
64
_rest = std::min ((int )_samples / RAMP_SCALE, MAX_RAMP);
64
- // align sample size with burst-size
65
- if (_rest != 0 && _samples > blockSize) {
66
- _samples = (_samples / blockSize) * blockSize;
67
- }
68
65
}
69
66
}
70
67
@@ -104,23 +101,21 @@ float Sound::sample() {
104
101
// fadeOut to silence
105
102
result *= (float )(_samples - _sampled) / (float )_fadeOut;
106
103
}
104
+
107
105
return result;
108
106
}
109
107
110
108
//
111
109
// Continues the same phase for the previous sound
112
110
//
113
- void Sound::sync (Sound *previous, bool lastSound, int blockSize ) {
111
+ void Sound::sync (Sound *previous, bool lastSound) {
114
112
_phase = previous->_phase ;
115
113
if (_rest != 0 ) {
116
114
// for fadeOut/In for adjoining silence
117
115
_increment = previous->_increment ;
118
116
}
119
117
if (lastSound) {
120
118
// fade out non-silent sound to silence
121
- if (_samples > blockSize) {
122
- _samples = (_samples / blockSize) * blockSize;
123
- }
124
119
_fadeOut = _samples / RAMP_SCALE;
125
120
if (_fadeOut > MAX_RAMP) {
126
121
_fadeOut = MAX_RAMP;
@@ -163,7 +158,7 @@ Audio::~Audio() {
163
158
// Play a sound with the given specification
164
159
//
165
160
void Audio::play (int frequency, int millis, int volume, bool background) {
166
- if (_stream != nullptr && millis > 0 ) {
161
+ if (_stream != nullptr && millis > 0 && _queue. size () < MAX_QUEUE_SIZE ) {
167
162
add (frequency, millis, volume);
168
163
if (_stream->getState () != StreamState::Started) {
169
164
trace (" Start audio" );
@@ -192,22 +187,25 @@ void Audio::clearSoundQueue() {
192
187
// Callback to play the next block of audio
193
188
//
194
189
DataCallbackResult Audio::onAudioReady (AudioStream *oboeStream, void *audioData, int32_t numFrames) {
195
- DataCallbackResult result = DataCallbackResult::Continue;
196
190
Sound *sound = front ();
197
191
auto *buffer = (float *)audioData;
198
- if (sound == nullptr ) {
199
- for ( int i = 0 ; i < numFrames; ++i ) {
192
+ for ( int i = 0 ; i < numFrames; ++i ) {
193
+ if (sound == nullptr ) {
200
194
buffer[i] = 0 ;
201
- }
202
- // continue filling with silence in case the script requests further sounds
203
- if (_startNoSound != 0 && maGetMilliSecondCount () - _startNoSound > SILENCE_BEFORE_STOP) {
204
- result = DataCallbackResult::Stop;
205
- }
206
- } else {
207
- for (int i = 0 ; i < numFrames; ++i) {
195
+ } else {
208
196
buffer[i] = sound->sample ();
197
+ if (!sound->ready ()) {
198
+ sound = front ();
199
+ }
209
200
}
210
201
}
202
+
203
+ DataCallbackResult result;
204
+ if (sound == nullptr && _startNoSound != 0 && maGetMilliSecondCount () - _startNoSound > SILENCE_BEFORE_STOP) {
205
+ result = DataCallbackResult::Stop;
206
+ } else {
207
+ result = DataCallbackResult::Continue;
208
+ }
211
209
return result;
212
210
}
213
211
@@ -216,7 +214,7 @@ DataCallbackResult Audio::onAudioReady(AudioStream *oboeStream, void *audioData,
216
214
//
217
215
void Audio::add (int frequency, int millis, int volume) {
218
216
std::lock_guard<std::mutex> lock (_lock);
219
- _queue.push (new Sound (_stream-> getFramesPerBurst (), _queue.empty (), frequency, millis, volume));
217
+ _queue.push (new Sound (_queue.empty (), frequency, millis, volume));
220
218
_startNoSound = 0 ;
221
219
}
222
220
@@ -236,7 +234,7 @@ Sound *Audio::front() {
236
234
_queue.pop ();
237
235
auto *next = _queue.front ();
238
236
if (next != nullptr ) {
239
- next->sync (result, _queue.size () == 1 , _stream-> getFramesPerBurst () );
237
+ next->sync (result, _queue.size () == 1 );
240
238
}
241
239
result = nullptr ;
242
240
}
0 commit comments