aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/music.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/music.h')
-rw-r--r--engines/gob/music.h131
1 files changed, 76 insertions, 55 deletions
diff --git a/engines/gob/music.h b/engines/gob/music.h
index 89d8e2933c..0ddcab79fd 100644
--- a/engines/gob/music.h
+++ b/engines/gob/music.h
@@ -36,15 +36,24 @@ namespace Gob {
class GobEngine;
-// Emulation of the "Paula" Amiga music chip
-class Paula: public Audio::AudioStream {
+/**
+ * Emulation of the "Paula" Amiga music chip
+ * The interrupt frequency specifies the number of mixed wavesamples between
+ * calls of the interrupt method
+ */
+class Paula : public Audio::AudioStream {
public:
- Paula(GobEngine *vm, bool stereo = false, int intFreq = 0);
+ Paula(bool stereo = false, int rate = 44100, int interruptFreq = 0);
~Paula();
bool playing() const { return _playing; }
void setInterruptFreq(int freq) { _intFreq = freq; }
- void clearVoice(int voice);
+ void setPanning(byte voice, byte panning)
+ {
+ if (voice < 4)
+ _voice[voice].panning = panning;
+ }
+ void clearVoice(byte voice);
void clearVoices() { int i; for (i = 0; i < 4; i++) clearVoice(i); }
virtual void startPlay(void) {}
virtual void stopPlay(void) {}
@@ -65,7 +74,7 @@ protected:
int16 period;
byte volume;
double offset;
- byte panning; // For stereo mixing; 0: left, 1: right
+ byte panning; // For stereo mixing: 0 = far left, 255 = far right
} _voice[4];
int _rate;
@@ -74,34 +83,31 @@ protected:
bool _stereo;
bool _end;
bool _playing;
-
- GobEngine *_vm;
+ Common::Mutex _mutex;
void mix(int16 *&buf, int8 data, int voice) {
if (_stereo) {
- *buf++ += _voice[voice].panning == 0 ? 2 * _voice[voice].volume * data : 0;
- *buf++ += _voice[voice].panning == 1 ? 2 * _voice[voice].volume * data : 0;
+ *buf++ += (((int32) data) * _voice[voice].volume *
+ (255 - _voice[voice].panning)) >> 7;
+ *buf++ += (((int32) data) * _voice[voice].volume *
+ (_voice[voice].panning)) >> 7;
} else
*buf++ += _voice[voice].volume * data;
}
virtual void interrupt(void) {};
};
+/** A player for the Infogrames/RobHubbard2 format */
class Infogrames : public Paula {
public:
class Instruments {
public:
- struct Sample {
- int8 *data;
- int8 *dataRepeat;
- uint32 length;
- uint32 lengthRepeat;
- } _samples[32];
-
- uint8 _count;
- int8 *_sampleData;
-
Instruments();
+ template<typename T> Instruments(T ins) {
+ init();
+ bool result = load(ins);
+ assert(result);
+ }
~Instruments();
bool load(Common::SeekableReadStream &ins);
@@ -112,17 +118,39 @@ public:
return load(f);
return false;
}
+ void unload(void);
+
+ uint8 getCount(void) const { return _count; }
+
+ protected:
+ struct Sample {
+ int8 *data;
+ int8 *dataRepeat;
+ uint32 length;
+ uint32 lengthRepeat;
+ } _samples[32];
+
+ uint8 _count;
+ int8 *_sampleData;
+
+ void init();
+
+ friend class Infogrames;
};
- Infogrames(GobEngine *vm, bool stereo = false);
+ Infogrames(Instruments &ins, bool stereo = false, int rate = 44100);
~Infogrames();
Instruments *getInstruments(void) const { return _instruments; }
bool getRepeating(void) const { return _repCount != 0; }
void setRepeating (int32 repCount) { _repCount = repCount; }
- void restart(void) { if (!_data || !_instruments) return; init(); _end = false; }
- virtual void startPlay(void) { if (_data && _instruments) { restart(); _playing = true; } }
- virtual void stopPlay(void) { _playing = false; }
+ virtual void startPlay(void) { _playing = true;}
+ virtual void stopPlay(void)
+ {
+ _mutex.lock();
+ _playing = false;
+ _mutex.unlock();
+ }
virtual void pausePlay(bool pause) { _playing = !pause; }
bool load(Common::SeekableReadStream &dum);
@@ -133,17 +161,8 @@ public:
return load(f);
return false;
}
- void unload(bool destroyInstruments = false);
- template<typename T> bool loadInstruments(T ins) {
- unload(true);
- _instruments = new Instruments();
- if (!_instruments->load(ins)) {
- delete _instruments;
- _instruments = 0;
- return false;
- }
- return true;
- }
+ void unload(void);
+ void restart(void) { if (_data) { stopPlay(); init(); startPlay(); } }
protected:
Instruments *_instruments;
@@ -153,44 +172,38 @@ protected:
byte *_data;
int32 _repCount;
- uint16 _volume;
- int16 _period;
- byte *_volSlideBlocks;
- byte *_periodSlideBlocks;
byte *_subSong;
byte *_cmdBlocks;
- uint8 _sample;
+ byte *_volSlideBlocks;
+ byte *_periodSlideBlocks;
uint8 _speedCounter;
uint8 _speed;
- uint8 _newVol;
- uint8 _field_1E;
+
+ uint16 _volume;
+ int16 _period;
+ uint8 _sample;
struct Slide {
- int16 finetuneNeg;
- int16 finetunePos;
byte *data;
int8 amount;
uint8 dataOffset;
- uint8 flags; // 0: Apply finetune modifier, 2: Don't slide, 7: Continuous
+ int16 finetuneNeg;
+ int16 finetunePos;
uint8 curDelay1;
uint8 curDelay2;
+ uint8 flags; // 0: Apply finetune modifier, 2: Don't slide, 7: Continuous
};
struct Channel {
byte *cmdBlockIndices;
- byte *cmds;
byte *cmdBlocks;
+ byte *cmds;
+ uint8 ticks;
+ uint8 tickCount;
Slide volSlide;
Slide periodSlide;
- int16 curPeriod;
int16 period;
- uint16 curCmdBlock;
- uint16 flags; // 0: Need init, 5: Loop cmdBlocks, 6: Ignore channel
- uint8 ticks;
- uint8 tickCount;
int8 periodMod;
- uint8 field_2B;
- uint8 field_2C;
- uint8 field_2F;
+ uint8 flags; // 0: Need init, 5: Loop cmdBlocks, 6: Ignore channel
} _chn[4];
void init(void);
@@ -211,8 +224,13 @@ public:
bool getRepeating(void) const { return _repCount != 0; }
void setRepeating (int32 repCount) { _repCount = repCount; }
int getIndex(void) const { return _index; }
- virtual void startPlay(void);
- virtual void stopPlay(void) { _mutex.lock(); _playing = false; _mutex.unlock(); }
+ virtual void startPlay(void) { if (_data) _playing = true; }
+ virtual void stopPlay(void)
+ {
+ _mutex.lock();
+ _playing = false;
+ _mutex.unlock();
+ }
virtual void playTrack(const char *trackname);
virtual void playBgMusic(void);
virtual bool load(const char *filename);
@@ -265,6 +283,9 @@ protected:
void pollMusic(void);
};
+/**
+ * A dummy class for the "null" sound driver
+ */
class Adlib_Dummy: public Adlib {
public:
Adlib_Dummy(GobEngine *vm) : Adlib(vm) {}