From 8f7a5035616cc31ce1344407a2bf08732b17c9a1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 24 Feb 2018 19:36:09 +0100 Subject: [PATCH] - don't let the Timidity++ player directly access the CVARs. This may cause problems because the player runs in a different thread than the input code. Instead the play thread will now copy their values to local variables when it starts generating output. --- .../music_timiditypp_mididevice.cpp | 18 ++++++++++ src/sound/timiditypp/effect.cpp | 16 ++++----- src/sound/timiditypp/effect.h | 5 ++- src/sound/timiditypp/playmidi.cpp | 34 ++++++++++++------- src/sound/timiditypp/playmidi.h | 18 ++++++++++ src/sound/timiditypp/reverb.h | 5 ++- src/sound/timiditypp/timidity.h | 10 ++---- 7 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index a87c185be..5730c81dc 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -102,6 +102,24 @@ CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) self = 65000; } +// These two need a music restart. +CUSTOM_CVAR(Bool, timidity_surround_chorus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_TIMIDITY) + { + MIDIDeviceChanged(-1, true); + } +} + +CUSTOM_CVAR(Bool, timidity_modulation_envelope, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (currSong != nullptr && currSong->GetDeviceType() == MDEV_TIMIDITY) + { + MIDIDeviceChanged(-1, true); + } +} + + //========================================================================== // // TimidityPPMIDIDevice Constructor diff --git a/src/sound/timiditypp/effect.cpp b/src/sound/timiditypp/effect.cpp index 6b2084e9c..b079b4779 100644 --- a/src/sound/timiditypp/effect.cpp +++ b/src/sound/timiditypp/effect.cpp @@ -183,27 +183,27 @@ void Effect::effect_left_right_delay(int32_t *buff, int32_t count) void Effect::do_effect(int32_t *buf, int32_t count) { int32_t nsamples = count * 2; - int reverb_level = (timidity_reverb < 0) - ? -timidity_reverb & 0x7f : DEFAULT_REVERB_SEND_LEVEL; + int reverb_level = (reverb->timidity_reverb < 0) + ? -reverb->timidity_reverb & 0x7f : DEFAULT_REVERB_SEND_LEVEL; /* for static reverb / chorus level */ - if (timidity_reverb == 2 || timidity_reverb == 4 - || (timidity_reverb < 0 && !(timidity_reverb & 0x80)) + if (reverb->timidity_reverb == 2 || reverb->timidity_reverb == 4 + || (reverb->timidity_reverb < 0 && !(reverb->timidity_reverb & 0x80)) || timidity_chorus < 0) { reverb->set_dry_signal(buf, nsamples); /* chorus sounds horrible * if applied globally on top of channel chorus */ - if (timidity_reverb == 2 || timidity_reverb == 4 - || (timidity_reverb < 0 && !(timidity_reverb & 0x80))) + if (reverb->timidity_reverb == 2 || reverb->timidity_reverb == 4 + || (reverb->timidity_reverb < 0 && !(reverb->timidity_reverb & 0x80))) reverb->set_ch_reverb(buf, nsamples, reverb_level); reverb->mix_dry_signal(buf, nsamples); /* chorus sounds horrible * if applied globally on top of channel chorus */ - if (timidity_reverb == 2 || timidity_reverb == 4 - || (timidity_reverb < 0 && !(timidity_reverb & 0x80))) + if (reverb->timidity_reverb == 2 || reverb->timidity_reverb == 4 + || (reverb->timidity_reverb < 0 && !(reverb->timidity_reverb & 0x80))) reverb->do_ch_reverb(buf, nsamples); } /* L/R Delay */ diff --git a/src/sound/timiditypp/effect.h b/src/sound/timiditypp/effect.h index b447fd9c5..f9141ede0 100644 --- a/src/sound/timiditypp/effect.h +++ b/src/sound/timiditypp/effect.h @@ -26,9 +26,12 @@ class Effect Reverb *reverb; public: - Effect(Reverb *_reverb) + int timidity_chorus; + + Effect(Reverb *_reverb, int chorus) { reverb = _reverb; + timidity_chorus = chorus; init_effect(); } diff --git a/src/sound/timiditypp/playmidi.cpp b/src/sound/timiditypp/playmidi.cpp index de2e22b96..59e4c94d3 100644 --- a/src/sound/timiditypp/playmidi.cpp +++ b/src/sound/timiditypp/playmidi.cpp @@ -51,17 +51,11 @@ CVAR(Bool, timidity_portamento, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) * reverb=4 "global" new reverb 4 * reverb=4,n set reverb level to n (-1 to -127) - 384 */ -static bool mustinitreverb; -CUSTOM_CVAR(Int, timidity_reverb, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - mustinitreverb = true; // this needs to reallocate some buffers -} +CVAR(Int, timidity_reverb, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, timidity_chorus, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, timidity_surround_chorus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, timidity_channel_pressure, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, timidity_lpf_def, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, timidity_temper_control, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, timidity_modulation_envelope, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, timidity_overlap_voice_allow, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, timidity_drum_effect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, timidity_pan_delay, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -119,7 +113,6 @@ Player::Player(int freq, Instruments *instr) const int CONTROLS_PER_SECOND = 1000; const int MAX_CONTROL_RATIO = 255; - mustinitreverb = false; memset(this, 0, sizeof(*this)); playback_rate = freq; @@ -137,9 +130,9 @@ Player::Player(int freq, Instruments *instr) new_midi_file_info(); init_mblock(&playmidi_pool); - reverb = new Reverb; + reverb = new Reverb(timidity_reverb); reverb->init_effect_status(play_system_mode); - effect = new Effect(reverb); + effect = new Effect(reverb, timidity_chorus); mixer = new Mixer(this); @@ -5021,12 +5014,29 @@ void Player::do_compute_data(int32_t count) int Player::compute_data(float *buffer, int32_t count) { if (count == 0) return RC_OK; - if (mustinitreverb) + + timidity_modulation_wheel = ::timidity_modulation_wheel; + timidity_portamento = ::timidity_portamento; + timidity_chorus = ::timidity_chorus; + timidity_channel_pressure = ::timidity_chorus; + timidity_lpf_def = ::timidity_lpf_def; + timidity_temper_control = ::timidity_temper_control; + timidity_overlap_voice_allow = ::timidity_overlap_voice_allow; + timidity_drum_effect = ::timidity_drum_effect; + timidity_pan_delay = ::timidity_pan_delay; + timidity_drum_power = ::timidity_drum_power; + timidity_key_adjust = ::timidity_key_adjust; + timidity_tempo_adjust = ::timidity_tempo_adjust; + effect->timidity_chorus = timidity_chorus; + + if (::timidity_reverb != timidity_reverb) { + timidity_reverb = ::timidity_reverb; + reverb->timidity_reverb = timidity_reverb; + // If the reverb mode has changed some buffers need to be reallocated before doing any sound generation. reverb->free_effect_buffers(); reverb->init_reverb(); - mustinitreverb = false; } buffer_pointer = common_buffer; diff --git a/src/sound/timiditypp/playmidi.h b/src/sound/timiditypp/playmidi.h index 6bf675fc9..39d16384b 100644 --- a/src/sound/timiditypp/playmidi.h +++ b/src/sound/timiditypp/playmidi.h @@ -512,6 +512,24 @@ class Effect; class Player { public: + + bool timidity_modulation_wheel = true; + bool timidity_portamento = true; + int timidity_reverb = 0; + int timidity_chorus = 0; + bool timidity_surround_chorus = false; + bool timidity_channel_pressure = false; + bool timidity_temper_control = true; + bool timidity_modulation_envelope = true; + bool timidity_overlap_voice_allow = true; + bool timidity_drum_effect = false; + bool timidity_pan_delay = false; + int timidity_lpf_def = true; + float timidity_drum_power = 1.0; + int timidity_key_adjust = 0; + float timidity_tempo_adjust = 1; + + Channel channel[MAX_CHANNELS]; Voice voice[max_voices]; ChannelBitMask default_drumchannel_mask; diff --git a/src/sound/timiditypp/reverb.h b/src/sound/timiditypp/reverb.h index 2cb230ba3..fa61971dc 100644 --- a/src/sound/timiditypp/reverb.h +++ b/src/sound/timiditypp/reverb.h @@ -692,13 +692,16 @@ class Reverb void do_xg_auto_wah_od(int32_t *buf, int32_t count, EffectList *ef); public: - Reverb() + int timidity_reverb; + + Reverb(int reverb) { // Make sure that this starts out with all zeros. memset(this, 0, sizeof(*this)); REV_INP_LEV = 1.0; direct_bufsize = sizeof(direct_buffer); reverb_effect_bufsize = sizeof(reverb_effect_buffer); + timidity_reverb = reverb; } diff --git a/src/sound/timiditypp/timidity.h b/src/sound/timiditypp/timidity.h index 272c35818..0a0aa2afc 100644 --- a/src/sound/timiditypp/timidity.h +++ b/src/sound/timiditypp/timidity.h @@ -28,6 +28,7 @@ #ifndef TIMIDITY_H_INCLUDED #define TIMIDITY_H_INCLUDED 1 +#include #include "c_cvars.h" #include "controls.h" #include "mblock.h" @@ -36,18 +37,11 @@ #pragma warning(disable:4244) // double->float truncation occurs so often in here that it's pointless to fix it all. #endif - -EXTERN_CVAR(Bool, timidity_modulation_wheel) -EXTERN_CVAR(Bool, timidity_portamento) -EXTERN_CVAR(Int, timidity_reverb) -EXTERN_CVAR(Int, timidity_chorus) EXTERN_CVAR(Bool, timidity_surround_chorus) -EXTERN_CVAR(Bool, timidity_channel_pressure) -EXTERN_CVAR(Int, timidity_lpf_def) -EXTERN_CVAR(Bool, timidity_temper_control) EXTERN_CVAR(Bool, timidity_modulation_envelope) + /* Table of contents: (1) Flags and definitions to customize timidity