mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
- fixed: The MIDI wave writer set the sample rate to save at too late.
This was done after the players had already been created. To ensure that everything gets set properly it is necessary to pass the desired sample rate to the device's constructor and let it make sure that a proper sample rate gets set.
This commit is contained in:
parent
72831c9db7
commit
9b61ee9618
9 changed files with 37 additions and 66 deletions
|
@ -88,7 +88,7 @@ public:
|
|||
#ifdef _WIN32
|
||||
MIDIDevice *CreateWinMIDIDevice(int mididevice);
|
||||
#endif
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args);
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args, int samplerate);
|
||||
void TimidityPP_Shutdown();
|
||||
|
||||
// Base class for software synthesizer MIDI output devices ------------------
|
||||
|
@ -97,7 +97,7 @@ class SoftSynthMIDIDevice : public MIDIDevice
|
|||
{
|
||||
friend class MIDIWaveWriter;
|
||||
public:
|
||||
SoftSynthMIDIDevice();
|
||||
SoftSynthMIDIDevice(int samplerate, int minrate = 1, int maxrate = 1000000 /* something higher than any valid value */);
|
||||
~SoftSynthMIDIDevice();
|
||||
|
||||
void Close();
|
||||
|
@ -131,10 +131,6 @@ protected:
|
|||
int OpenStream(int chunks, int flags, MidiCallback, void *userdata);
|
||||
static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata);
|
||||
virtual bool ServiceStream (void *buff, int numbytes);
|
||||
virtual void SetSampleRate(int rate)
|
||||
{
|
||||
if (rate > 11025) { SampleRate = rate; }
|
||||
}
|
||||
int GetSampleRate() const { return SampleRate; }
|
||||
|
||||
virtual void HandleEvent(int status, int parm1, int parm2) = 0;
|
||||
|
@ -152,7 +148,6 @@ public:
|
|||
void Close();
|
||||
int GetTechnology() const;
|
||||
FString GetStats();
|
||||
virtual void SetSampleRate(int rate) { } // cannot be changed.
|
||||
|
||||
protected:
|
||||
void CalcTickRate();
|
||||
|
@ -182,14 +177,13 @@ namespace Timidity { struct Renderer; }
|
|||
class TimidityMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
public:
|
||||
TimidityMIDIDevice(const char *args);
|
||||
TimidityMIDIDevice(const char *args, int samplerate);
|
||||
~TimidityMIDIDevice();
|
||||
|
||||
int Open(MidiCallback, void *userdata);
|
||||
void PrecacheInstruments(const uint16_t *instruments, int count);
|
||||
FString GetStats();
|
||||
int GetDeviceType() const override { return MDEV_GUS; }
|
||||
virtual void SetSampleRate(int rate) { if (rate >= 11025 && rate < 65535) SampleRate = rate; }
|
||||
|
||||
protected:
|
||||
Timidity::Renderer *Renderer;
|
||||
|
@ -204,7 +198,7 @@ protected:
|
|||
class MIDIWaveWriter : public SoftSynthMIDIDevice
|
||||
{
|
||||
public:
|
||||
MIDIWaveWriter(const char *filename, MIDIDevice *devtouse, int rate);
|
||||
MIDIWaveWriter(const char *filename, MIDIDevice *devtouse);
|
||||
~MIDIWaveWriter();
|
||||
int Resume();
|
||||
int Open(MidiCallback cb, void *userdata)
|
||||
|
@ -235,14 +229,13 @@ protected:
|
|||
class WildMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
public:
|
||||
WildMIDIDevice(const char *args);
|
||||
WildMIDIDevice(const char *args, int samplerate);
|
||||
~WildMIDIDevice();
|
||||
|
||||
int Open(MidiCallback, void *userdata);
|
||||
void PrecacheInstruments(const uint16_t *instruments, int count);
|
||||
FString GetStats();
|
||||
int GetDeviceType() const override { return MDEV_WILDMIDI; }
|
||||
virtual void SetSampleRate(int rate) { if (rate >= 11025 && SampleRate < rate) SampleRate = rate; }
|
||||
|
||||
protected:
|
||||
WildMidi_Renderer *Renderer;
|
||||
|
@ -268,7 +261,7 @@ struct fluid_synth_t;
|
|||
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
|
||||
{
|
||||
public:
|
||||
FluidSynthMIDIDevice(const char *args);
|
||||
FluidSynthMIDIDevice(const char *args, int samplerate);
|
||||
~FluidSynthMIDIDevice();
|
||||
|
||||
int Open(MidiCallback, void *userdata);
|
||||
|
@ -277,7 +270,6 @@ public:
|
|||
void FluidSettingNum(const char *setting, double value);
|
||||
void FluidSettingStr(const char *setting, const char *value);
|
||||
int GetDeviceType() const override { return MDEV_FLUIDSYNTH; }
|
||||
virtual void SetSampleRate(int rate) { if (rate >= 22050 && rate <= 96000) SampleRate = rate; }
|
||||
|
||||
protected:
|
||||
void HandleEvent(int status, int parm1, int parm2);
|
||||
|
@ -382,7 +374,7 @@ protected:
|
|||
|
||||
|
||||
static EMidiDevice SelectMIDIDevice(EMidiDevice devtype);
|
||||
MIDIDevice *CreateMIDIDevice(EMidiDevice devtype);
|
||||
MIDIDevice *CreateMIDIDevice(EMidiDevice devtype, int samplerate);
|
||||
|
||||
static void Callback(void *userdata);
|
||||
|
||||
|
|
|
@ -274,7 +274,8 @@ CUSTOM_CVAR(Int, fluid_chorus_type, FLUID_CHORUS_DEFAULT_TYPE, CVAR_ARCHIVE|CVAR
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
|
||||
FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args, int samplerate)
|
||||
: SoftSynthMIDIDevice(samplerate <= 0? fluid_samplerate : samplerate, 22050, 96000)
|
||||
{
|
||||
FluidSynth = NULL;
|
||||
FluidSettings = NULL;
|
||||
|
@ -290,11 +291,6 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
|
|||
printf("Failed to create FluidSettings.\n");
|
||||
return;
|
||||
}
|
||||
SampleRate = fluid_samplerate;
|
||||
if (SampleRate < 22050 || SampleRate > 96000)
|
||||
{ // Match sample rate to SFX rate
|
||||
SampleRate = clamp((int)GSnd->GetOutputRate(), 22050, 96000);
|
||||
}
|
||||
fluid_settings_setnum(FluidSettings, "synth.sample-rate", SampleRate);
|
||||
fluid_settings_setnum(FluidSettings, "synth.gain", fluid_gain);
|
||||
fluid_settings_setint(FluidSettings, "synth.reverb.active", fluid_reverb);
|
||||
|
|
|
@ -79,6 +79,7 @@ CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
|||
//==========================================================================
|
||||
|
||||
OPLMIDIDevice::OPLMIDIDevice(const char *args)
|
||||
: SoftSynthMIDIDevice((int)OPL_SAMPLE_RATE)
|
||||
{
|
||||
OPL_SetCore(args);
|
||||
FullPan = opl_fullpan;
|
||||
|
@ -88,7 +89,6 @@ OPLMIDIDevice::OPLMIDIDevice(const char *args)
|
|||
data.Read(filehdr, 8);
|
||||
if (memcmp(filehdr, "#OPL_II#", 8)) I_Error("Corrupt GENMIDI lump");
|
||||
data.Read(OPLinstruments, sizeof(GenMidiInstrument) * GENMIDI_NUM_TOTAL);
|
||||
SampleRate = (int)OPL_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -68,14 +68,15 @@ CVAR(Bool, synth_watch, false, 0)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
SoftSynthMIDIDevice::SoftSynthMIDIDevice()
|
||||
SoftSynthMIDIDevice::SoftSynthMIDIDevice(int samplerate, int minrate, int maxrate)
|
||||
{
|
||||
Stream = NULL;
|
||||
Tempo = 0;
|
||||
Division = 0;
|
||||
Events = NULL;
|
||||
Started = false;
|
||||
SampleRate = GSnd != NULL ? (int)GSnd->GetOutputRate() : 44100;
|
||||
SampleRate = samplerate;
|
||||
if (SampleRate < minrate || SampleRate > maxrate) SampleRate = GSnd != NULL ? clamp((int)GSnd->GetOutputRate(), minrate, maxrate) : 44100;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -66,9 +66,9 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
TimidityMIDIDevice::TimidityMIDIDevice(const char *args)
|
||||
TimidityMIDIDevice::TimidityMIDIDevice(const char *args, int samplerate)
|
||||
: SoftSynthMIDIDevice(samplerate, 11025, 65535)
|
||||
{
|
||||
Renderer = nullptr;
|
||||
Renderer = new Timidity::Renderer((float)SampleRate, args);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class TimidityPPMIDIDevice : public SoftSynthMIDIDevice
|
|||
static TimidityPlus::Instruments *instruments;
|
||||
int sampletime;
|
||||
public:
|
||||
TimidityPPMIDIDevice(const char *args);
|
||||
TimidityPPMIDIDevice(const char *args, int samplerate);
|
||||
~TimidityPPMIDIDevice();
|
||||
|
||||
int Open(MidiCallback, void *userdata);
|
||||
|
@ -65,10 +65,6 @@ public:
|
|||
if (instruments != nullptr) delete instruments;
|
||||
instruments = nullptr;
|
||||
}
|
||||
virtual void SetSampleRate(int rate)
|
||||
{
|
||||
if (rate >= 4000 && SampleRate < rate) SampleRate = rate;
|
||||
}
|
||||
|
||||
double test[3] = { 0, 0, 0 };
|
||||
|
||||
|
@ -91,13 +87,7 @@ CUSTOM_CVAR(String, timidity_config, "timidity.cfg", CVAR_ARCHIVE | CVAR_GLOBALC
|
|||
}
|
||||
|
||||
|
||||
CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{ // Clamp frequency to Timidity's limits
|
||||
if (self < 4000)
|
||||
self = 4000;
|
||||
else if (self > 65000)
|
||||
self = 65000;
|
||||
}
|
||||
CVAR (Int, timidity_frequency, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -105,7 +95,8 @@ CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args, int samplerate)
|
||||
:SoftSynthMIDIDevice(samplerate <= 0? timidity_frequency : samplerate, 4000, 65000)
|
||||
{
|
||||
if (args == NULL || *args == 0) args = timidity_config;
|
||||
|
||||
|
@ -115,8 +106,8 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
|||
delete instruments;
|
||||
instruments = nullptr;
|
||||
}
|
||||
TimidityPlus::set_playback_rate(timidity_frequency);
|
||||
SampleRate = timidity_frequency;
|
||||
TimidityPlus::set_playback_rate(SampleRate);
|
||||
|
||||
if (instruments == nullptr)
|
||||
{
|
||||
instruments = new TimidityPlus::Instruments;
|
||||
|
@ -229,9 +220,9 @@ void TimidityPPMIDIDevice::ComputeOutput(float *buffer, int len)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args)
|
||||
MIDIDevice *CreateTimidityPPMIDIDevice(const char *args, int samplerate)
|
||||
{
|
||||
return new TimidityPPMIDIDevice(args);
|
||||
return new TimidityPPMIDIDevice(args, samplerate);
|
||||
}
|
||||
|
||||
void TimidityPP_Shutdown()
|
||||
|
|
|
@ -87,7 +87,8 @@ struct FmtChunk
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
MIDIWaveWriter::MIDIWaveWriter(const char *filename, MIDIDevice *playdevice, int rate)
|
||||
MIDIWaveWriter::MIDIWaveWriter(const char *filename, MIDIDevice *playdevice)
|
||||
: SoftSynthMIDIDevice(playDevice->GetSampleRate())
|
||||
{
|
||||
File = FileWriter::Open(filename);
|
||||
playDevice = (SoftSynthMIDIDevice*) playdevice;
|
||||
|
@ -102,15 +103,13 @@ MIDIWaveWriter::MIDIWaveWriter(const char *filename, MIDIDevice *playdevice, int
|
|||
if (4*3 != File->Write(work, 4 * 3)) goto fail;
|
||||
|
||||
|
||||
playDevice->SetSampleRate(rate);
|
||||
playDevice->CalcTickRate();
|
||||
rate = playDevice->GetSampleRate(); // read back what the device made of it.
|
||||
fmt.ChunkID = MAKE_ID('f','m','t',' ');
|
||||
fmt.ChunkLen = LittleLong(uint32_t(sizeof(fmt) - 8));
|
||||
fmt.FormatTag = LittleShort(0xFFFE); // WAVE_FORMAT_EXTENSIBLE
|
||||
fmt.Channels = LittleShort(2);
|
||||
fmt.SamplesPerSec = LittleLong(rate);
|
||||
fmt.AvgBytesPerSec = LittleLong(rate * 8);
|
||||
fmt.SamplesPerSec = LittleLong(SampleRate);
|
||||
fmt.AvgBytesPerSec = LittleLong(SampleRate * 8);
|
||||
fmt.BlockAlign = LittleShort(8);
|
||||
fmt.BitsPerSample = LittleShort(32);
|
||||
fmt.ExtensionSize = LittleShort(2 + 4 + 16);
|
||||
|
|
|
@ -89,19 +89,11 @@ CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBAL
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
WildMIDIDevice::WildMIDIDevice(const char *args)
|
||||
WildMIDIDevice::WildMIDIDevice(const char *args, int samplerate)
|
||||
:SoftSynthMIDIDevice(samplerate <= 0? wildmidi_frequency : samplerate, 11025, 65535)
|
||||
{
|
||||
Renderer = NULL;
|
||||
|
||||
if (wildmidi_frequency > 0)
|
||||
{
|
||||
SampleRate = clamp(*wildmidi_frequency, 11025, 65535);
|
||||
}
|
||||
else
|
||||
{ // If nothing is set, use the active device's output rate.
|
||||
SampleRate = (int)GSnd->GetOutputRate();
|
||||
}
|
||||
|
||||
if (args == NULL || *args == 0) args = wildmidi_config;
|
||||
|
||||
if (CurrentConfig.CompareNoCase(args) != 0 || SampleRate != WildMidi_GetSampleRate())
|
||||
|
|
|
@ -182,7 +182,7 @@ EMidiDevice MIDIStreamer::SelectMIDIDevice(EMidiDevice device)
|
|||
|
||||
static EMidiDevice lastRequestedDevice, lastSelectedDevice;
|
||||
|
||||
MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
||||
MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype, int samplerate)
|
||||
{
|
||||
bool checked[MDEV_COUNT] = { false };
|
||||
|
||||
|
@ -197,7 +197,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
|||
switch (devtype)
|
||||
{
|
||||
case MDEV_GUS:
|
||||
dev = new TimidityMIDIDevice(Args);
|
||||
dev = new TimidityMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
case MDEV_MMAPI:
|
||||
|
@ -208,7 +208,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
|||
// Intentional fall-through for non-Windows systems.
|
||||
|
||||
case MDEV_FLUIDSYNTH:
|
||||
dev = new FluidSynthMIDIDevice(Args);
|
||||
dev = new FluidSynthMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
case MDEV_OPL:
|
||||
|
@ -216,11 +216,11 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
|||
break;
|
||||
|
||||
case MDEV_TIMIDITY:
|
||||
dev = CreateTimidityPPMIDIDevice(Args);
|
||||
dev = CreateTimidityPPMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
case MDEV_WILDMIDI:
|
||||
dev = new WildMIDIDevice(Args);
|
||||
dev = new WildMIDIDevice(Args, samplerate);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -284,7 +284,7 @@ void MIDIStreamer::Play(bool looping, int subsong)
|
|||
m_Looping = looping;
|
||||
source->SetMIDISubsong(subsong);
|
||||
devtype = SelectMIDIDevice(DeviceType);
|
||||
MIDI = CreateMIDIDevice(devtype);
|
||||
MIDI = CreateMIDIDevice(devtype, 0);
|
||||
InitPlayback();
|
||||
}
|
||||
|
||||
|
@ -319,8 +319,8 @@ bool MIDIStreamer::DumpWave(const char *filename, int subsong, int samplerate)
|
|||
|
||||
assert(MIDI == NULL);
|
||||
auto devtype = SelectMIDIDevice(DeviceType);
|
||||
MIDI = CreateMIDIDevice(devtype);
|
||||
MIDI = new MIDIWaveWriter(filename, MIDI, samplerate);
|
||||
MIDI = CreateMIDIDevice(devtype, samplerate);
|
||||
MIDI = new MIDIWaveWriter(filename, MIDI);
|
||||
return InitPlayback();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue