22 #include "audio/audiostream.h" 23 #include "audio/mixer.h" 24 #include "common/frac.h" 25 #include "common/mutex.h" 26 #include "common/system.h" 28 #ifndef SCI_SOUND_DRIVERS_MACMIXER_H 29 #define SCI_SOUND_DRIVERS_MACMIXER_H 34 typedef uint32 ufrac_t;
35 static inline ufrac_t uintToUfrac(uint16 value) {
return value << FRAC_BITS; }
36 static inline uint16 ufracToUint(ufrac_t value) {
return value >> FRAC_BITS; }
55 void setMixerVolume(byte volume) { _mixVolume = volume; }
56 void resetChannel(uint channel);
59 void setChannelData(uint channel,
const byte *data, uint16 startOffset, uint16 endOffset, uint16 loopLength = 0);
60 void setChannelStep(uint channel, ufrac_t step);
61 void setChannelVolume(uint channel, byte volume);
62 void setChannelPan(uint channel, byte pan);
65 bool isStereo()
const override {
return _mode == kModeHqStereo; }
67 int readBuffer(int16 *data,
const int numSamples)
override;
74 void generateSamples(int16 *buf,
int len);
87 ufrac_t _samplesPerTick;
90 Channel _mixChannels[kChannels];
103 template <
typename T>
105 _nextTick = _samplesPerTick = uintToUfrac(
getRate() / kInterruptFreq) + uintToUfrac(
getRate() % kInterruptFreq) / kInterruptFreq;
111 template <
typename T>
117 template <
typename T>
119 assert(channel < kChannels);
121 Channel &ch = _mixChannels[channel];
124 ch.pos = uintToUfrac(startOffset);
125 ch.endOffset = endOffset;
126 ch.loopLength = loopLength;
129 template <
typename T>
131 assert(channel < kChannels);
133 if (_mode == kModeAuthentic) {
134 _mixChannels[channel].step = step;
139 _mixChannels[channel].step = (ufrac_t)(step * 11000ULL /
getRate());
143 template <
typename T>
145 assert(channel < kChannels);
146 _mixChannels[channel].volume = volume;
149 template <
typename T>
151 assert(channel < kChannels);
152 _mixChannels[channel].pan = pan;
155 template <
typename T>
156 template <typename Mixer_Mac<T>::Mode mode>
158 for (
int i = 0; i < len; ++i) {
162 for (
int ci = 0; ci < kChannels; ++ci) {
163 Channel &ch = _mixChannels[ci];
168 const uint16 curOffset = ufracToUint(ch.pos);
170 if (mode == kModeHq || mode == kModeHqStereo) {
171 int32 sample = (ch.data[curOffset] - 0x80) << 8;
173 const int32 sample2 = (ch.data[curOffset + 1] - 0x80) << 8;
174 sample += fracToInt((sample2 - sample) * (ch.pos & FRAC_LO_MASK));
177 if (mode == kModeHqStereo) {
178 mixL += sample * (127 - ch.pan) / (63 * 64);
179 mixR += sample * ch.pan / (63 * 64);
184 mixL +=
static_cast<T *
>(
this)->applyChannelVolume(ch.volume, ch.data[curOffset]) << 8;
189 if (ufracToUint(ch.pos) > ch.endOffset) {
190 if (ch.loopLength > 0) {
192 ch.pos -= uintToUfrac(ch.loopLength);
193 }
while (ufracToUint(ch.pos) > ch.endOffset);
195 static_cast<T *
>(
this)->onChannelFinished(ci);
201 *data++ = (int16)CLIP<int32>(mixL, -32768, 32767) * _mixVolume / 8;
202 if (mode == kModeHqStereo)
203 *data++ = (int16)CLIP<int32>(mixR, -32768, 32767) * _mixVolume / 8;
207 template <
typename T>
213 memset(data, 0, numSamples * 2);
217 const int stereoFactor =
isStereo() ? 2 : 1;
218 int len = numSamples / stereoFactor;
222 if (step > ufracToUint(_nextTick))
223 step = ufracToUint(_nextTick);
227 generateSamples<kModeAuthentic>(data, step);
230 generateSamples<kModeHq>(data, step);
233 generateSamples<kModeHqStereo>(data, step);
236 _nextTick -= uintToUfrac(step);
237 if (ufracToUint(_nextTick) == 0) {
238 static_cast<T *
>(
this)->interrupt();
239 _nextTick += _samplesPerTick;
242 data += step * stereoFactor;
249 template <
typename T>
251 assert(channel < kChannels);
253 Channel &ch = _mixChannels[channel];
264 template <
typename T>
266 for (uint ci = 0; ci < kChannels; ++ci)
272 #endif // SCI_SOUND_DRIVERS_MACMIXER_H bool endOfData() const override
Definition: macmixer.h:68
Definition: macmixer.h:39
virtual uint getOutputRate() const =0
virtual Audio::Mixer * getMixer()=0
int readBuffer(int16 *data, const int numSamples) override
Definition: macmixer.h:208
Definition: audiostream.h:50
int getRate() const override
Definition: macmixer.h:66
bool isStereo() const override
Definition: macmixer.h:65