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:
Alyssa Milburn 2011-11-14 20:39:00 +01:00 committed by Filippos Karapetis
parent ef58cc326e
commit 3d83111f62
9 changed files with 62 additions and 22 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -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:

View file

@ -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();

View file

@ -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);

View file

@ -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,7 +100,41 @@ void MusicBase::loadNewMusic() {
_currentMusic = _onNextPoll.musicToProcess;
if (_currentMusic != 0) {
if (_currentMusic == 0)
return;
// 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;
@ -106,7 +146,6 @@ void MusicBase::loadNewMusic() {
updateTempo();
}
}
void MusicBase::pollMusic() {
Common::StackLock lock(_mutex);

View file

@ -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;

View file

@ -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()) {