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/playmidi.cpp
|
||||
sound/timiditypp/quantity.cpp
|
||||
sound/timiditypp/readmidi.cpp
|
||||
sound/timiditypp/readmidic.cpp
|
||||
sound/timiditypp/recache.cpp
|
||||
sound/timiditypp/resample.cpp
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
@ -118,6 +118,8 @@ PlayMode dpm =
|
|||
};
|
||||
|
||||
/*****************************************************************************************************************************/
|
||||
CRITICAL_SECTION critSect;
|
||||
|
||||
|
||||
static int open_output(void)
|
||||
{
|
||||
|
@ -130,6 +132,8 @@ static int open_output(void)
|
|||
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)
|
||||
|
|
Loading…
Reference in a new issue