- safety commit.

This commit is contained in:
Christoph Oelckers 2018-02-20 23:36:59 +01:00
parent cbcfea99cb
commit 57967a1033
8 changed files with 61 additions and 132 deletions

View file

@ -181,7 +181,11 @@ void I_ShutdownMusic(bool onexit)
assert (currSong == NULL); assert (currSong == NULL);
} }
Timidity::FreeAll(); Timidity::FreeAll();
if (onexit) WildMidi_Shutdown(); if (onexit)
{
WildMidi_Shutdown();
TimidityPP_Shutdown();
}
} }
void I_ShutdownMusicExit() void I_ShutdownMusicExit()

View file

@ -92,6 +92,7 @@ MIDIDevice *CreateWinMIDIDevice(int mididevice);
MIDIDevice *CreateAudioToolboxMIDIDevice(); MIDIDevice *CreateAudioToolboxMIDIDevice();
#endif #endif
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args); MIDIDevice *CreateTimidityPPMIDIDevice(const char *args);
void TimidityPP_Shutdown();
// Base class for pseudo-MIDI devices --------------------------------------- // Base class for pseudo-MIDI devices ---------------------------------------

View file

@ -45,6 +45,7 @@
#include "tmpfileplus.h" #include "tmpfileplus.h"
#include "m_misc.h" #include "m_misc.h"
#include "v_text.h" #include "v_text.h"
#include "i_system.h"
#include "timiditypp/timidity.h" #include "timiditypp/timidity.h"
#include "timiditypp/instrum.h" #include "timiditypp/instrum.h"
@ -64,6 +65,11 @@ public:
int GetDeviceType() const override { return MDEV_TIMIDITY; } int GetDeviceType() const override { return MDEV_TIMIDITY; }
bool Preprocess(MIDIStreamer *song, bool looping); bool Preprocess(MIDIStreamer *song, bool looping);
void TimidityVolumeChanged(); void TimidityVolumeChanged();
static void ClearInstruments()
{
if (instruments != nullptr) delete instruments;
instruments = nullptr;
}
protected: protected:
TimidityPlus::Player *Renderer; TimidityPlus::Player *Renderer;
@ -132,13 +138,10 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
TimidityPPMIDIDevice::~TimidityPPMIDIDevice () TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
{ {
Close(); Close();
/*
if (Renderer != nullptr) if (Renderer != nullptr)
{ {
delete Renderer; delete Renderer;
} }
*/
} }
//========================================================================== //==========================================================================
@ -176,7 +179,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata)
int ret = OpenStream(2, 0, callback, userdata); int ret = OpenStream(2, 0, callback, userdata);
if (ret == 0) if (ret == 0)
{ {
//Renderer->Reset(); //Renderer->playmidi_stream_init();
} }
return ret; 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) instruments->PrecacheInstruments(instrumentlist, count);
{
//Renderer->MarkInstrument((instruments[i] >> 7) & 127, instruments[i] >> 14, instruments[i] & 127);
}
//Renderer->load_missing_instruments();
} }
//========================================================================== //==========================================================================
@ -231,10 +230,9 @@ void TimidityPPMIDIDevice::HandleLongEvent(const uint8_t *data, int len)
void TimidityPPMIDIDevice::ComputeOutput(float *buffer, 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 memset(buffer, len, 0); // to do
Renderer->get_output(buffer, len);
//Renderer->ComputeOutput(buffer, len);
} }
//========================================================================== //==========================================================================
@ -257,6 +255,11 @@ MIDIDevice *CreateTimidityPPMIDIDevice(const char *args)
return new TimidityPPMIDIDevice(args); return new TimidityPPMIDIDevice(args);
} }
void TimidityPP_Shutdown()
{
TimidityPPMIDIDevice::ClearInstruments();
}
void TimidityPlus::ctl_cmsg(int type, int verbosity_level, const char *fmt, ...) void TimidityPlus::ctl_cmsg(int type, int verbosity_level, const char *fmt, ...)
{ {

View file

@ -73,10 +73,10 @@ void Effect::effect_left_right_delay(int32_t *buff, int32_t count)
return; return;
if (backoff > count) if (backoff > count)
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)); memset(buff + count, 0, 4 * (AUDIO_BUFFER_SIZE * 2 - count));
count = audio_buffer_size * 2; count = AUDIO_BUFFER_SIZE * 2;
} }
memcpy(save, buff, 4 * count); memcpy(save, buff, 4 * count);
pi = count - backoff; pi = count - backoff;

View file

@ -76,8 +76,6 @@ struct PlayMode {
}; };
extern PlayMode *play_mode_list[], *play_mode; extern PlayMode *play_mode_list[], *play_mode;
extern int audio_buffer_bits;
#define audio_buffer_size (1<<audio_buffer_bits)
/* 16-bit */ /* 16-bit */
extern void s32tos16(int32_t *lp, int32_t c); extern void s32tos16(int32_t *lp, int32_t c);

View file

@ -37,6 +37,7 @@
#include "quantity.h" #include "quantity.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "tables.h" #include "tables.h"
#include "effect.h"
CVAR(Bool, opt_modulation_wheel, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, opt_modulation_wheel, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, opt_portamento, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, opt_portamento, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -129,10 +130,12 @@ Player::Player(int freq, Instruments *instr)
reverb = new Reverb; reverb = new Reverb;
reverb->init_effect_status(play_system_mode); reverb->init_effect_status(play_system_mode);
effect = new Effect(reverb);
mixer = new Mixer(this); mixer = new Mixer(this);
recache = new Recache(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(); aq->setup();
for (int i = 0; i < MAX_CHANNELS; i++) for (int i = 0; i < MAX_CHANNELS; i++)
@ -191,6 +194,7 @@ Player::~Player()
delete aq; delete aq;
delete mixer; delete mixer;
delete recache; delete recache;
delete effect;
delete reverb; delete reverb;
} }
@ -5017,101 +5021,23 @@ void Player::do_compute_data(int32_t count)
current_sample += 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; aq->add(samples, count);
/*
for(i = 0; i < len; i++) effect->do_effect(samples, count);
// pass to caller
for (int i = 0; i < count && output_len > 0; i++)
{ {
type = e[i].type; *output_buffer++ = (*samples++)*(1.f / 0x80000000u);
if(type == ME_NOTEON || type == ME_LAST || type == ME_WRD || type == ME_SHERRY) *output_buffer++ = (*samples++)*(1.f / 0x80000000u);
return 0; output_len--;
if(type == ME_EOT)
return i + 1;
} }
return 0; */
memset(output_buffer, 0, output_len * 8);
return RC_OK;
} }
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++)
{
rc = compute_data(playback_rate / 2);
if(RC_IS_SKIP_FILE(rc))
goto midi_end;
}
/* 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;
}
/* count=0 means flush remaining buffered data to output device, then
flush the device itself */
int Player::compute_data(int32_t count) int Player::compute_data(int32_t count)
{ {
if (!count) if (!count)
@ -5126,29 +5052,19 @@ int Player::compute_data(int32_t count)
return RC_OK; return RC_OK;
} }
while ((count + buffered_count) >= audio_buffer_size) while ((count + buffered_count) >= AUDIO_BUFFER_SIZE)
{ {
int i; int i;
do_compute_data(audio_buffer_size - buffered_count); do_compute_data(AUDIO_BUFFER_SIZE - buffered_count);
count -= 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; return RC_ERROR;
buffer_pointer = common_buffer; buffer_pointer = common_buffer;
buffered_count = 0; 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) if (count > 0)
{ {
@ -5755,7 +5671,7 @@ int Player::play_event(MidiEvent *ev)
break; break;
case ME_EOT: case ME_EOT:
return midi_play_end(); break;
} }
#ifndef SUPPRESS_CHANNEL_LAYER #ifndef SUPPRESS_CHANNEL_LAYER
} }
@ -6101,8 +6017,7 @@ Instrument *Player::play_midi_load_instrument(int dr, int bk, int prog)
bool load_success; bool load_success;
// The inner workings of this function which alters the instrument data has been put into the Instruments class. // 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); auto instr = instruments->play_midi_load_instrument(dr, bk, prog, &load_success);
if (load_success) //if (load_success) send_output(NULL, 0); /* Update software buffer */
aq->add(NULL, 0); /* Update software buffer */
return instr; return instr;
} }
@ -6150,4 +6065,11 @@ void Player::init_channel_layer(int ch)
channel[ch].port_select = ch >> 4; channel[ch].port_select = ch >> 4;
} }
void Player::get_output(float *buffer, int len)
{
output_buffer = buffer;
output_len = len;
//compute_data(len);
}
} }

View file

@ -511,6 +511,7 @@ struct midi_file_info
class Recache; class Recache;
class Mixer; class Mixer;
class Reverb; class Reverb;
class Effect;
class AudioQueue; class AudioQueue;
class Player class Player
@ -532,6 +533,7 @@ private:
Recache *recache; Recache *recache;
Mixer *mixer; Mixer *mixer;
Reverb *reverb; Reverb *reverb;
Effect *effect;
AudioQueue *aq; AudioQueue *aq;
@ -559,6 +561,8 @@ private:
int current_freq_table; int current_freq_table;
int current_temper_freq_table; int current_temper_freq_table;
int master_tuning; int master_tuning;
float *output_buffer;
int output_len;
int make_rvid_flag; /* For reverb optimization */ int make_rvid_flag; /* For reverb optimization */
@ -666,6 +670,7 @@ private:
void update_legato_controls(int ch); void update_legato_controls(int ch);
void set_master_tuning(int tune); void set_master_tuning(int tune);
struct midi_file_info *new_midi_file_info(); struct midi_file_info *new_midi_file_info();
int send_output(int32_t *samples, int32_t count);
void adjust_amplification(void); void adjust_amplification(void);
@ -734,6 +739,7 @@ public:
void recompute_freq(int v); void recompute_freq(int v);
int get_default_mapID(int ch); int get_default_mapID(int ch);
void init_channel_layer(int ch); void init_channel_layer(int ch);
void get_output(float *buffer, int len);
// Only until streaming works. // Only until streaming works.
void skip_to(int32_t until_time, MidiEvent *evt_start); void skip_to(int32_t until_time, MidiEvent *evt_start);

View file

@ -1566,11 +1566,6 @@ void Player::run_midi(int samples)
} }
} }
void run_midi(int msec)
{
gplayer->run_midi(msec);
}
void timidity_close() void timidity_close()
{ {