diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index b276cfcfed..1c3ed8d287 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -763,29 +763,26 @@ static MIDISource *GetMIDISource(const char *fn) UNSAFE_CCMD (writeopl) { - if (argv.argc() == 2) + if (argv.argc() >= 3 && argv.argc() <= 7) { - if (currSong == nullptr) - { - Printf ("No song is currently playing.\n"); - } - else - { - MusInfo *dumper = currSong->GetOPLDumper(argv[1]); - if (dumper == nullptr) - { - Printf ("Current song cannot be saved as OPL data.\n"); - } - else - { - dumper->Play(false, 0); // FIXME: Remember subsong. - delete dumper; - } - } + auto source = GetMIDISource(argv[1]); + if (source == nullptr) return; + + // We must stop the currently playing music to avoid interference between two synths. + auto savedsong = mus_playing; + S_StopMusic(true); + auto streamer = new MIDIStreamer(MDEV_OPL, nullptr); + streamer->SetMIDISource(source); + streamer->DumpOPL(argv[2], argv.argc() <4 ? 0 : (int)strtol(argv[3], nullptr, 10)); + delete streamer; + S_ChangeMusic(savedsong.name, savedsong.baseorder, savedsong.loop, true); + } else { - Printf ("Usage: writeopl \n"); + Printf("Usage: writeopl [subsong]\n" + " - use '*' as song name to dump the currently playing song\n" + " - use 0 for subsong to play the default\n"); } } @@ -824,7 +821,7 @@ UNSAFE_CCMD (writewave) // We must stop the currently playing music to avoid interference between two synths. auto savedsong = mus_playing; S_StopMusic(true); - if (snd_mididevice >= 0) dev = MDEV_FLUIDSYNTH; // The Windows system synth cannot dump a wave. + if (dev == MDEV_DEFAULT && snd_mididevice >= 0) dev = MDEV_FLUIDSYNTH; // The Windows system synth cannot dump a wave. auto streamer = new MIDIStreamer(dev, argv.argc() < 6 ? nullptr : argv[6]); streamer->SetMIDISource(source); streamer->DumpWave(argv[2], argv.argc() <4? 0: (int)strtol(argv[3], nullptr, 10), argv.argc() <5 ? 0 : (int)strtol(argv[4], nullptr, 10)); diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 501e61974a..2f04a39c15 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -363,7 +363,8 @@ public: } bool DumpWave(const char *filename, int subsong, int samplerate); - + bool DumpOPL(const char *filename, int subsong); + protected: MIDIStreamer(const char *dumpname, EMidiDevice type); @@ -376,6 +377,7 @@ protected: void SetTempo(int new_tempo); void Precache(); void StartPlayback(); + bool InitPlayback(); //void SetMidiSynth(MIDIDevice *synth); diff --git a/src/sound/musicformats/music_midistream.cpp b/src/sound/musicformats/music_midistream.cpp index e3f58bc848..207ea51a05 100644 --- a/src/sound/musicformats/music_midistream.cpp +++ b/src/sound/musicformats/music_midistream.cpp @@ -232,26 +232,65 @@ void MIDIStreamer::Play(bool looping, int subsong) { EMidiDevice devtype; - m_Status = STATE_Stopped; + if (source == nullptr) return; // We have nothing to play so abort. + + assert(MIDI == NULL); m_Looping = looping; + source->SetMIDISubsong(subsong); + devtype = SelectMIDIDevice(DeviceType); + MIDI = CreateMIDIDevice(devtype); + InitPlayback(); +} + +//========================================================================== +// +// MIDIStreamer :: DumpWave +// +//========================================================================== + +bool MIDIStreamer::DumpOPL(const char *filename, int subsong) +{ + m_Looping = false; + if (source == nullptr) return false; // We have nothing to play so abort. + source->SetMIDISubsong(subsong); + + assert(MIDI == NULL); + MIDI = new OPLDumperMIDIDevice(filename); + return InitPlayback(); +} + +//========================================================================== +// +// MIDIStreamer :: DumpWave +// +//========================================================================== + +bool MIDIStreamer::DumpWave(const char *filename, int subsong, int samplerate) +{ + m_Looping = false; + if (source == nullptr) return false; // We have nothing to play so abort. + source->SetMIDISubsong(subsong); + + assert(MIDI == NULL); + auto devtype = SelectMIDIDevice(DeviceType); + MIDI = CreateMIDIDevice(devtype); + MIDI = new MIDIWaveWriter(filename, MIDI, samplerate); + return InitPlayback(); +} + +//========================================================================== +// +// MIDIStreamer :: InitPlayback +// +//========================================================================== + +bool MIDIStreamer::InitPlayback() +{ + m_Status = STATE_Stopped; EndQueued = 0; VolumeChanged = false; Restarting = true; InitialPlayback = true; - if (source == nullptr) return; // We have nothing to play so abort. - - assert(MIDI == NULL); - devtype = SelectMIDIDevice(DeviceType); - /* - if (DumpFilename.IsNotEmpty()) - { - if (DeviceType == MDEV_OPLDUMP) - { - MIDI = new OPLDumperMIDIDevice(DumpFilename); - } - } - */ - MIDI = CreateMIDIDevice(devtype); if (MIDI == NULL || 0 != MIDI->Open(Callback, this)) { @@ -261,18 +300,17 @@ void MIDIStreamer::Play(bool looping, int subsong) delete MIDI; MIDI = NULL; } - return; + return false; } - source->SetMIDISubsong(subsong); source->CheckCaps(MIDI->GetTechnology()); - if (MIDI->Preprocess(this, looping)) + if (MIDI->Preprocess(this, m_Looping)) { StartPlayback(); if (MIDI == NULL) { // The MIDI file had no content and has been automatically closed. - return; + return false; } } @@ -280,10 +318,12 @@ void MIDIStreamer::Play(bool looping, int subsong) { Printf ("Starting MIDI playback failed\n"); Stop(); + return false; } else { m_Status = STATE_Playing; + return true; } } @@ -343,58 +383,6 @@ void MIDIStreamer::StartPlayback() while (BufferNum != 0); } -bool MIDIStreamer::DumpWave(const char *filename, int subsong, int samplerate) -{ - EMidiDevice devtype; - - m_Status = STATE_Stopped; - m_Looping = false; - EndQueued = 0; - VolumeChanged = false; - Restarting = true; - InitialPlayback = true; - if (source == nullptr) return false; // We have nothing to play so abort. - - assert(MIDI == NULL); - devtype = SelectMIDIDevice(DeviceType); - MIDI = CreateMIDIDevice(devtype); - MIDI = new MIDIWaveWriter(filename, MIDI, samplerate); - - if (MIDI == NULL || 0 != MIDI->Open(Callback, this)) - { - Printf(PRINT_BOLD, "Could not open MIDI out device\n"); - if (MIDI != NULL) - { - delete MIDI; - MIDI = NULL; - } - return false; - } - - source->SetMIDISubsong(subsong); - source->CheckCaps(MIDI->GetTechnology()); - - if (MIDI->Preprocess(this, false)) - { - StartPlayback(); - if (MIDI == NULL) - { // The MIDI file had no content and has been automatically closed. - return false; - } - } - - if (0 != MIDI->Resume()) - { - Printf("Starting MIDI playback failed\n"); - Stop(); - return false; - } - else - { - return true; - } -} - //========================================================================== // // MIDIStreamer :: Pause