ScummVM API documentation
mac_sound_lowlevel.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_PLAYERS_MAC_SOUND_LOWLEVEL_H
23#define SCUMM_PLAYERS_MAC_SOUND_LOWLEVEL_H
24
25#include "audio/audiostream.h"
26#include "audio/mixer.h"
27#include "common/array.h"
28#include "common/func.h"
29
30namespace Scumm {
31
33public:
34 MacSoundDriver(Common::Mutex &mutex, uint32 deviceRate, int activeChannels, bool canInterpolate, bool internal16Bit) : _mutex(mutex),
35 _smpSize(internal16Bit ? 2 : 1), _smpMin(internal16Bit ? -32768 : -128), _smpMax(internal16Bit ? 32767 : 127) {
36 for (int i = 0; i < 4; ++i) {
37 _status[i].deviceRate = deviceRate;
38 _status[i].numExternalMixChannels = activeChannels;
39 _status[i].allowInterPolation = canInterpolate;
40 _status[i].flags = 0;
41 }
42 }
43 virtual ~MacSoundDriver() {}
44 virtual void feed(int8 *dst, uint32 byteSize, Audio::Mixer::SoundType type, bool expectStereo) = 0;
45
46 struct Status {
47 Status() : deviceRate(0), numExternalMixChannels(0), allowInterPolation(false), flags(0) {}
48 uint32 deviceRate;
49 int numExternalMixChannels;
50 bool allowInterPolation;
51 uint8 flags;
52 };
53 const Status &getStatus(Audio::Mixer::SoundType sndType = Audio::Mixer::kPlainSoundType) const { return _status[sndType]; }
54
55 enum StatusFlag : uint8 {
56 kStatusPlaying = 1 << 0,
57 kStatusOverflow = 1 << 1,
58 kStatusStartup = 1 << 2,
59 kStatusDone = 1 << 3,
60 kStatusDisabled = 1 << 7
61 };
62
63 void clearFlags(uint8 flags, Audio::Mixer::SoundType sndType = Audio::Mixer::kPlainSoundType) { _status[sndType].flags &= ~flags; }
64 void setFlags(uint8 flags, Audio::Mixer::SoundType sndType = Audio::Mixer::kPlainSoundType) { _status[sndType].flags |= flags; }
65
66protected:
67 Common::Mutex &_mutex;
68 const int _smpSize;
69 const int16 _smpMin;
70 const int16 _smpMax;
71 Status _status[4];
72};
73
74class MacSndChannel;
76public:
77 struct PCMSound {
78 PCMSound() : len(0), rate(0), loopst(0), loopend(0), baseFreq(0), stereo(false), enc(0) {}
79 PCMSound(Common::SharedPtr<const byte> a, uint32 b, uint32 c, uint32 d, uint32 e, byte f, byte g, bool h) : data(a), len(b), rate(c), loopst(d), loopend(e), baseFreq(f), enc(g), stereo(h) {}
81 uint32 len;
82 uint32 rate;
83 uint32 loopst;
84 uint32 loopend;
85 byte baseFreq;
86 byte enc;
87 bool stereo;
88 };
89
90 enum SynthType : byte {
91 kSquareWaveSynth = 1,
92 kWaveTableSynth = 3,
93 kSampledSynth = 5,
94 kIgnoreSynth = 0xff
95 };
96
97 enum ChanAttrib : byte {
98 kInitChanLeft = 2,
99 kInitChanRight = 3,
100 kWaveInitChannel0 = 4,
101 kWaveInitChannel1 = 5,
102 kWaveInitChannel2 = 6,
103 kWaveInitChannel3 = 7,
104 kNoInterp = 4,
105 kInitNoDrop = 8,
106 kInitMono = 0x80,
107 kInitStereo = 0xC0
108 };
109
110 enum ExecMode : byte {
111 kImmediate,
112 kEnqueue,
113 };
114
115 typedef int ChanHandle;
116
118 enum Flags : uint32 {
119 kBufferReady = 1,
120 kLastBufferLast = 4
121 };
122 DoubleBuffer(ChanHandle hdl, uint32 numframes) : numFrames(numframes), flags(0), data(0), chanHandle(hdl) {}
123 ~DoubleBuffer() { delete[] data; }
124 uint32 numFrames;
125 const ChanHandle chanHandle;
126 uint32 flags;
127 byte *data;
128 };
129
131 public:
132 virtual ~CallbackClient() {}
133 virtual void sndChannelCallback(uint16 arg1, const void *arg2) {}
134 virtual void dblBuffCallback(DoubleBuffer *dblBuffer) {}
135 };
138
139public:
140 MacLowLevelPCMDriver(Common::Mutex &mutex, uint32 deviceRate, bool internal16Bit);
141 ~MacLowLevelPCMDriver() override;
142
143 void feed(int8 *dst, uint32 byteSize, Audio::Mixer::SoundType type, bool expectStereo) override;
144
145 ChanHandle createChannel(Audio::Mixer::SoundType sndType, SynthType synthType, byte attributes, ChanCallback *callback);
146 void disposeChannel(ChanHandle handle);
147
148 void playSamples(ChanHandle handle, ExecMode mode, const PCMSound *snd);
149 void playNote(ChanHandle handle, ExecMode mode, uint8 note, uint16 duration);
150 void quiet(ChanHandle handle, ExecMode mode);
151 void flush(ChanHandle handle, ExecMode mode);
152 void wait(ChanHandle handle, ExecMode mode, uint16 duration);
153 void loadWaveTable(ChanHandle handle, ExecMode mode, const byte *data, uint16 dataSize);
154 void loadInstrument(ChanHandle handle, ExecMode mode, const PCMSound *snd);
155 void setTimbre(ChanHandle handle, ExecMode mode, uint16 timbre);
156 void callback(ChanHandle handle, ExecMode mode, uint16 arg1, const void *arg2);
157
158 bool playDoubleBuffer(ChanHandle handle, byte numChan, byte bitsPerSample, uint32 rate, DBCallback *callback, byte numMixChan = 1);
159
160 uint8 getChannelStatus(ChanHandle handle) const;
161 void clearChannelFlags(ChanHandle handle, uint8 flags);
162
163 static uint32 calcRate(uint32 outRate, uint32 factor, uint32 dataRate);
164
165private:
166 void updateStatus(Audio::Mixer::SoundType sndType);
167 MacSndChannel *findAndCheckChannel(ChanHandle h, const char *caller, byte reqSynthType) const;
168 MacSndChannel *findChannel(ChanHandle h) const;
170 int _numInternalMixChannels[4];
171 int32 *_mixBuffer = 0;
172 uint32 _mixBufferSize;
173};
174
176public:
177 virtual ~VblTaskClientDriver() {}
178 virtual void vblCallback() = 0;
179 virtual void generateData(int8 *dst, uint32 len, Audio::Mixer::SoundType type, bool expectStereo) const = 0;
180 virtual const MacSoundDriver::Status &getDriverStatus(Audio::Mixer::SoundType sndType) const = 0;
181};
182
184public:
185 MacPlayerAudioStream(VblTaskClientDriver *drv, uint32 scummVMOutputrate, bool stereo, bool interpolate, bool internal16Bit);
186 ~MacPlayerAudioStream() override;
187
188 void initBuffers(uint32 feedBufferSize);
189 void initDrivers();
190 void addVolumeGroup(Audio::Mixer::SoundType type);
191 void scaleVolume(uint upscale, uint downscale) { _upscale = upscale; _downscale = downscale; }
193 void setVblCallback(const CallbackProc *proc);
194 void clearBuffer();
195
196 void setMasterVolume(Audio::Mixer::SoundType type, uint16 vol);
197
198 // AudioStream interface
199 int readBuffer(int16 *buffer, const int numSamples) override;
200 bool isStereo() const override { return _isStereo; }
201 int getRate() const override { return _outputRate; }
202 bool endOfData() const override { return false; }
203
204private:
205 void generateData(int8 *dst, uint32 byteSize, Audio::Mixer::SoundType, bool expectStereo) const;
206 void runVblTask();
207
209 int _numGroups;
210 uint16 _upscale;
211 uint16 _downscale;
212
213 uint32 _vblSmpQty;
214 uint32 _vblSmpQtyRem;
215 uint32 _vblCountDown;
216 uint32 _vblCountDownRem;
217 const CallbackProc *_vblCbProc;
218
219 struct SmpBuffer {
220 SmpBuffer() : start(0), pos(0), end(0), volume(0), lastL(0), lastR(0), size(0), rateConvInt(0), rateConvFrac(0), rateConvAcc(-1), group(Audio::Mixer::kPlainSoundType) {}
221 int8 *start;
222 int8 *pos;
223 const int8 *end;
224 uint32 volume;
225 int32 lastL;
226 int32 lastR;
227 uint32 size;
228 uint32 rateConvInt;
229 uint32 rateConvFrac;
230 int32 rateConvAcc;
232 } *_buffers;
233
234 const uint32 _outputRate;
235 const uint8 _frameSize;
236 const bool _interp;
237 const int _smpInternalSize;
238
239 const bool _isStereo;
240};
241
243public:
244 // Construct from Mac resource stream
246 // Construct from Mac sound data buffer
247 MacSndResource(uint32 id, const byte *in, uint32 size);
248 ~MacSndResource() {}
249 const MacLowLevelPCMDriver::PCMSound *data() const { return &_snd; }
250 uint32 id() const { return _id; }
251 const char* name() { return _name.c_str(); }
252
253private:
254 uint32 _id;
255 Common::String _name;
257};
258
259extern const uint8 _fourToneSynthWaveForm[256];
260extern const uint32 _fourToneSynthWaveFormSize;
261
262} // End of namespace Scumm
263
264#endif
Definition: audiostream.h:50
SoundType
Definition: mixer.h:73
@ kPlainSoundType
Definition: mixer.h:74
Definition: func.h:452
Definition: mutex.h:67
Definition: stream.h:745
Definition: str.h:59
Definition: mac_sound_lowlevel.h:130
Definition: mac_sound_lowlevel.h:75
Definition: mac_sound_lowlevel.h:183
int readBuffer(int16 *buffer, const int numSamples) override
bool isStereo() const override
Definition: mac_sound_lowlevel.h:200
bool endOfData() const override
Definition: mac_sound_lowlevel.h:202
int getRate() const override
Definition: mac_sound_lowlevel.h:201
Definition: mac_sound_lowlevel.h:32
Definition: mac_sound_lowlevel.h:175
Definition: system.h:39
Definition: actor.h:30
Definition: mac_sound_lowlevel.h:117
Definition: mac_sound_lowlevel.h:77
Definition: mac_sound_lowlevel.h:242
Definition: mac_sound_lowlevel.h:46