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
34typedef uint32 ufrac_t;
35static inline ufrac_t uintToUfrac(uint16 value) {
return value << FRAC_BITS; }
36static 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];
95Mixer_Mac<T>::Mixer_Mac(Mode mode) :
104void Mixer_Mac<T>::startMixer() {
105 _nextTick = _samplesPerTick = uintToUfrac(getRate() / kInterruptFreq) + uintToUfrac(getRate() % kInterruptFreq) / kInterruptFreq;
112void Mixer_Mac<T>::stopMixer() {
118void Mixer_Mac<T>::setChannelData(uint channel,
const byte *data, uint16 startOffset, uint16 endOffset, uint16 loopLength) {
119 assert(channel < kChannels);
121 Channel &ch = _mixChannels[channel];
124 ch.pos = uintToUfrac(startOffset);
125 ch.endOffset = endOffset;
126 ch.loopLength = loopLength;
130void Mixer_Mac<T>::setChannelStep(uint channel, ufrac_t step) {
131 assert(channel < kChannels);
133 if (_mode == kModeAuthentic) {
134 _mixChannels[channel].step = step;
139 _mixChannels[channel].step = (ufrac_t)(step * 11000ULL / getRate());
144void Mixer_Mac<T>::setChannelVolume(uint channel,
byte volume) {
145 assert(channel < kChannels);
146 _mixChannels[channel].volume = volume;
150void Mixer_Mac<T>::setChannelPan(uint channel,
byte pan) {
151 assert(channel < kChannels);
152 _mixChannels[channel].pan = pan;
156template <typename Mixer_Mac<T>::Mode mode>
157void Mixer_Mac<T>::generateSamples(int16 *data,
int len) {
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;
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;
251 assert(channel < kChannels);
253 Channel &ch = _mixChannels[channel];
265void Mixer_Mac<T>::resetChannels() {
266 for (uint ci = 0; ci < kChannels; ++ci)
Definition: audiostream.h:50
virtual uint getOutputRate() const =0
Definition: macmixer.h:39
int getRate() const override
Definition: macmixer.h:66
bool endOfData() const override
Definition: macmixer.h:68
int readBuffer(int16 *data, const int numSamples) override
Definition: macmixer.h:208
bool isStereo() const override
Definition: macmixer.h:65
virtual Audio::Mixer * getMixer()=0