aboutsummaryrefslogtreecommitdiff
path: root/engines/lure/sound.h
blob: cfe0739298c34f4110a818d6b3afce76ce5b3e57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2005-2006 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *
 */

#ifndef LURE_SOUND_H
#define LURE_SOUND_H

#include "lure/luredefs.h"
#include "lure/disk.h"
#include "lure/memory.h"

#include "common/singleton.h"
#include "sound/mididrv.h"
#include "sound/mixer.h"

class MidiParser;

namespace Lure {

#define NUM_CHANNELS_OUTER 8
#define NUM_CHANNELS_INNER 16

struct ChannelEntry {
	MidiChannel *midiChannel;
	byte volume;
};

class MidiMusic: public MidiDriver {
private:
	uint8 _soundNumber;
	uint8 _channelNumber;
	uint8 _numChannels;
	byte _volume;
	MemoryBlock *_decompressedSound;
	uint8 *_soundData;
	uint8 _soundSize;
	MidiDriver *_driver;
	MidiParser *_parser;
	ChannelEntry *_channels;
	bool _isPlaying;
	bool _nativeMT32;

	void queueUpdatePos();
	uint8 randomQueuePos();
	uint32 songOffset(uint16 songNum) const;
	uint32 songLength(uint16 songNum) const;

	bool _passThrough;

public:
	MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS_INNER], 
		uint8 channelNum, uint8 soundNum, void *soundData, uint32 size);
	~MidiMusic();
	void setVolume(int volume);
	int getVolume()	{ return _volume; }

	void hasNativeMT32(bool b)	{ _nativeMT32 = b; }
	void playSong(uint16 songNum);
	void stopSong() { stopMusic(); }
	void playMusic();
	void stopMusic();
	void queueTuneList(int16 tuneList);
	bool queueSong(uint16 songNum);
	void setPassThrough(bool b) { _passThrough = b; }
	void toggleVChange();

	//MidiDriver interface implementation
	int open();
	void close();
	void send(uint32 b);
	void onTimer();

	void metaEvent(byte type, byte *data, uint16 length);

	void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }
	uint32 getBaseTempo(void)	{ return _driver ? _driver->getBaseTempo() : 0; }

	//Channel allocation functions
	MidiChannel *allocateChannel()		{ return 0; }
	MidiChannel *getPercussionChannel()	{ return 0; }

	uint8 channelNumber() { return _channelNumber; }
	uint8 soundNumber() { return _soundNumber; }
	bool isPlaying() { return _isPlaying; }
};

class SoundManager: public Common::Singleton<SoundManager> {
private:
	// Outer sound interface properties
	MemoryBlock *_descs;
	MemoryBlock *_soundData;
	uint8 _soundsTotal;
	int _numDescs;
	SoundDescResource *soundDescs() { return (SoundDescResource *) _descs->data(); }
	MidiDriver *_driver;
	ManagedList<SoundDescResource *> _activeSounds;
	ManagedList<MidiMusic *> _playingSounds;
	ChannelEntry _channelsInner[NUM_CHANNELS_INNER];
	bool _channelsInUse[NUM_CHANNELS_OUTER];
	bool _isPlaying;
	bool _nativeMT32;

	// Internal support methods
	void bellsBodge();
	void musicInterface_TidySounds();
	static void onTimer(void *data);
public:
	SoundManager();
	~SoundManager();

	void loadSection(uint16 sectionId);
	void killSounds();
	void addSound(uint8 soundIndex, bool tidyFlag = true);
	void addSound2(uint8 soundIndex);
	void stopSound(uint8 soundIndex);
	void killSound(uint8 soundNumber);
	void setVolume(uint8 soundNumber, uint8 volume);
	void setVolume(uint8 volume);
	void tidySounds();
	SoundDescResource *findSound(uint8 soundNumber);
	void removeSounds();
	void restoreSounds();
	void fadeOut();

	// The following methods implement the external sound player module
	void musicInterface_Initialise();
	void musicInterface_Play(uint8 soundNumber, uint8 channelNumber);
	void musicInterface_Stop(uint8 soundNumber);
	bool musicInterface_CheckPlaying(uint8 soundNumber);
	void musicInterface_SetVolume(uint8 channelNum, uint8 volume);
	void musicInterface_KillAll();
	void musicInterface_ContinuePlaying();
	void musicInterface_TrashReverb();
};

} // End of namespace Lure

#define Sound (::Lure::SoundManager::instance())

#endif