@@ -39,7 +39,8 @@ constexpr uint64_t INDEX_SHIFT = 32;
3939Ref<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
5455void 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}
5866int 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+
74135void 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
121180void 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
272335AudioStreamPlaybackPolyphonic::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
287351const 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
302367void 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