- 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);
}
Timidity::FreeAll();
if (onexit) WildMidi_Shutdown();
if (onexit)
{
WildMidi_Shutdown();
TimidityPP_Shutdown();
}
}
void I_ShutdownMusicExit()

View file

@ -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 ---------------------------------------

View file

@ -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, ...)
{

View file

@ -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;

View file

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

View file

@ -37,6 +37,7 @@
#include "quantity.h"
#include "c_cvars.h"
#include "tables.h"
#include "effect.h"
CVAR(Bool, opt_modulation_wheel, 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->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);
}
}

View file

@ -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);

View file

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