void SfxPlayer::stop() { debug(DBG_SND, "SfxPlayer::stop()"); MutexStack(_stub, _mutex); if (_resNum != 0) { _resNum = 0; _stub->removeTimer(_timerId); } }
void Mixer::playChannel(uint8 channel, const MixerChunk *mc, uint16 freq, uint8 volume) { debug(DBG_SND, "Mixer::playChannel(%d, %d, %d)", channel, freq, volume); assert(channel < NUM_CHANNELS); MutexStack(_stub, _mutex); MixerChannel *ch = &_channels[channel]; ch->active = true; ch->volume = volume; ch->chunk = *mc; ch->chunkPos = 0; ch->chunkInc = (freq << 8) / _stub->getOutputSampleRate(); }
void SfxPlayer::handleEvents() { MutexStack(sys, _mutex); uint8_t order = _sfxMod.orderTable[_sfxMod.curOrder]; const uint8_t *patternData = _sfxMod.data + _sfxMod.curPos + order * 1024; for (uint8_t ch = 0; ch < 4; ++ch) { handlePattern(ch, patternData); patternData += 4; } _sfxMod.curPos += 4 * 4; debug(DBG_SND, "SfxPlayer::handleEvents() order = 0x%X curPos = 0x%X", order, _sfxMod.curPos); if (_sfxMod.curPos >= 1024) { _sfxMod.curPos = 0; order = _sfxMod.curOrder + 1; if (order == _sfxMod.numOrder) { _resNum = 0; sys->removeTimer(_timerId); mixer->stopAll(); } _sfxMod.curOrder = order; } }
void Mixer::mix(int8 *buf, int len) { MutexStack(_stub, _mutex); memset(buf, 0, len); for (uint8 i = 0; i < NUM_CHANNELS; ++i) { MixerChannel *ch = &_channels[i]; if (ch->active) { int8 *pBuf = buf; for (int j = 0; j < len; ++j, ++pBuf) { uint16 p1, p2; uint16 ilc = (ch->chunkPos & 0xFF); p1 = ch->chunkPos >> 8; ch->chunkPos += ch->chunkInc; if (ch->chunk.loopLen != 0) { if (p1 == ch->chunk.loopPos + ch->chunk.loopLen - 1) { debug(DBG_SND, "Looping sample on channel %d", i); ch->chunkPos = p2 = ch->chunk.loopPos; } else { p2 = p1 + 1; } } else { if (p1 == ch->chunk.len - 1) { debug(DBG_SND, "Stopping sample on channel %d", i); ch->active = false; break; } else { p2 = p1 + 1; } } // interpolate int8 b1 = *(int8 *)(ch->chunk.data + p1); int8 b2 = *(int8 *)(ch->chunk.data + p2); int8 b = (int8)((b1 * (0xFF - ilc) + b2 * ilc) >> 8); // set volume and clamp *pBuf = addclamp(*pBuf, (int)b * ch->volume / 0x40); } } }
void SfxPlayer::start() { debug(DBG_SND, "SfxPlayer::start()"); MutexStack(sys, _mutex); _sfxMod.curPos = 0; _timerId = sys->addTimer(_delay, eventsCallback, this); }
void SfxPlayer::setEventsDelay(uint16_t delay) { debug(DBG_SND, "SfxPlayer::setEventsDelay(%d)", delay); MutexStack(sys, _mutex); _delay = delay * 60 / 7050; }
void Mixer::setChannelVolume(uint8 channel, uint8 volume) { debug(DBG_SND, "Mixer::setChannelVolume(%d, %d)", channel, volume); assert(channel < NUM_CHANNELS); MutexStack(_stub, _mutex); _channels[channel].volume = volume; }
void Mixer::stopChannel(uint8 channel) { debug(DBG_SND, "Mixer::stopChannel(%d)", channel); assert(channel < NUM_CHANNELS); MutexStack(_stub, _mutex); _channels[channel].active = false; }