38 static std::atomic<uint8> _active_channels;
40 static uint32 _play_rate = 11025;
41 static uint32 _max_size = UINT_MAX;
43 static std::mutex _music_stream_mutex;
44 static std::atomic<uint8> _effect_vol;
64 return ((b[0] * ((1 << 16) - frac_pos)) + (b[1] * frac_pos)) >> 16;
67 static void mix_int16(
MixerChannel *sc, int16 *buffer, uint samples, uint8 effect_vol)
69 if (samples > sc->samples_left) samples = sc->samples_left;
70 sc->samples_left -= samples;
73 const int16 *b = (
const int16 *)sc->memory + sc->pos;
74 uint32 frac_pos = sc->frac_pos;
75 uint32 frac_speed = sc->frac_speed;
76 int volume_left = sc->volume_left * effect_vol / 255;
77 int volume_right = sc->volume_right * effect_vol / 255;
79 if (frac_speed == 0x10000) {
86 }
while (--samples > 0);
93 frac_pos += frac_speed;
96 }
while (--samples > 0);
99 sc->frac_pos = frac_pos;
100 sc->pos = b - (
const int16 *)sc->memory;
103 static void mix_int8_to_int16(
MixerChannel *sc, int16 *buffer, uint samples, uint8 effect_vol)
105 if (samples > sc->samples_left) samples = sc->samples_left;
106 sc->samples_left -= samples;
109 const int8 *b = sc->memory + sc->pos;
110 uint32 frac_pos = sc->frac_pos;
111 uint32 frac_speed = sc->frac_speed;
112 int volume_left = sc->volume_left * effect_vol / 255;
113 int volume_right = sc->volume_right * effect_vol / 255;
115 if (frac_speed == 0x10000) {
122 }
while (--samples > 0);
129 frac_pos += frac_speed;
132 }
while (--samples > 0);
135 sc->frac_pos = frac_pos;
136 sc->pos = b - sc->memory;
139 static void MxCloseChannel(uint8 channel_index)
141 _active_channels.fetch_and(~(1 << channel_index), std::memory_order_release);
144 void MxMixSamples(
void *buffer, uint samples)
147 static uint last_samples = 0;
148 if (samples != last_samples) {
149 framerate.SetExpectedRate((
double)_play_rate / samples);
150 last_samples = samples;
154 memset(buffer, 0,
sizeof(int16) * 2 * samples);
157 std::lock_guard<std::mutex>
lock{ _music_stream_mutex };
159 if (_music_stream) _music_stream((int16*)buffer, samples);
166 uint8 effect_vol_setting = _effect_vol.load(std::memory_order_relaxed);
167 uint8 effect_vol = (effect_vol_setting *
169 effect_vol_setting) / (127 * 127);
172 uint8 active = _active_channels.load(std::memory_order_acquire);
176 mix_int16(mc, (int16*)buffer, samples, effect_vol);
178 mix_int8_to_int16(mc, (int16*)buffer, samples, effect_vol);
180 if (mc->samples_left == 0) MxCloseChannel(idx);
186 uint8 currently_active = _active_channels.load(std::memory_order_acquire);
187 uint8 available = ~currently_active;
188 if (available == 0)
return nullptr;
194 mc->memory =
nullptr;
198 void MxSetChannelRawSrc(
MixerChannel *mc, int8 *mem,
size_t size, uint rate,
bool is16bit)
204 mc->frac_speed = (rate << 16) / _play_rate;
206 if (is16bit) size /= 2;
209 while (size >= _max_size) {
211 rate = (rate >> 1) + 1;
214 mc->samples_left = (uint)size * _play_rate / rate;
215 mc->is16bit = is16bit;
228 mc->volume_left = (uint)(sin((1.0 - pan) * M_PI / 2.0) * volume);
229 mc->volume_right = (uint)(sin(pan * M_PI / 2.0) * volume);
235 uint8 channel_index = mc - _channels;
236 _active_channels.fetch_or((1 << channel_index), std::memory_order_release);
246 std::lock_guard<std::mutex>
lock{ _music_stream_mutex };
247 _music_stream = music_callback;
252 bool MxInitialize(uint rate)
254 std::lock_guard<std::mutex>
lock{ _music_stream_mutex };
256 _max_size = UINT_MAX / _play_rate;
257 _music_stream =
nullptr;
261 void SetEffectVolume(uint8 volume)
263 _effect_vol.store(volume, std::memory_order_relaxed);