mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- 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:
parent
57967a1033
commit
4813eeeb85
6 changed files with 75 additions and 1620 deletions
|
@ -1184,7 +1184,6 @@ set (PCH_SOURCES
|
||||||
sound/timiditypp/output.cpp
|
sound/timiditypp/output.cpp
|
||||||
sound/timiditypp/playmidi.cpp
|
sound/timiditypp/playmidi.cpp
|
||||||
sound/timiditypp/quantity.cpp
|
sound/timiditypp/quantity.cpp
|
||||||
sound/timiditypp/readmidi.cpp
|
|
||||||
sound/timiditypp/readmidic.cpp
|
sound/timiditypp/readmidic.cpp
|
||||||
sound/timiditypp/recache.cpp
|
sound/timiditypp/recache.cpp
|
||||||
sound/timiditypp/resample.cpp
|
sound/timiditypp/resample.cpp
|
||||||
|
|
|
@ -53,8 +53,8 @@
|
||||||
|
|
||||||
class TimidityPPMIDIDevice : public SoftSynthMIDIDevice
|
class TimidityPPMIDIDevice : public SoftSynthMIDIDevice
|
||||||
{
|
{
|
||||||
TArray<uint8_t> midi;
|
|
||||||
static TimidityPlus::Instruments *instruments;
|
static TimidityPlus::Instruments *instruments;
|
||||||
|
int sampletime;
|
||||||
public:
|
public:
|
||||||
TimidityPPMIDIDevice(const char *args);
|
TimidityPPMIDIDevice(const char *args);
|
||||||
~TimidityPPMIDIDevice();
|
~TimidityPPMIDIDevice();
|
||||||
|
@ -63,7 +63,6 @@ public:
|
||||||
void PrecacheInstruments(const uint16_t *instruments, int count);
|
void PrecacheInstruments(const uint16_t *instruments, int count);
|
||||||
//FString GetStats();
|
//FString GetStats();
|
||||||
int GetDeviceType() const override { return MDEV_TIMIDITY; }
|
int GetDeviceType() const override { return MDEV_TIMIDITY; }
|
||||||
bool Preprocess(MIDIStreamer *song, bool looping);
|
|
||||||
void TimidityVolumeChanged();
|
void TimidityVolumeChanged();
|
||||||
static void ClearInstruments()
|
static void ClearInstruments()
|
||||||
{
|
{
|
||||||
|
@ -127,6 +126,7 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
||||||
{
|
{
|
||||||
Renderer = new TimidityPlus::Player(timidity_frequency, instruments);
|
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
|
// TimidityPPMIDIDevice :: Open
|
||||||
|
@ -179,7 +158,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->playmidi_stream_init();
|
Renderer->playmidi_stream_init();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +187,7 @@ void TimidityPPMIDIDevice::PrecacheInstruments(const uint16_t *instrumentlist, i
|
||||||
|
|
||||||
void TimidityPPMIDIDevice::HandleEvent(int status, int parm1, int parm2)
|
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)
|
void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len)
|
||||||
{
|
{
|
||||||
Renderer->run_midi(len);
|
|
||||||
memset(buffer, len, 0); // to do
|
|
||||||
Renderer->get_output(buffer, len);
|
Renderer->get_output(buffer, len);
|
||||||
|
sampletime += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -258,6 +236,7 @@ MIDIDevice *CreateTimidityPPMIDIDevice(const char *args)
|
||||||
void TimidityPP_Shutdown()
|
void TimidityPP_Shutdown()
|
||||||
{
|
{
|
||||||
TimidityPPMIDIDevice::ClearInstruments();
|
TimidityPPMIDIDevice::ClearInstruments();
|
||||||
|
TimidityPlus::free_global_mblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5040,17 +5040,9 @@ int Player::send_output(int32_t *samples, int32_t count)
|
||||||
|
|
||||||
int Player::compute_data(int32_t count)
|
int Player::compute_data(int32_t count)
|
||||||
{
|
{
|
||||||
if (!count)
|
if (count == 0) return RC_OK;
|
||||||
{
|
|
||||||
if (buffered_count)
|
if (!buffered_count) buffer_pointer = common_buffer;
|
||||||
{
|
|
||||||
if (aq->add(common_buffer, buffered_count) == -1)
|
|
||||||
return RC_ERROR;
|
|
||||||
}
|
|
||||||
buffer_pointer = common_buffer;
|
|
||||||
buffered_count = 0;
|
|
||||||
return RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((count + buffered_count) >= AUDIO_BUFFER_SIZE)
|
while ((count + buffered_count) >= AUDIO_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -5170,12 +5162,12 @@ int Player::play_event(MidiEvent *ev)
|
||||||
int32_t i, j, cet;
|
int32_t i, j, cet;
|
||||||
int k, l, ch, orig_ch, port_ch, offset, layered;
|
int k, l, ch, orig_ch, port_ch, offset, layered;
|
||||||
|
|
||||||
current_event = ev;
|
//current_event = ev;
|
||||||
cet = MIDI_EVENT_TIME(ev);
|
cet = MIDI_EVENT_TIME(ev);
|
||||||
|
|
||||||
if (cet > current_sample)
|
if (cet > current_sample)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = RC_OK;
|
||||||
|
|
||||||
if (midi_streaming != 0 && (cet - current_sample) * 1000 / playback_rate > stream_max_compute)
|
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;
|
current_sample = cet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Printf("Computing %d samples\n", cet - current_sample);
|
||||||
|
|
||||||
rc = compute_data(cet - current_sample);
|
rc = compute_data(cet - current_sample);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
current_event = ev;
|
||||||
|
|
||||||
|
//Printf("Playing event %d, time %d\n", ev->type, ev->time);
|
||||||
|
|
||||||
#ifndef SUPPRESS_CHANNEL_LAYER
|
#ifndef SUPPRESS_CHANNEL_LAYER
|
||||||
orig_ch = ev->channel;
|
orig_ch = ev->channel;
|
||||||
|
@ -6069,7 +6066,60 @@ void Player::get_output(float *buffer, int len)
|
||||||
{
|
{
|
||||||
output_buffer = buffer;
|
output_buffer = buffer;
|
||||||
output_len = len;
|
output_len = len;
|
||||||
|
//Printf("Not Computing %d samples\n", len);
|
||||||
//compute_data(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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -740,6 +740,7 @@ public:
|
||||||
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);
|
void get_output(float *buffer, int len);
|
||||||
|
int send_event(int time, int status, int parm1, int parm2);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -118,6 +118,8 @@ PlayMode dpm =
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************************************************************/
|
/*****************************************************************************************************************************/
|
||||||
|
CRITICAL_SECTION critSect;
|
||||||
|
|
||||||
|
|
||||||
static int open_output(void)
|
static int open_output(void)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +131,9 @@ static int open_output(void)
|
||||||
MMRESULT Result;
|
MMRESULT Result;
|
||||||
UINT DeviceID;
|
UINT DeviceID;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&critSect);
|
||||||
|
|
||||||
if( dpm.name != NULL)
|
if( dpm.name != NULL)
|
||||||
ret = sscanf(dpm.name, "%d", &opt_wmme_device_id);
|
ret = sscanf(dpm.name, "%d", &opt_wmme_device_id);
|
||||||
if ( dpm.name == NULL || ret == 0 || ret == EOF)
|
if ( dpm.name == NULL || ret == 0 || ret == EOF)
|
||||||
|
|
Loading…
Reference in a new issue