- Timidity++ now plays ZDoom's event stream, although still through the Windows output module.

This also means that readmidi.cpp is no longer needed.
This commit is contained in:
Christoph Oelckers 2018-02-21 01:29:39 +01:00
parent 57967a1033
commit 4813eeeb85
6 changed files with 75 additions and 1620 deletions

View file

@ -1184,7 +1184,6 @@ set (PCH_SOURCES
sound/timiditypp/output.cpp
sound/timiditypp/playmidi.cpp
sound/timiditypp/quantity.cpp
sound/timiditypp/readmidi.cpp
sound/timiditypp/readmidic.cpp
sound/timiditypp/recache.cpp
sound/timiditypp/resample.cpp

View file

@ -53,8 +53,8 @@
class TimidityPPMIDIDevice : public SoftSynthMIDIDevice
{
TArray<uint8_t> midi;
static TimidityPlus::Instruments *instruments;
int sampletime;
public:
TimidityPPMIDIDevice(const char *args);
~TimidityPPMIDIDevice();
@ -63,7 +63,6 @@ public:
void PrecacheInstruments(const uint16_t *instruments, int count);
//FString GetStats();
int GetDeviceType() const override { return MDEV_TIMIDITY; }
bool Preprocess(MIDIStreamer *song, bool looping);
void TimidityVolumeChanged();
static void ClearInstruments()
{
@ -127,6 +126,7 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
{
Renderer = new TimidityPlus::Player(timidity_frequency, instruments);
}
sampletime = 0;
}
//==========================================================================
@ -144,27 +144,6 @@ TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
}
}
//==========================================================================
//
// TimidityPPMIDIDevice :: Preprocess
//
//==========================================================================
namespace TimidityPlus
{
int load_midi_file(FileReader *fr, TimidityPlus::Player *p);
void run_midi(int samples);
void timidity_close();
}
bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
{
// Write MIDI song to temporary file
song->CreateSMF(midi, looping ? 0 : 1);
MemoryReader fr((char*)&midi[0], midi.Size());
return !TimidityPlus::load_midi_file(&fr, Renderer);
}
//==========================================================================
//
// TimidityPPMIDIDevice :: Open
@ -179,7 +158,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata)
int ret = OpenStream(2, 0, callback, userdata);
if (ret == 0)
{
//Renderer->playmidi_stream_init();
Renderer->playmidi_stream_init();
}
return ret;
}
@ -208,7 +187,7 @@ void TimidityPPMIDIDevice::PrecacheInstruments(const uint16_t *instrumentlist, i
void TimidityPPMIDIDevice::HandleEvent(int status, int parm1, int parm2)
{
//Renderer->HandleEvent(status, parm1, parm2);
Renderer->send_event(sampletime, status, parm1, parm2);
}
//==========================================================================
@ -230,9 +209,8 @@ void TimidityPPMIDIDevice::HandleLongEvent(const uint8_t *data, int len)
void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len)
{
Renderer->run_midi(len);
memset(buffer, len, 0); // to do
Renderer->get_output(buffer, len);
sampletime += len;
}
//==========================================================================
@ -258,6 +236,7 @@ MIDIDevice *CreateTimidityPPMIDIDevice(const char *args)
void TimidityPP_Shutdown()
{
TimidityPPMIDIDevice::ClearInstruments();
TimidityPlus::free_global_mblock();
}

View file

@ -5040,17 +5040,9 @@ int Player::send_output(int32_t *samples, int32_t count)
int Player::compute_data(int32_t count)
{
if (!count)
{
if (buffered_count)
{
if (aq->add(common_buffer, buffered_count) == -1)
return RC_ERROR;
}
buffer_pointer = common_buffer;
buffered_count = 0;
return RC_OK;
}
if (count == 0) return RC_OK;
if (!buffered_count) buffer_pointer = common_buffer;
while ((count + buffered_count) >= AUDIO_BUFFER_SIZE)
{
@ -5170,12 +5162,12 @@ int Player::play_event(MidiEvent *ev)
int32_t i, j, cet;
int k, l, ch, orig_ch, port_ch, offset, layered;
current_event = ev;
//current_event = ev;
cet = MIDI_EVENT_TIME(ev);
if (cet > current_sample)
{
int rc;
int rc = RC_OK;
if (midi_streaming != 0 && (cet - current_sample) * 1000 / playback_rate > stream_max_compute)
{
@ -5183,10 +5175,15 @@ int Player::play_event(MidiEvent *ev)
current_sample = cet;
}
//Printf("Computing %d samples\n", cet - current_sample);
rc = compute_data(cet - current_sample);
if (rc != RC_OK)
return rc;
}
current_event = ev;
//Printf("Playing event %d, time %d\n", ev->type, ev->time);
#ifndef SUPPRESS_CHANNEL_LAYER
orig_ch = ev->channel;
@ -6069,7 +6066,60 @@ void Player::get_output(float *buffer, int len)
{
output_buffer = buffer;
output_len = len;
//Printf("Not Computing %d samples\n", len);
//compute_data(len);
}
int Player::send_event(int sampletime, int status, int parm1, int parm2)
{
MidiEvent ev;
ev.time = sampletime;
ev.type = ME_NONE;
ev.channel = status & 0x0000000f;
//ev.channel = ev.channel + port * 16;
ev.a = (uint8_t)parm1;
ev.b = (uint8_t)parm2;
switch ((int)(status & 0x000000f0))
{
case 0x80:
ev.type = ME_NOTEOFF;
break;
case 0x90:
ev.type = (ev.b) ? ME_NOTEON : ME_NOTEOFF;
break;
case 0xa0:
ev.type = ME_KEYPRESSURE;
break;
case 0xb0:
if (!convert_midi_control_change(ev.channel, ev.a, ev.b, &ev))
ev.type = ME_NONE;
break;
case 0xc0:
ev.type = ME_PROGRAM;
break;
case 0xd0:
ev.type = ME_CHANNEL_PRESSURE;
break;
case 0xe0:
ev.type = ME_PITCHWHEEL;
break;
/*
case 0xf0:
if ((status & 0x000000ff) == 0xf2)
{
ev.type = ME_PROGRAM;
}
break;
*/
default:
break;
}
if (ev.type != ME_NONE)
{
play_event(&ev);
}
return 0;
}
}

View file

@ -740,6 +740,7 @@ public:
int get_default_mapID(int ch);
void init_channel_layer(int ch);
void get_output(float *buffer, int len);
int send_event(int time, int status, int parm1, int parm2);
// Only until streaming works.
void skip_to(int32_t until_time, MidiEvent *evt_start);

File diff suppressed because it is too large Load diff

View file

@ -118,6 +118,8 @@ PlayMode dpm =
};
/*****************************************************************************************************************************/
CRITICAL_SECTION critSect;
static int open_output(void)
{
@ -129,7 +131,9 @@ static int open_output(void)
MMRESULT Result;
UINT DeviceID;
int ret;
InitializeCriticalSection(&critSect);
if( dpm.name != NULL)
ret = sscanf(dpm.name, "%d", &opt_wmme_device_id);
if ( dpm.name == NULL || ret == 0 || ret == EOF)