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