ScummVM API documentation
mixer_he.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 SCUMM_HE_MIXER_HE_H
23 #define SCUMM_HE_MIXER_HE_H
24 
25 #include "scumm/he/sound_he.h"
26 #include "scumm/he/intern_he.h"
27 #include "scumm/resource.h"
28 
29 #include "common/util.h"
30 #include "common/file.h"
31 #include "common/debug.h"
32 #include "common/memstream.h"
33 
34 #include "audio/decoders/adpcm.h"
35 #include "audio/audiostream.h"
36 #include "audio/decoders/raw.h"
37 #include "audio/decoders/wave.h"
38 #include "audio/decoders/mp3.h"
39 #include "audio/decoders/vorbis.h"
40 #include "audio/decoders/flac.h"
41 
42 namespace Scumm {
43 
44 #define CHANNEL_EMPTY_FLAGS (0 << 0)
45 #define CHANNEL_ACTIVE (1 << 0)
46 #define CHANNEL_FINISHED (1 << 1)
47 #define CHANNEL_LOOPING (1 << 2)
48 #define CHANNEL_LAST_CHUNK (1 << 3)
49 #define CHANNEL_SPOOLING (1 << 4)
50 #define CHANNEL_CALLBACK_EARLY (1 << 7)
51 #define CHANNEL_SOFT_REMIX (1 << 8)
52 
53 #define MIXER_MAX_CHANNELS 8
54 #define MIXER_PCM_CHUNK_SIZE 4096
55 #define MIXER_MAX_QUEUED_STREAMS 8
56 #define MIXER_DEFAULT_SAMPLE_RATE 11025
57 #define MIXER_SPOOL_CHUNK_SIZE (8 * 1024)
58 
59 #define MILES_MAX_CHANNELS 8
60 #define MILES_PCM_CHUNK_SIZE 4096u
61 #define MILES_IMA_ADPCM_PER_FRAME_CHUNKS_NUM 4u
62 #define MILES_MAX_QUEUED_STREAMS 16
63 
64 struct HESoundModifiers;
65 struct HESpoolingMusicItem;
66 class ScummEngine_v60he;
67 
69  int frequencyShift;
70  int pan;
71  int volume;
72 };
73 
75 protected:
76  struct MilesStream {
77  Audio::QueuingAudioStream *streamObj = nullptr;
78  Audio::SoundHandle streamHandle;
79  bool loopFlag = false;
80  Common::File *fileHandle = nullptr;
81  uint32 dataLength = 0;
82  uint32 curDataPos = 0;
83  uint32 dataOffset = 0;
84  };
85 
86 public:
87  MilesModifiers _modifiers;
88  MilesStream _stream;
89  int _baseFrequency;
90  Audio::SoundHandle _audioHandle;
91  bool _audioHandleActive = false;
92  uint32 _lastPlayPosition;
93  uint32 _playFlags;
94  int _dataOffset;
95  int _globType;
96  int _globNum;
97 
98  uint16 _blockAlign = 0;
99  uint16 _numChannels = 1;
100  uint16 _bitsPerSample = 8;
101  uint16 _dataFormat = 1;
102 
103  bool _isUsingStreamOverride = false;
104 
105  HEMilesChannel() {
106  clearChannelData();
107  }
108 
109  ~HEMilesChannel() {
110  clearChannelData();
111  }
112 
113  void startSpoolingChannel(const char *filename, long offset, int flags, HESoundModifiers modifiers, Audio::Mixer *mixer);
114  void clearChannelData();
115  void closeFileHandle();
116  void serviceStream();
117  byte getOutputFlags();
118 };
119 
120 class HEMixer {
121 protected:
122  ScummEngine *_vm;
123  Audio::Mixer *_mixer;
124  bool _useMilesSoundSystem = false;
125  bool _mixerPaused = false;
126  int _pauseCount = 0;
127  Common::HashMap<int32, int32> _offsetsToSongId;
128 
129  HEMilesChannel _milesChannels[MILES_MAX_CHANNELS];
130 
131  struct HEMixerChannel {
132  Audio::SoundHandle handle;
133  Audio::QueuingAudioStream *stream = nullptr;
134  Common::File *fileHandle = nullptr;
135  int number = 0;
136  int volume = 0;
137  int frequency = 0;
138  int globType = 0;
139  int globNum = 0;
140  int callbackID = 0;
141  int endSampleAdjustment = 0;
142  uint32 lastReadPosition = 0;
143  uint32 initialSpoolingFileOffset = 0;
144  uint32 sampleLen = 0;
145  uint32 dataOffset = 0;
146  uint32 flags = 0;
147  bool callbackOnNextFrame = false;
148  bool isUsingStreamOverride = false;
149  byte *residualData = nullptr; // For early callbacks
150  };
151 
152  HEMixerChannel _mixerChannels[MIXER_MAX_CHANNELS];
153 
154 
155 public:
156  HEMixer(Audio::Mixer *mixer, ScummEngine_v60he *vm, bool useMiles);
157  ~HEMixer();
158 
159  bool initSoftMixerSubSystem();
160  void deinitSoftMixerSubSystem();
161  bool stopChannel(int channel);
162  void stopAllChannels();
163  bool pauseMixerSubSystem(bool paused);
164  void feedMixer();
165  bool changeChannelVolume(int channel, int volume, bool soft);
166  bool startChannelNew(
167  int channel, int globType, int globNum, uint32 soundData, uint32 offset,
168  int sampleLen, int frequency, int bitsPerSample, int sampleChannels,
169  const HESoundModifiers &modifiers, int callbackId, int32 flags, ...);
170  bool startChannel(
171  int channel, int globType, int globNum, uint32 sampleDataOffset,
172  int sampleLen, int frequency, int volume, int callbackId, int32 flags, ...);
173  bool startSpoolingChannel(
174  int channel, int song, Common::File &spoolingFile, int sampleLen, int frequency,
175  int volume, int callbackID, int32 flags);
176 
177  bool audioOverrideExists(int globNum, bool justGetInfo,
178  int *duration = nullptr, Audio::SeekableAudioStream **outStream = nullptr);
179 
180  void setSpoolingSongsTable(HESpoolingMusicItem *heSpoolingMusicTable, int32 tableSize);
181  int32 matchOffsetToSongId(int32 offset);
182 
183  /* --- MILES MIXER CODE --- */
184  bool isMilesActive();
185  void milesStartSpoolingChannel(int channel, const char *filename, long offset, int flags, HESoundModifiers modifiers);
186  bool milesStartChannel(
187  int channel, int globType, int globNum, uint32 sound_data, uint32 offset,
188  int sampleLen, int bitsPerSample, int sampleChannels,
189  int frequency, HESoundModifiers modifiers, int callbackID, uint32 flags, ...);
190  bool milesStopChannel(int channel);
191  void milesStopAllSounds();
192  void milesModifySound(int channel, int offset, HESoundModifiers modifiers, int flags);
193  void milesStopAndCallback(int channel, int messageId);
194  void milesFeedMixer();
195  void milesServiceAllStreams();
196  bool milesPauseMixerSubSystem(bool paused);
197  byte *milesGetAudioDataFromResource(int globType, int globNum, uint32 dataOffset, uint16 &compType, uint16 &blockAlign, uint32 &dataSize);
198 
199  /* --- SOFTWARE MIXER CODE --- */
200  bool mixerInitMyMixerSubSystem();
201  void mixerFeedMixer();
202  bool mixerIsMixerDisabled();
203  bool mixerStopChannel(int channel);
204  bool mixerStopAllSounds();
205  bool mixerChangeChannelVolume(int channel, int volume, bool soft);
206  bool mixerPauseMixerSubSystem(bool paused);
207  bool mixerStartChannel(
208  int channel, int globType, int globNum, uint32 sampleDataOffset,
209  int sampleLen, int frequency, int volume, int callbackID, uint32 flags, ...);
210  bool mixerStartSpoolingChannel(
211  int channel, int song, Common::File &sampleFileIOHandle, int sampleLen, int frequency,
212  int volume, int callbackID, uint32 flags);
213  byte mixerGetOutputFlags(bool is3DOMusic = false);
214 };
215 
216 } // End of namespace Scumm
217 
218 #endif
Definition: audiostream.h:212
Definition: scumm.h:518
Definition: intern_he.h:52
Definition: mixer.h:49
Definition: mixer.h:59
Definition: mixer_he.h:74
Definition: file.h:47
Definition: mixer_he.h:120
Definition: sound_he.h:109
Definition: audiostream.h:370
Definition: mixer_he.h:68
Definition: mixer_he.h:131
Definition: mixer_he.h:76
Definition: actor.h:30
Definition: sound_he.h:136