diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 342fc5bf6d..fce71efbe4 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -181,7 +181,11 @@ void I_ShutdownMusic(bool onexit) assert (currSong == NULL); } Timidity::FreeAll(); - if (onexit) WildMidi_Shutdown(); + if (onexit) + { + WildMidi_Shutdown(); + TimidityPP_Shutdown(); + } } void I_ShutdownMusicExit() diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 4c796ead59..95ce0e876a 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -92,6 +92,7 @@ MIDIDevice *CreateWinMIDIDevice(int mididevice); MIDIDevice *CreateAudioToolboxMIDIDevice(); #endif MIDIDevice *CreateTimidityPPMIDIDevice(const char *args); +void TimidityPP_Shutdown(); // Base class for pseudo-MIDI devices --------------------------------------- diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index bd9fd31756..ba9444a357 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -45,6 +45,7 @@ #include "tmpfileplus.h" #include "m_misc.h" #include "v_text.h" +#include "i_system.h" #include "timiditypp/timidity.h" #include "timiditypp/instrum.h" @@ -64,6 +65,11 @@ public: int GetDeviceType() const override { return MDEV_TIMIDITY; } bool Preprocess(MIDIStreamer *song, bool looping); void TimidityVolumeChanged(); + static void ClearInstruments() + { + if (instruments != nullptr) delete instruments; + instruments = nullptr; + } protected: TimidityPlus::Player *Renderer; @@ -132,13 +138,10 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args) TimidityPPMIDIDevice::~TimidityPPMIDIDevice () { Close(); - /* if (Renderer != nullptr) { delete Renderer; } - */ - } //========================================================================== @@ -176,7 +179,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata) int ret = OpenStream(2, 0, callback, userdata); if (ret == 0) { - //Renderer->Reset(); + //Renderer->playmidi_stream_init(); } return ret; } @@ -192,13 +195,9 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata) // //========================================================================== -void TimidityPPMIDIDevice::PrecacheInstruments(const uint16_t *instruments, int count) +void TimidityPPMIDIDevice::PrecacheInstruments(const uint16_t *instrumentlist, int count) { - for (int i = 0; i < count; ++i) - { - //Renderer->MarkInstrument((instruments[i] >> 7) & 127, instruments[i] >> 14, instruments[i] & 127); - } - //Renderer->load_missing_instruments(); + instruments->PrecacheInstruments(instrumentlist, count); } //========================================================================== @@ -231,10 +230,9 @@ void TimidityPPMIDIDevice::HandleLongEvent(const uint8_t *data, int len) void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len) { - TimidityPlus::run_midi(len / 8); // bytes to samples + Renderer->run_midi(len); memset(buffer, len, 0); // to do - - //Renderer->ComputeOutput(buffer, len); + Renderer->get_output(buffer, len); } //========================================================================== @@ -257,6 +255,11 @@ MIDIDevice *CreateTimidityPPMIDIDevice(const char *args) return new TimidityPPMIDIDevice(args); } +void TimidityPP_Shutdown() +{ + TimidityPPMIDIDevice::ClearInstruments(); +} + void TimidityPlus::ctl_cmsg(int type, int verbosity_level, const char *fmt, ...) { diff --git a/src/sound/timiditypp/effect.cpp b/src/sound/timiditypp/effect.cpp index 6eb8f2260a..c76d99c7e4 100644 --- a/src/sound/timiditypp/effect.cpp +++ b/src/sound/timiditypp/effect.cpp @@ -73,10 +73,10 @@ void Effect::effect_left_right_delay(int32_t *buff, int32_t count) return; if (backoff > count) backoff = count; - if (count < audio_buffer_size * 2) + if (count < AUDIO_BUFFER_SIZE * 2) { - memset(buff + count, 0, 4 * (audio_buffer_size * 2 - count)); - count = audio_buffer_size * 2; + memset(buff + count, 0, 4 * (AUDIO_BUFFER_SIZE * 2 - count)); + count = AUDIO_BUFFER_SIZE * 2; } memcpy(save, buff, 4 * count); pi = count - backoff; diff --git a/src/sound/timiditypp/output.h b/src/sound/timiditypp/output.h index edbbf9b02a..804f8745fc 100644 --- a/src/sound/timiditypp/output.h +++ b/src/sound/timiditypp/output.h @@ -76,8 +76,6 @@ struct PlayMode { }; extern PlayMode *play_mode_list[], *play_mode; -extern int audio_buffer_bits; -#define audio_buffer_size (1<init_effect_status(play_system_mode); + effect = new Effect(reverb); + mixer = new Mixer(this); recache = new Recache(this); - aq = new AudioQueue(play_mode, audio_buffer_size, reverb); + aq = new AudioQueue(play_mode, AUDIO_BUFFER_SIZE, reverb); aq->setup(); for (int i = 0; i < MAX_CHANNELS; i++) @@ -191,6 +194,7 @@ Player::~Player() delete aq; delete mixer; delete recache; + delete effect; delete reverb; } @@ -5017,101 +5021,23 @@ void Player::do_compute_data(int32_t count) current_sample += count; } -int Player::check_midi_play_end(MidiEvent *e, int len) +int Player::send_output(int32_t *samples, int32_t count) { - int i, type; - - for(i = 0; i < len; i++) - { - type = e[i].type; - if(type == ME_NOTEON || type == ME_LAST || type == ME_WRD || type == ME_SHERRY) - return 0; - if(type == ME_EOT) - return i + 1; - } - return 0; -} - -int Player::midi_play_end(void) -{ - int i, rc = RC_TUNE_END; - - check_eot_flag = 0; - - if(opt_realtime_playing && current_sample == 0) - { - reset_voices(); - return RC_TUNE_END; - } - - if(upper_voices > 0) - { - int fadeout_cnt; - - rc = compute_data(playback_rate); - if(RC_IS_SKIP_FILE(rc)) - goto midi_end; - - for(i = 0; i < upper_voices; i++) - if(voice[i].status & (VOICE_ON | VOICE_SUSTAINED)) - finish_note(i); - if(opt_realtime_playing) - fadeout_cnt = 3; - else - fadeout_cnt = 6; - for(i = 0; i < fadeout_cnt && upper_voices > 0; i++) + aq->add(samples, count); + /* + effect->do_effect(samples, count); + // pass to caller + for (int i = 0; i < count && output_len > 0; i++) { - rc = compute_data(playback_rate / 2); - if(RC_IS_SKIP_FILE(rc)) - goto midi_end; + *output_buffer++ = (*samples++)*(1.f / 0x80000000u); + *output_buffer++ = (*samples++)*(1.f / 0x80000000u); + output_len--; } - - /* kill voices */ - kill_all_voices(); - rc = compute_data(MAX_DIE_TIME); - if(RC_IS_SKIP_FILE(rc)) - goto midi_end; - upper_voices = 0; - } - - /* clear reverb echo sound */ - reverb->init_reverb(); - for(i = 0; i < MAX_CHANNELS; i++) - { - channel[i].reverb_level = -1; - channel[i].reverb_id = -1; - make_rvid_flag = 1; - } - - /* output null sound */ - if(opt_realtime_playing) - rc = compute_data((int32_t)(playback_rate * PLAY_INTERLEAVE_SEC/2)); - else - rc = compute_data((int32_t)(playback_rate * PLAY_INTERLEAVE_SEC)); - if(RC_IS_SKIP_FILE(rc)) - goto midi_end; - - compute_data(0); /* flush buffer to device */ - - rc = aq->softFlush(); - - midi_end: - if(RC_IS_SKIP_FILE(rc)) - aq->flush(1); - - ctl_cmsg(CMSG_INFO, VERB_VERBOSE, "Playing time: ~%d seconds", - current_sample/playback_rate+2); - ctl_cmsg(CMSG_INFO, VERB_VERBOSE, "Notes cut: %d", - cut_notes); - ctl_cmsg(CMSG_INFO, VERB_VERBOSE, "Notes lost totally: %d", - lost_notes); - if(RC_IS_SKIP_FILE(rc)) - return rc; - return RC_TUNE_END; + */ + memset(output_buffer, 0, output_len * 8); + return RC_OK; } -/* count=0 means flush remaining buffered data to output device, then - flush the device itself */ int Player::compute_data(int32_t count) { if (!count) @@ -5126,29 +5052,19 @@ int Player::compute_data(int32_t count) return RC_OK; } - while ((count + buffered_count) >= audio_buffer_size) + while ((count + buffered_count) >= AUDIO_BUFFER_SIZE) { int i; - do_compute_data(audio_buffer_size - buffered_count); - count -= audio_buffer_size - buffered_count; + do_compute_data(AUDIO_BUFFER_SIZE - buffered_count); + count -= AUDIO_BUFFER_SIZE - buffered_count; - if (aq->add(common_buffer, audio_buffer_size) == -1) + if (aq->add(common_buffer, AUDIO_BUFFER_SIZE) == -1) return RC_ERROR; buffer_pointer = common_buffer; buffered_count = 0; - /* check break signals */ - - if (upper_voices == 0 && check_eot_flag && - (i = check_midi_play_end(current_event, EOT_PRESEARCH_LEN)) > 0) - { - if (i > 1) - ctl_cmsg(CMSG_INFO, VERB_VERBOSE, - "Last %d MIDI events are ignored", i - 1); - return midi_play_end(); - } } if (count > 0) { @@ -5755,7 +5671,7 @@ int Player::play_event(MidiEvent *ev) break; case ME_EOT: - return midi_play_end(); + break; } #ifndef SUPPRESS_CHANNEL_LAYER } @@ -6101,8 +6017,7 @@ Instrument *Player::play_midi_load_instrument(int dr, int bk, int prog) bool load_success; // The inner workings of this function which alters the instrument data has been put into the Instruments class. auto instr = instruments->play_midi_load_instrument(dr, bk, prog, &load_success); - if (load_success) - aq->add(NULL, 0); /* Update software buffer */ + //if (load_success) send_output(NULL, 0); /* Update software buffer */ return instr; } @@ -6150,4 +6065,11 @@ void Player::init_channel_layer(int ch) channel[ch].port_select = ch >> 4; } +void Player::get_output(float *buffer, int len) +{ + output_buffer = buffer; + output_len = len; + //compute_data(len); +} + } \ No newline at end of file diff --git a/src/sound/timiditypp/playmidi.h b/src/sound/timiditypp/playmidi.h index 1ab0c65fbc..2e93216672 100644 --- a/src/sound/timiditypp/playmidi.h +++ b/src/sound/timiditypp/playmidi.h @@ -511,6 +511,7 @@ struct midi_file_info class Recache; class Mixer; class Reverb; +class Effect; class AudioQueue; class Player @@ -532,6 +533,7 @@ private: Recache *recache; Mixer *mixer; Reverb *reverb; + Effect *effect; AudioQueue *aq; @@ -559,6 +561,8 @@ private: int current_freq_table; int current_temper_freq_table; int master_tuning; + float *output_buffer; + int output_len; int make_rvid_flag; /* For reverb optimization */ @@ -666,6 +670,7 @@ private: void update_legato_controls(int ch); void set_master_tuning(int tune); struct midi_file_info *new_midi_file_info(); + int send_output(int32_t *samples, int32_t count); void adjust_amplification(void); @@ -734,6 +739,7 @@ public: void recompute_freq(int v); int get_default_mapID(int ch); void init_channel_layer(int ch); + void get_output(float *buffer, int len); // Only until streaming works. void skip_to(int32_t until_time, MidiEvent *evt_start); diff --git a/src/sound/timiditypp/readmidi.cpp b/src/sound/timiditypp/readmidi.cpp index d59484bc95..4d9afa80ac 100644 --- a/src/sound/timiditypp/readmidi.cpp +++ b/src/sound/timiditypp/readmidi.cpp @@ -1566,11 +1566,6 @@ void Player::run_midi(int samples) } } -void run_midi(int msec) -{ - gplayer->run_midi(msec); -} - void timidity_close() {