Skip to content

Commit f1b81b2

Browse files
committed
Fix issues with AudioStreamPolyphonic
1 parent 084d5d4 commit f1b81b2

File tree

2 files changed

+163
-70
lines changed

2 files changed

+163
-70
lines changed

scene/resources/audio_stream_polyphonic.cpp

Lines changed: 139 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ constexpr uint64_t INDEX_SHIFT = 32;
3939
Ref<AudioStreamPlayback> AudioStreamPolyphonic::instantiate_playback() {
4040
Ref<AudioStreamPlaybackPolyphonic> playback;
4141
playback.instantiate();
42-
playback->streams.resize(polyphony);
42+
playback->resize_streams(polyphony);
43+
playbacks.push_back(playback);
4344
return playback;
4445
}
4546

@@ -53,7 +54,14 @@ bool AudioStreamPolyphonic::is_monophonic() const {
5354

5455
void AudioStreamPolyphonic::set_polyphony(int p_voices) {
5556
ERR_FAIL_COND(p_voices < 0 || p_voices > 128);
57+
if (polyphony == p_voices) {
58+
return;
59+
}
5660
polyphony = p_voices;
61+
62+
for (Ref<AudioStreamPlaybackPolyphonic> playback : playbacks) {
63+
playback->resize_streams(polyphony);
64+
}
5765
}
5866
int AudioStreamPolyphonic::get_polyphony() const {
5967
return polyphony;
@@ -66,11 +74,64 @@ void AudioStreamPolyphonic::_bind_methods() {
6674
ADD_PROPERTY(PropertyInfo(Variant::INT, "polyphony", PROPERTY_HINT_RANGE, "1,128,1"), "set_polyphony", "get_polyphony");
6775
}
6876

69-
AudioStreamPolyphonic::AudioStreamPolyphonic() {
77+
AudioStreamPolyphonic::AudioStreamPolyphonic() {}
78+
AudioStreamPolyphonic::~AudioStreamPolyphonic() {
79+
playbacks.clear();
7080
}
7181

7282
////////////////////////
7383

84+
void AudioStreamPlaybackPolyphonic::resize_streams(int p_voices) {
85+
ERR_FAIL_COND(p_voices < 0 || p_voices > 128);
86+
int32_t streams_size = (int32_t)streams.size();
87+
if (p_voices == streams_size) {
88+
return;
89+
}
90+
91+
MutexLock lock(streams_mutex);
92+
93+
if (p_voices == 0) {
94+
for (int i = streams_size - 1; i >= 0; i--) {
95+
memdelete(streams[i]);
96+
}
97+
streams.resize(0);
98+
return;
99+
}
100+
101+
if (p_voices > streams_size) {
102+
streams.resize(p_voices);
103+
for (int i = streams_size; i < p_voices; i++) {
104+
streams[i] = memnew(Stream);
105+
}
106+
return;
107+
}
108+
109+
LocalVector<Stream *> active_streams;
110+
for (Stream *stream : streams) {
111+
if (!stream->active.is_set()) {
112+
memdelete(stream);
113+
continue;
114+
}
115+
active_streams.push_back(stream);
116+
}
117+
streams.resize(p_voices);
118+
119+
int active_streams_size = (int32_t)active_streams.size();
120+
for (int i = 0; i < p_voices; i++) {
121+
if (i < active_streams_size) {
122+
streams[i] = active_streams[i];
123+
continue;
124+
}
125+
streams[i] = memnew(Stream);
126+
}
127+
if (active_streams_size > p_voices) {
128+
for (int i = p_voices; i < active_streams_size; i++) {
129+
memdelete(active_streams[i]);
130+
}
131+
}
132+
active_streams.clear();
133+
}
134+
74135
void AudioStreamPlaybackPolyphonic::start(double p_from_pos) {
75136
if (active) {
76137
stop();
@@ -84,17 +145,15 @@ void AudioStreamPlaybackPolyphonic::stop() {
84145
return;
85146
}
86147

148+
MutexLock lock(streams_mutex);
87149
bool locked = false;
88-
for (Stream &s : streams) {
89-
if (s.active.is_set()) {
150+
for (Stream *s : streams) {
151+
if (s->active.is_set()) {
90152
// Need locking because something may still be mixing.
91153
locked = true;
92154
AudioServer::get_singleton()->lock();
93155
}
94-
s.active.clear();
95-
s.finish_request.clear();
96-
s.stream_playback.unref();
97-
s.stream.unref();
156+
s->clear();
98157
}
99158
if (locked) {
100159
AudioServer::get_singleton()->unlock();
@@ -119,9 +178,10 @@ void AudioStreamPlaybackPolyphonic::seek(double p_time) {
119178
}
120179

121180
void AudioStreamPlaybackPolyphonic::tag_used_streams() {
122-
for (Stream &s : streams) {
123-
if (s.active.is_set()) {
124-
s.stream_playback->tag_used_streams();
181+
MutexLock lock(streams_mutex);
182+
for (Stream *s : streams) {
183+
if (s->active.is_set()) {
184+
s->stream_playback->tag_used_streams();
125185
}
126186
}
127187
}
@@ -136,37 +196,38 @@ int AudioStreamPlaybackPolyphonic::mix(AudioFrame *p_buffer, float p_rate_scale,
136196
p_buffer[i] = AudioFrame(0, 0);
137197
}
138198

139-
for (Stream &s : streams) {
140-
if (!s.active.is_set()) {
199+
MutexLock lock(streams_mutex);
200+
for (Stream *s : streams) {
201+
if (!s->active.is_set()) {
141202
continue;
142203
}
143204

144-
if (s.stream_playback->get_is_sample()) {
145-
if (s.finish_request.is_set()) {
146-
s.active.clear();
147-
AudioServer::get_singleton()->stop_sample_playback(s.stream_playback->get_sample_playback());
205+
if (s->stream_playback->get_is_sample()) {
206+
if (s->finish_request.is_set()) {
207+
s->active.clear();
208+
AudioServer::get_singleton()->stop_sample_playback(s->stream_playback->get_sample_playback());
148209
}
149210
continue;
150211
}
151212

152-
float volume_db = s.volume_db; // Copy because it can be overridden at any time.
213+
float volume_db = s->volume_db; // Copy because it can be overridden at any time.
153214
float next_volume = Math::db_to_linear(volume_db);
154-
s.prev_volume_db = volume_db;
215+
s->prev_volume_db = volume_db;
155216

156-
if (s.finish_request.is_set()) {
157-
if (s.pending_play.is_set()) {
217+
if (s->finish_request.is_set()) {
218+
if (s->pending_play.is_set()) {
158219
// Did not get the chance to play, was finalized too soon.
159-
s.active.clear();
220+
s->active.clear();
160221
continue;
161222
}
162223
next_volume = 0;
163224
}
164225

165-
if (s.pending_play.is_set()) {
166-
s.stream_playback->start(s.play_offset);
167-
s.pending_play.clear();
226+
if (s->pending_play.is_set()) {
227+
s->stream_playback->start(s->play_offset);
228+
s->pending_play.clear();
168229
}
169-
float prev_volume = Math::db_to_linear(s.prev_volume_db);
230+
float prev_volume = Math::db_to_linear(s->prev_volume_db);
170231

171232
float volume_inc = (next_volume - prev_volume) / float(p_frames);
172233

@@ -178,7 +239,7 @@ int AudioStreamPlaybackPolyphonic::mix(AudioFrame *p_buffer, float p_rate_scale,
178239

179240
while (todo) {
180241
int to_mix = MIN(todo, int(INTERNAL_BUFFER_LEN));
181-
int mixed = s.stream_playback->mix(internal_buffer, s.pitch_scale, to_mix);
242+
int mixed = s->stream_playback->mix(internal_buffer, s->pitch_scale, to_mix);
182243

183244
for (int i = 0; i < to_mix; i++) {
184245
p_buffer[offset + i] += internal_buffer[i] * volume;
@@ -187,7 +248,7 @@ int AudioStreamPlaybackPolyphonic::mix(AudioFrame *p_buffer, float p_rate_scale,
187248

188249
if (mixed < to_mix) {
189250
// Stream is done.
190-
s.active.clear();
251+
s->active.clear();
191252
stream_done = true;
192253
break;
193254
}
@@ -200,8 +261,8 @@ int AudioStreamPlaybackPolyphonic::mix(AudioFrame *p_buffer, float p_rate_scale,
200261
continue;
201262
}
202263

203-
if (s.finish_request.is_set()) {
204-
s.active.clear();
264+
if (s->finish_request.is_set()) {
265+
s->active.clear();
205266
}
206267
}
207268

@@ -215,88 +276,92 @@ AudioStreamPlaybackPolyphonic::ID AudioStreamPlaybackPolyphonic::play_stream(con
215276
? AudioServer::get_singleton()->get_default_playback_type()
216277
: p_playback_type;
217278

279+
MutexLock lock(streams_mutex);
218280
for (uint32_t i = 0; i < streams.size(); i++) {
219-
if (streams[i].active.is_set() && streams[i].stream_playback->get_is_sample()) {
220-
Ref<AudioSamplePlayback> active_sample_playback = streams[i].stream_playback->get_sample_playback();
281+
if (streams[i]->active.is_set() && streams[i]->stream_playback->get_is_sample()) {
282+
Ref<AudioSamplePlayback> active_sample_playback = streams[i]->stream_playback->get_sample_playback();
221283
if (active_sample_playback.is_null() || !AudioServer::get_singleton()->is_sample_playback_active(active_sample_playback)) {
222-
streams[i].active.clear();
284+
streams[i]->active.clear();
223285
}
224286
}
225287

226-
if (!streams[i].active.is_set()) {
288+
if (!streams[i]->active.is_set()) {
227289
// Can use this stream, as it's not active.
228-
streams[i].stream = p_stream;
229-
streams[i].stream_playback = streams[i].stream->instantiate_playback();
230-
streams[i].play_offset = p_from_offset;
231-
streams[i].volume_db = p_volume_db;
232-
streams[i].prev_volume_db = p_volume_db;
233-
streams[i].pitch_scale = p_pitch_scale;
234-
streams[i].id = id_counter++;
235-
streams[i].finish_request.clear();
236-
streams[i].pending_play.set();
237-
streams[i].active.set();
290+
streams[i]->stream = p_stream;
291+
streams[i]->stream_playback = streams[i]->stream->instantiate_playback();
292+
streams[i]->play_offset = p_from_offset;
293+
streams[i]->volume_db = p_volume_db;
294+
streams[i]->prev_volume_db = p_volume_db;
295+
streams[i]->pitch_scale = p_pitch_scale;
296+
streams[i]->id = id_counter++;
297+
streams[i]->finish_request.clear();
298+
streams[i]->pending_play.set();
299+
streams[i]->active.set();
238300

239301
// Sample playback.
240302
if (playback_type == AudioServer::PlaybackType::PLAYBACK_TYPE_SAMPLE && p_stream->can_be_sampled()) {
241-
streams[i].stream_playback->set_is_sample(true);
303+
streams[i]->stream_playback->set_is_sample(true);
242304
if (!AudioServer::get_singleton()->is_stream_registered_as_sample(p_stream)) {
243305
AudioServer::get_singleton()->register_stream_as_sample(p_stream);
244306
}
245307
float linear_volume = Math::db_to_linear(p_volume_db);
246-
Ref<AudioSamplePlayback> sp;
247-
sp.instantiate();
248-
sp->stream = streams[i].stream;
249-
sp->offset = p_from_offset;
250-
sp->volume_vector.resize(4);
251-
sp->volume_vector.write[0] = AudioFrame(linear_volume, linear_volume);
252-
sp->volume_vector.write[1] = AudioFrame(linear_volume, /* LFE= */ 1.0f);
253-
sp->volume_vector.write[2] = AudioFrame(linear_volume, linear_volume);
254-
sp->volume_vector.write[3] = AudioFrame(linear_volume, linear_volume);
255-
sp->bus = p_bus;
256-
257-
if (streams[i].stream_playback->get_sample_playback().is_valid()) {
258-
AudioServer::get_singleton()->stop_playback_stream(sp);
308+
Ref<AudioSamplePlayback> audio_sample_playback;
309+
audio_sample_playback.instantiate();
310+
audio_sample_playback->stream = streams[i]->stream;
311+
audio_sample_playback->offset = p_from_offset;
312+
audio_sample_playback->pitch_scale = p_pitch_scale;
313+
audio_sample_playback->volume_vector.resize(4);
314+
audio_sample_playback->volume_vector.write[0] = AudioFrame(linear_volume, linear_volume);
315+
audio_sample_playback->volume_vector.write[1] = AudioFrame(linear_volume, /* LFE= */ 1.0f);
316+
audio_sample_playback->volume_vector.write[2] = AudioFrame(linear_volume, linear_volume);
317+
audio_sample_playback->volume_vector.write[3] = AudioFrame(linear_volume, linear_volume);
318+
audio_sample_playback->bus = p_bus;
319+
320+
if (streams[i]->stream_playback->get_sample_playback().is_valid()) {
321+
AudioServer::get_singleton()->stop_playback_stream(streams[i]->stream_playback);
259322
}
260323

261-
streams[i].stream_playback->set_sample_playback(sp);
262-
AudioServer::get_singleton()->start_sample_playback(sp);
324+
streams[i]->stream_playback->set_sample_playback(audio_sample_playback);
325+
AudioServer::get_singleton()->start_sample_playback(audio_sample_playback);
263326
}
264327

265-
return (ID(i) << INDEX_SHIFT) | ID(streams[i].id);
328+
return (ID(i) << INDEX_SHIFT) | ID(streams[i]->id);
266329
}
267330
}
268331

269332
return INVALID_ID;
270333
}
271334

272335
AudioStreamPlaybackPolyphonic::Stream *AudioStreamPlaybackPolyphonic::_find_stream(int64_t p_id) {
336+
MutexLock lock(streams_mutex);
273337
uint32_t index = static_cast<uint64_t>(p_id) >> INDEX_SHIFT;
274338
if (index >= streams.size()) {
275339
return nullptr;
276340
}
277-
if (!streams[index].active.is_set()) {
341+
if (!streams[index]->active.is_set()) {
278342
return nullptr; // Not active, no longer exists.
279343
}
280344
int64_t id = static_cast<uint64_t>(p_id) & ID_MASK;
281-
if (streams[index].id != id) {
345+
if (streams[index]->id != id) {
282346
return nullptr;
283347
}
284-
return &streams[index];
348+
return streams[index];
285349
}
286350

287351
const AudioStreamPlaybackPolyphonic::Stream *AudioStreamPlaybackPolyphonic::_find_stream(int64_t p_id) const {
352+
MutexLock lock(streams_mutex);
288353
uint32_t index = static_cast<uint64_t>(p_id) >> INDEX_SHIFT;
289354
if (index >= streams.size()) {
290355
return nullptr;
291356
}
292-
if (!streams[index].active.is_set()) {
357+
if (!streams[index]->active.is_set()) {
293358
return nullptr; // Not active, no longer exists.
294359
}
295360
int64_t id = static_cast<uint64_t>(p_id) & ID_MASK;
296-
if (streams[index].id != id) {
361+
if (streams[index]->id != id) {
297362
return nullptr;
298363
}
299-
return &streams[index];
364+
return streams[index];
300365
}
301366

302367
void AudioStreamPlaybackPolyphonic::set_stream_volume(ID p_stream_id, float p_volume_db) {
@@ -356,5 +421,11 @@ void AudioStreamPlaybackPolyphonic::_bind_methods() {
356421
BIND_CONSTANT(INVALID_ID);
357422
}
358423

359-
AudioStreamPlaybackPolyphonic::AudioStreamPlaybackPolyphonic() {
424+
AudioStreamPlaybackPolyphonic::AudioStreamPlaybackPolyphonic() {}
425+
426+
AudioStreamPlaybackPolyphonic::~AudioStreamPlaybackPolyphonic() {
427+
for (Stream *stream : streams) {
428+
memdelete(stream);
429+
}
430+
streams.clear();
360431
}

0 commit comments

Comments
 (0)