ScummVM API documentation
sound.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef SWORD1_SOUND_H
23 #define SWORD1_SOUND_H
24 
25 #include "sword1/object.h"
26 #include "sword1/sworddefs.h"
27 
28 #include "common/file.h"
29 #include "common/mutex.h"
30 #include "common/random.h"
31 #include "common/timer.h"
32 #include "common/util.h"
33 
34 #include "audio/mixer.h"
35 #include "audio/audiostream.h"
36 
37 namespace Audio {
38 class Mixer;
39 }
40 
41 namespace Sword1 {
42 
43 #define TOTAL_FX_PER_ROOM 7 // total loop & random fx per room (see fx_list.c)
44 #define MAX_ROOMS_PER_FX 7 // max no. of rooms in the fx's room,vol list
45 #define MAX_FXQ_LENGTH 32 // max length of sound queue - ie. max number of fx that can be stored up/playing together
46 
47 #define FX_SPOT 1
48 #define FX_LOOP 2
49 #define FX_RANDOM 3
50 
51 struct QueueElement {
52  uint32 id, delay;
53  Audio::SoundHandle handle;
54 
55  void reset() {
56  id = 0, delay = 0;
57  handle = Audio::SoundHandle();
58  }
59 };
60 
61 struct RoomVol {
62  int32 roomNo, leftVol, rightVol;
63 };
64 
65 struct SampleId {
66  byte cluster;
67  byte idStd;
68  byte idWinDemo;
69 };
70 
71 struct FxDef {
72  SampleId sampleId;
73  uint32 type, delay;
74  RoomVol roomVolList[MAX_ROOMS_PER_FX];
75 };
76 
77 class ResMan;
78 class SwordEngine;
79 
80 #define MUSIC_UNDERSCORE 50
81 #define NEG_MOUTH_THRESHOLD -750
82 #define POS_MOUTH_THRESHOLD 750
83 #define MAX_FX 4
84 #define MAX_MUSIC 2
85 #define S_STATUS_FINISHED 1
86 #define S_STATUS_RUNNING 0
87 #define MUSIC_BUFFER_SIZE 0x2000
88 #define TOTAL_TUNES 270
89 #define DEFAULT_SAMPLE_RATE 11025
90 
91 enum CowMode {
92  CowWave = 0,
93  CowFLAC,
94  CowVorbis,
95  CowMP3,
96  CowDemo,
97  CowPSX
98 };
99 
100 enum MusCompMode {
101  MusWav = 0,
102  MusAif,
103  MusFLAC,
104  MusVorbis,
105  MusMP3,
106  MusPSX
107 };
108 
109 class Sound {
110  friend class SwordConsole;
111  friend class Control;
112 public:
113  Sound(Audio::Mixer *mixer, SwordEngine *vm, ResMan *pResMan);
114  ~Sound();
115 
116  void newScreen(uint32 screen);
117  void closeCowSystem();
118 
119  void engine();
120 
121  void checkSpeechFileEndianness();
122  double endiannessHeuristicValue(int16* data, uint32 dataSize, uint32 &maxSamples);
123 
124  void installFadeTimer();
125  void uninstallFadeTimer();
126 
127  void playSample(int32 fxNo);
128  void stopSample(int32 fxNo);
129  void setFXVolume(byte targetVolume, int handleIdx);
130  void clearAllFx();
131  int addToQueue(uint32 fxNo);
132  void removeFromQueue(uint32 fxNo);
133 
134  void startSpeech(uint16 roomNo, uint16 localNo);
135  bool amISpeaking();
136  int32 checkSpeechStatus();
137  void playSpeech();
138  void stopSpeech();
139 
140  void streamMusicFile(int32 tuneId, int32 looped);
141  void updateMusicStreaming();
142  void setCrossFadeIncrement();
143 
144  void fadeMusicDown(int32 rate);
145  void fadeFxDown(int32 rate);
146  void fadeFxUp(int32 rate);
147 
148  void pauseSpeech();
149  void unpauseSpeech();
150  void pauseMusic();
151  void unpauseMusic();
152  void pauseFx();
153  void unpauseFx();
154 
155  void getVolumes();
156  void setVolumes();
157  byte clampVolume(int32 volume);
158 
159  Common::Mutex _soundMutex;
160  Audio::Mixer *_mixer;
161 
162  // Handles for external volume changes (control panel)
163  uint32 _volFX[2] = { 0, 0 };
164  uint32 _volSpeech[2] = { 0, 0 };
165  uint32 _volMusic[2] = { 0, 0 };
166 
167  // Volume fading variables
168  int32 _fxCount = 0;
169  int32 _fxFadingFlag = 0;
170  int32 _fxFadingRate = 0;
171  int32 _fxFadeVolume[2] = { 0, 0 };
172  int32 _musicFadeVolume[2] = { 0, 0 };
173 
174  // Sound FX information
175  bool _fxSampleBusy[MAX_FX] = { false, false, false, false };
176 
177  // Speech data
178  byte *_speechSample = nullptr;
179 
180 private:
181  struct WaveHeader {
182  uint32 riffTag;
183  uint32 riffSize;
184  uint32 waveTag;
185  uint32 fmtTag;
186  uint32 fmtSize;
187 
188  // Format subchunk
189  uint16 wFormatTag;
190  uint16 wChannels;
191  uint32 dwSamplesPerSec;
192  uint32 dwAvgBytesPerSec;
193  uint16 wBlockAlign;
194  uint16 wBitsPerSample;
195  uint32 dwDataTag;
196  uint32 dwDataSize;
197  };
198 
199  void initCowSystem();
200 
201  uint32 getSampleId(int32 fxNo);
202  void playFX(int32 fxID, int32 type, uint8 *wavData, uint32 vol[2]);
203  void stopFX(int32 fxID);
204  int32 checkSampleStatus(int32 id);
205 
206  bool expandSpeech(byte *src, byte *dst, uint32 dstSize,
207  bool *endiannessCheck = nullptr, uint32 *sizeForEndiannessCheck = nullptr);
208  int32 getSpeechSize(byte *compData, uint32 compSize);
209 
210  bool prepareMusicStreaming(const Common::Path &filename, int newHandleId, int32 tuneId,
211  uint32 volume, int8 pan, MusCompMode assignedMode);
212  void serveSample(Common::File *file, int32 i);
213  void reduceMusicVolume();
214  void restoreMusicVolume();
215 
216  int8 scalePan(int pan); // From 0,127 to -127,127
217 
218  Common::File _cowFile;
219  uint32 *_cowHeader;
220  uint32 _cowHeaderSize;
221  uint8 _currentCowFile;
222  CowMode _cowMode;
224 
225  QueueElement _fxQueue[MAX_FXQ_LENGTH];
226  uint8 _endOfQueue;
227  SwordEngine *_vm;
228  ResMan *_resMan;
229 
230  bool _bigEndianSpeech;
231  static const char _musicList[270];
232  static const uint16 _roomsFixedFx[TOTAL_ROOMS][TOTAL_FX_PER_ROOM];
233  static const FxDef _fxList[312];
234  static const char _tuneList[TOTAL_TUNES][8]; // In staticres.cpp
235 
236  // Volume fading variables
237  bool _crossFadeIncrement = false;
238 
239  // Speech variables
240  int32 _speechLipsyncCounter = 0;
241  int32 _speechSize = 0;
242  bool _speechSampleBusy = false;
243 
244  // Sound handles
245  Audio::SoundHandle _hSampleFX[MAX_FX];
246  Audio::SoundHandle _hSampleSpeech;
247  Audio::SoundHandle _hSampleMusic[MAX_MUSIC];
248 
249  // Music stream information
250  bool _musicStreamPlaying[MAX_MUSIC] = { false, false };
251  bool _streamLoopingFlag[MAX_MUSIC] = { false, false };
252  int32 _musicStreamFading[MAX_MUSIC] = { 0, 0 };
253  MusCompMode _musicStreamFormat[MAX_MUSIC] = { MusWav, MusWav };
254  Audio::QueuingAudioStream *_musicOutputStream[MAX_MUSIC] = { nullptr, nullptr };
255  Audio::RewindableAudioStream *_compressedMusicStream[MAX_MUSIC] = { nullptr, nullptr };
256  Common::File _musicFile[MAX_MUSIC];
257 
258  // Sound FX information
259  int32 _fxSampleId[MAX_FX] = { 0, 0, 0, 0 };
260 
261  // Pause variables
262  bool _speechPaused = false;
263  bool _fxPaused[MAX_FX] = { false, false, false, false };
264  bool _musicPaused[MAX_MUSIC] = { false, false };
265 };
266 
267 } // End of namespace Sword1
268 
269 #endif // SOUND_H
Definition: sound.h:61
Definition: sound.h:71
Definition: sword1.h:104
Definition: sound.h:109
Definition: random.h:44
Definition: sound.h:65
Definition: resman.h:65
Definition: path.h:52
Definition: animation.h:38
Definition: console.h:31
Definition: mixer.h:49
Definition: mixer.h:59
Definition: file.h:47
Definition: sound.h:51
Definition: mutex.h:67
Definition: audiostream.h:109
Definition: audiostream.h:370
Definition: control.h:120
Definition: system.h:38