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
40#include "audio/audiostream.h"
41#include "audio/decoders/raw.h"
42#include "audio/decoders/wave.h"
43#include "audio/decoders/mp3.h"
45#include "audio/decoders/flac.h"
46
47namespace 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
69struct HESoundModifiers;
70struct HESpoolingMusicItem;
71class ScummEngine_v60he;
72
74 int frequencyShift;
75 int pan;
76 int volume;
77};
78
80protected:
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
91public:
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
111 clearChannelData();
112 }
113
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
125class HEMixer {
126protected:
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
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
160public:
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: mixer.h:70
Definition: audiostream.h:370
Definition: audiostream.h:212
Definition: mixer.h:49
Definition: file.h:47
Definition: mixer_he.h:79
Definition: mixer_he.h:125
Definition: intern_he.h:53
Definition: scumm.h:536
Definition: actor.h:30
Definition: mixer_he.h:81
Definition: mixer_he.h:136
Definition: sound_he.h:109
Definition: sound_he.h:136
Definition: mixer_he.h:73