SKY: Support external digital music tracks.
This allows replacement of the supplied MIDI music with tracks from the Music Enhancement Project.
This commit is contained in:
parent
ef58cc326e
commit
3d83111f62
9 changed files with 62 additions and 22 deletions
|
@ -30,9 +30,8 @@
|
|||
|
||||
namespace Sky {
|
||||
|
||||
AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pDisk) {
|
||||
AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
|
||||
_driverFileBase = 60202;
|
||||
_mixer = pMixer;
|
||||
_sampleRate = pMixer->getOutputRate();
|
||||
|
||||
_opl = makeAdLibOPL(_sampleRate);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "sky/music/musicbase.h"
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/fmopl.h"
|
||||
#include "audio/mixer.h"
|
||||
|
||||
namespace Sky {
|
||||
|
||||
|
@ -44,7 +43,6 @@ public:
|
|||
|
||||
private:
|
||||
FM_OPL *_opl;
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
uint8 *_initSequence;
|
||||
uint32 _sampleRate, _nextMusicPoll;
|
||||
|
|
|
@ -34,7 +34,7 @@ void GmMusic::passTimerFunc(void *param) {
|
|||
((GmMusic*)param)->timerCall();
|
||||
}
|
||||
|
||||
GmMusic::GmMusic(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) {
|
||||
GmMusic::GmMusic(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
|
||||
_driverFileBase = 60200;
|
||||
_midiDrv = pMidiDrv;
|
||||
int midiRes = _midiDrv->open();
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Sky {
|
|||
|
||||
class GmMusic : public MusicBase {
|
||||
public:
|
||||
GmMusic(MidiDriver *pMidiDrv, Disk *pDisk);
|
||||
GmMusic(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk);
|
||||
~GmMusic();
|
||||
virtual void setVolume(uint16 param);
|
||||
private:
|
||||
|
|
|
@ -34,7 +34,7 @@ void MT32Music::passTimerFunc(void *param) {
|
|||
((MT32Music*)param)->timerCall();
|
||||
}
|
||||
|
||||
MT32Music::MT32Music(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) {
|
||||
MT32Music::MT32Music(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
|
||||
_driverFileBase = 60200;
|
||||
_midiDrv = pMidiDrv;
|
||||
int midiRes = _midiDrv->open();
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Sky {
|
|||
|
||||
class MT32Music : public MusicBase {
|
||||
public:
|
||||
MT32Music(MidiDriver *pMidiDrv, Disk *pDisk);
|
||||
MT32Music(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk);
|
||||
~MT32Music();
|
||||
private:
|
||||
static void passTimerFunc(void *param);
|
||||
|
|
|
@ -25,11 +25,13 @@
|
|||
#include "common/util.h"
|
||||
#include "common/endian.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
namespace Sky {
|
||||
|
||||
MusicBase::MusicBase(Disk *pDisk) {
|
||||
MusicBase::MusicBase(Audio::Mixer *pMixer, Disk *pDisk) {
|
||||
_musicData = NULL;
|
||||
_mixer = pMixer;
|
||||
_skyDisk = pDisk;
|
||||
_currentMusic = 0;
|
||||
_musicVolume = 127;
|
||||
|
@ -59,6 +61,8 @@ void MusicBase::loadSection(uint8 pSection) {
|
|||
}
|
||||
|
||||
bool MusicBase::musicIsPlaying() {
|
||||
if (_mixer->isSoundHandleActive(_musicHandle))
|
||||
return true;
|
||||
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
|
||||
if (_channels[cnt]->isActive())
|
||||
return true;
|
||||
|
@ -71,6 +75,8 @@ void MusicBase::stopMusic() {
|
|||
}
|
||||
|
||||
void MusicBase::stopMusicInternal() {
|
||||
_mixer->stopHandle(_musicHandle);
|
||||
|
||||
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
|
||||
delete _channels[cnt];
|
||||
_numberOfChannels = 0;
|
||||
|
@ -94,18 +100,51 @@ void MusicBase::loadNewMusic() {
|
|||
|
||||
_currentMusic = _onNextPoll.musicToProcess;
|
||||
|
||||
if (_currentMusic != 0) {
|
||||
musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1);
|
||||
musicPos += _musicDataLoc + ((_currentMusic - 1) << 1);
|
||||
musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc;
|
||||
if (_currentMusic == 0)
|
||||
return;
|
||||
|
||||
_musicTempo0 = _musicData[musicPos];
|
||||
_musicTempo1 = _musicData[musicPos+1];
|
||||
|
||||
setupChannels(_musicData + musicPos + 2);
|
||||
|
||||
updateTempo();
|
||||
// Try playing digital audio first (from the Music Enhancement Project).
|
||||
// TODO: This always prefers digital music over the MIDI music types!
|
||||
uint8 section = _currentSection;
|
||||
uint8 song = _currentMusic;
|
||||
// handle duplicates
|
||||
if ((section == 2 && song == 1) || (section == 5 && song == 1)) {
|
||||
section = 1;
|
||||
song = 1;
|
||||
} else if ((section == 2 && song == 4) || (section == 5 && song == 4)) {
|
||||
section = 1;
|
||||
song = 4;
|
||||
} else if (section == 5 && song == 6) {
|
||||
section = 4;
|
||||
song = 4;
|
||||
}
|
||||
Common::String trackName = Common::String::format("music_%d%02d", section, song);
|
||||
Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName);
|
||||
if (stream) {
|
||||
// not all tracks should loop
|
||||
bool loops = true;
|
||||
if ((section == 1 && song == 1) || (section == 1 && song == 4)
|
||||
|| (section == 2 && song == 1) || (section == 2 && song == 4)
|
||||
|| (section == 4 && song == 2) || (section == 4 && song == 3)
|
||||
|| (section == 4 && song == 5) || (section == 4 && song == 6)
|
||||
|| (section == 4 && song == 11) || (section == 5 && song == 1)
|
||||
|| (section == 5 && song == 3) || (section == 5 && song == 4))
|
||||
loops = false;
|
||||
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, Audio::makeLoopingAudioStream(stream, loops ? 0 : 1));
|
||||
return;
|
||||
}
|
||||
|
||||
// no digital audio, resort to MIDI playback
|
||||
musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1);
|
||||
musicPos += _musicDataLoc + ((_currentMusic - 1) << 1);
|
||||
musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc;
|
||||
|
||||
_musicTempo0 = _musicData[musicPos];
|
||||
_musicTempo1 = _musicData[musicPos+1];
|
||||
|
||||
setupChannels(_musicData + musicPos + 2);
|
||||
|
||||
updateTempo();
|
||||
}
|
||||
|
||||
void MusicBase::pollMusic() {
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "common/scummsys.h"
|
||||
#include "common/mutex.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
|
||||
namespace Sky {
|
||||
|
||||
class Disk;
|
||||
|
@ -48,7 +50,7 @@ private:
|
|||
|
||||
class MusicBase {
|
||||
public:
|
||||
MusicBase(Disk *pDisk);
|
||||
MusicBase(Audio::Mixer *pMixer, Disk *pDisk);
|
||||
virtual ~MusicBase();
|
||||
void loadSection(uint8 pSection);
|
||||
void startMusic(uint16 param);
|
||||
|
@ -60,6 +62,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
Audio::Mixer *_mixer;
|
||||
Disk *_skyDisk;
|
||||
uint8 *_musicData;
|
||||
|
||||
|
@ -75,6 +78,7 @@ protected:
|
|||
Actions _onNextPoll;
|
||||
ChannelBase *_channels[10];
|
||||
Common::Mutex _mutex;
|
||||
Audio::SoundHandle _musicHandle;
|
||||
|
||||
virtual void setupPointers() = 0;
|
||||
virtual void setupChannels(uint8 *channelData) = 0;
|
||||
|
|
|
@ -268,9 +268,9 @@ Common::Error SkyEngine::init() {
|
|||
} else {
|
||||
_systemVars.systemFlags |= SF_ROLAND;
|
||||
if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"))
|
||||
_skyMusic = new MT32Music(MidiDriver::createMidi(dev), _skyDisk);
|
||||
_skyMusic = new MT32Music(MidiDriver::createMidi(dev), _mixer, _skyDisk);
|
||||
else
|
||||
_skyMusic = new GmMusic(MidiDriver::createMidi(dev), _skyDisk);
|
||||
_skyMusic = new GmMusic(MidiDriver::createMidi(dev), _mixer, _skyDisk);
|
||||
}
|
||||
|
||||
if (isCDVersion()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue