1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 // Music class
24 
25 #ifndef TINSEL_MUSIC_H
26 #define TINSEL_MUSIC_H
27 
28 #include "audio/midiplayer.h"
29 #include "audio/audiostream.h"
30 #include "audio/mixer.h"
31 #include "common/mutex.h"
32 
33 class MidiParser;
34 
35 namespace Tinsel {
36 
37 bool PlayMidiSequence(		// Plays the specified MIDI sequence through the sound driver
38 	uint32 dwFileOffset,		// handle of MIDI sequence data
39 	bool bLoop);			// Whether to loop the sequence
40 
41 bool MidiPlaying();		// Returns TRUE if a Midi tune is currently playing
42 
43 bool StopMidi();		// Stops any currently playing midi
44 
45 void SetMidiVolume(		// Sets the volume of the MIDI music. Returns the old volume
46 	int vol);		// new volume - 0..MAXMIDIVOL
47 
48 int GetMidiVolume();
49 
50 void OpenMidiFiles();
51 void DeleteMidiBuffer();
52 
53 void CurrentMidiFacts(SCNHANDLE	*pMidi, bool *pLoop);
54 void RestoreMidiFacts(SCNHANDLE	Midi, bool Loop);
55 
56 int GetTrackNumber(SCNHANDLE hMidi);
57 SCNHANDLE GetTrackOffset(int trackNumber);
58 
59 void dumpMusic();
60 
61 class MidiMusicPlayer : public Audio::MidiPlayer {
62 public:
63 	MidiMusicPlayer(TinselEngine *vm);
64 
65 	virtual void setVolume(int volume);
66 
67 	void playMIDI(uint32 size, bool loop);
68 
69 //	void stop();
70 	void pause();
71 	void resume();
72 
73 	// MidiDriver_BASE interface implementation
74 	virtual void send(uint32 b);
75 
76 	// The original sets the "sequence timing" to 109 Hz, whatever that
77 	// means. The default is 120.
getBaseTempo()78 	uint32 getBaseTempo()	{ return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
79 
80 	bool _milesAudioMode;
81 
82 private:
83 	void playXMIDI(uint32 size, bool loop);
84 	void playSEQ(uint32 size, bool loop);
85 };
86 
87 class PCMMusicPlayer : public Audio::AudioStream {
88 public:
89 	PCMMusicPlayer();
90 	~PCMMusicPlayer();
91 
92 	bool isPlaying() const;
93 
94 	bool isDimmed() const;
95 
96 	void getTunePlaying(void *voidPtr, int length);
97 	void restoreThatTune(void *voidPtr);
98 
99 	void setMusicSceneDetails(SCNHANDLE hScript, SCNHANDLE hSegment, const char *fileName);
100 
101 	void setVolume(int volume);
102 
103 	void startPlay(int id);
104 	void stopPlay();
105 
106 	bool getMusicTinselDimmed() const;
107 	void dim(bool bTinselDim);
108 	void unDim(bool bTinselUnDim);
109 	void dimIteration();
110 
111 	void startFadeOut(int ticks);
112 	void fadeOutIteration();
113 
114 	int readBuffer(int16 *buffer, const int numSamples);
isStereo()115 	bool isStereo() const { return false; }
endOfData()116 	bool endOfData() const { return _end; }
endOfStream()117 	bool endOfStream() const { return false; }
getRate()118 	int getRate() const { return 22050; }
119 
120 protected:
121 	enum State {
122 		S_IDLE,
123 		S_NEW,
124 		S_MID,
125 		S_END1,
126 		S_END2,
127 		S_END3,
128 		S_NEXT,
129 		S_STOP
130 	};
131 
132 	struct MusicSegment {
133 		uint32 numChannels;
134 		uint32 bitsPerSec;
135 		uint32 bitsPerSample;
136 		uint32 sampleLength;
137 		uint32 sampleOffset;
138 	};
139 
140 	Audio::SoundHandle _handle;
141 	Audio::AudioStream *_curChunk;
142 	Common::Mutex _mutex;
143 
144 	bool _end;
145 
146 	int _silenceSamples;
147 
148 	State _state, _mState;
149 	bool _forcePlay;
150 	int32 _scriptNum;
151 	int32 _scriptIndex;
152 	SCNHANDLE _hScript;
153 	SCNHANDLE _hSegment;
154 	Common::String _filename;
155 
156 	uint8 _volume;
157 
158 	bool _dimmed;
159 	bool _dimmedTinsel;
160 	uint8 _dimmedVolume;
161 	int _dimIteration;
162 	int _dimPosition;
163 
164 	uint8 _fadeOutVolume;
165 	int _fadeOutIteration;
166 
167 	void play();
168 	void stop();
169 	void setVol(uint8 volume);
170 
171 	bool getNextChunk();
172 };
173 
174 } // End of namespace Tinsel
175 
176 #endif
177