@@ -301,11 +301,62 @@ bool GenericAudio::PlayOnChannel(SeChannel& chan, std::unique_ptr<AudioSeCache>
301301 chan.paused = false ; // Unpause channel -> Play it.
302302 return true ;
303303}
304-
305304void GenericAudio::Decode (uint8_t * output_buffer, int buffer_length) {
305+ auto [channel_active, total_volume, samples_per_frame] = GenericAudio::Decode (buffer_length);
306+ if (channel_active) {
307+ if (total_volume > 1.0 ) {
308+ float threshold = 0.8 ;
309+ for (unsigned i = 0 ; i < (unsigned )(samples_per_frame * 2 ); i++) {
310+ float sample = mixer_buffer[i];
311+ float sign = (sample < 0 ) ? -1.0 : 1.0 ;
312+ sample /= sign;
313+ // dynamic range compression
314+ if (sample > threshold) {
315+ sample_buffer[i] = sign * 32768.0 * (threshold + (1.0 - threshold) * (sample - threshold) / (total_volume - threshold));
316+ } else {
317+ sample_buffer[i] = sign * sample * 32768.0 ;
318+ }
319+ }
320+ } else {
321+ // No dynamic range compression necessary
322+ for (unsigned i = 0 ; i < (unsigned )(samples_per_frame * 2 ); i++) {
323+ sample_buffer[i] = mixer_buffer[i] * 32768.0 ;
324+ }
325+ }
326+
327+ memcpy (output_buffer, sample_buffer.data (), buffer_length);
328+ } else {
329+ memset (output_buffer, ' \0 ' , buffer_length);
330+ }
331+ }
332+
333+ void GenericAudio::Decode (float * output_buffer, int buffer_length) {
334+ auto [channel_active, total_volume, samples_per_frame] = GenericAudio::Decode (buffer_length);
335+ if (channel_active) {
336+ if (total_volume > 1.0 ) {
337+ float threshold = 0.8 ;
338+ for (unsigned i = 0 ; i < (unsigned )(samples_per_frame * 2 ); ++i) {
339+ float sample = mixer_buffer[i];
340+ float sign = (sample < 0 ) ? -1.0 : 1.0 ;
341+ sample /= sign;
342+ if (sample > threshold) {
343+ output_buffer[i] = sign * (threshold + (1.0 - threshold) * (sample - threshold) / (total_volume - threshold));
344+ } else {
345+ output_buffer[i] = sign * sample;
346+ }
347+ }
348+ } else {
349+ memcpy (output_buffer, mixer_buffer.data (), buffer_length);
350+ }
351+ } else {
352+ memset (output_buffer, ' \0 ' , buffer_length);
353+ }
354+ }
355+
356+ GenericAudio::DecodeResult GenericAudio::Decode (int buffer_length) {
306357 bool channel_active = false ;
307358 float total_volume = 0 ;
308- int samples_per_frame = buffer_length / output_format.channels / 2 ;
359+ int samples_per_frame = buffer_length / output_format.channels / AudioDecoder::GetSamplesizeForFormat (output_format. format ) ;
309360
310361 assert (buffer_length > 0 );
311362
@@ -471,32 +522,7 @@ void GenericAudio::Decode(uint8_t* output_buffer, int buffer_length) {
471522 channel_active = true ;
472523 }
473524 }
474-
475- if (channel_active) {
476- if (total_volume > 1.0 ) {
477- float threshold = 0 .8f ;
478- for (unsigned i = 0 ; i < (unsigned )(samples_per_frame * 2 ); i++) {
479- float sample = mixer_buffer[i];
480- float sign = (sample < 0 ) ? -1.0 : 1.0 ;
481- sample /= sign;
482- // dynamic range compression
483- if (sample > threshold) {
484- sample_buffer[i] = sign * 32768.0 * (threshold + (1.0 - threshold) * (sample - threshold) / (total_volume - threshold));
485- } else {
486- sample_buffer[i] = sign * sample * 32768.0 ;
487- }
488- }
489- } else {
490- // No dynamic range compression necessary
491- for (unsigned i = 0 ; i < (unsigned )(samples_per_frame * 2 ); i++) {
492- sample_buffer[i] = mixer_buffer[i] * 32768.0 ;
493- }
494- }
495-
496- memcpy (output_buffer, sample_buffer.data (), buffer_length);
497- } else {
498- memset (output_buffer, ' \0 ' , buffer_length);
499- }
525+ return {channel_active, total_volume, samples_per_frame};
500526}
501527
502528void GenericAudio::BgmChannel::Stop () {
@@ -505,9 +531,9 @@ void GenericAudio::BgmChannel::Stop() {
505531 midi_out_used = false ;
506532 instance->midi_thread ->GetMidiOut ().Reset ();
507533 instance->midi_thread ->GetMidiOut ().Pause ();
508- } else if (decoder) {
509- decoder.reset ();
510534 }
535+ // Don't reset the decoder here, another thread could be using it right now
536+ // it will be reset on the next call to Decode
511537}
512538
513539void GenericAudio::BgmChannel::SetPaused (bool newPaused) {
0 commit comments