diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index b4269aaba..9679fec93 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -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); diff --git a/src/sound/mididevices/music_fluidsynth_mididevice.cpp b/src/sound/mididevices/music_fluidsynth_mididevice.cpp index 05ed27532..97282299f 100644 --- a/src/sound/mididevices/music_fluidsynth_mididevice.cpp +++ b/src/sound/mididevices/music_fluidsynth_mididevice.cpp @@ -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); diff --git a/src/sound/mididevices/music_opl_mididevice.cpp b/src/sound/mididevices/music_opl_mididevice.cpp index 72ae555a8..a37358520 100644 --- a/src/sound/mididevices/music_opl_mididevice.cpp +++ b/src/sound/mididevices/music_opl_mididevice.cpp @@ -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; } //========================================================================== diff --git a/src/sound/mididevices/music_softsynth_mididevice.cpp b/src/sound/mididevices/music_softsynth_mididevice.cpp index ae46e31d3..ccee4bd27 100644 --- a/src/sound/mididevices/music_softsynth_mididevice.cpp +++ b/src/sound/mididevices/music_softsynth_mididevice.cpp @@ -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; } //========================================================================== diff --git a/src/sound/mididevices/music_timidity_mididevice.cpp b/src/sound/mididevices/music_timidity_mididevice.cpp index 675fee126..c8454f811 100644 --- a/src/sound/mididevices/music_timidity_mididevice.cpp +++ b/src/sound/mididevices/music_timidity_mididevice.cpp @@ -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); } diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index c299dddae..40205840f 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -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() diff --git a/src/sound/mididevices/music_wavewriter_mididevice.cpp b/src/sound/mididevices/music_wavewriter_mididevice.cpp index ddf5bb3bb..1f109aea2 100644 --- a/src/sound/mididevices/music_wavewriter_mididevice.cpp +++ b/src/sound/mididevices/music_wavewriter_mididevice.cpp @@ -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); diff --git a/src/sound/mididevices/music_wildmidi_mididevice.cpp b/src/sound/mididevices/music_wildmidi_mididevice.cpp index 2a71f1c7e..fe3571389 100644 --- a/src/sound/mididevices/music_wildmidi_mididevice.cpp +++ b/src/sound/mididevices/music_wildmidi_mididevice.cpp @@ -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()) diff --git a/src/sound/musicformats/music_midistream.cpp b/src/sound/musicformats/music_midistream.cpp index eea204910..2b4e1c34e 100644 --- a/src/sound/musicformats/music_midistream.cpp +++ b/src/sound/musicformats/music_midistream.cpp @@ -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(); }