void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning) { // Change the game's sound volume (0 - 100) to Scummvm's scale (0 - 255) volume = (volume == -1) ? 255 : volume * 255 / 100; if (resIndex == -1) { // Stop all sounds _vm->_mixer->stopAll(); _vm->_screen->keepTalkTextItemsAlive(); for (int i = 0; i < kMaxChannels; i++) { clearChannel(i); } } else if (type == -2) { // Stop sounds with specified resIndex for (int i = 0; i < kMaxChannels; i++) { if (channels[i].resIndex == resIndex) { _vm->_mixer->stopHandle(channels[i].handle); clearChannel(i); } } } else { if (type == kChannelTypeSpeech) { // Stop speech and play new sound stopSpeech(); } // Play new sound in empty channel int freeChannel = -1; for (int i = 0; i < kMaxChannels; i++) { if (channels[i].type == kChannelTypeEmpty || !_vm->_mixer->isSoundHandleActive(channels[i].handle)) { freeChannel = i; break; } } // If all channels are in use no new sound will be played if (freeChannel >= 0) { Resource *soundResource = _vm->_res->load(resIndex); Audio::AudioStream *stream = Audio::makeLoopingAudioStream( Audio::makeRawStream(soundResource->data, soundResource->size, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO), type == kChannelTypeBackground ? 0 : 1); channels[freeChannel].type = type; channels[freeChannel].resIndex = resIndex; channels[freeChannel].volume = volume; channels[freeChannel].panning = panning; Audio::Mixer::SoundType soundType = getScummVMSoundType((SoundChannelType)type); _vm->_mixer->playStream(soundType, &channels[freeChannel].handle, stream, -1, volume, panning); } // if (freeChannel >= 0) } // resIndex }
void Sound::stopAll() { for (int i = 0; i < kMaxChannels; i++) { _vm->_mixer->stopHandle(channels[i].handle); _vm->_screen->keepTalkTextItemsAlive(); clearChannel(i); } }
void FxMixer::clear() { while( m_fxChannels.size() > 1 ) { deleteChannel(1); } clearChannel(0); }
void Sound::stopSpeech() { for (int i = 0; i < kMaxChannels; i++) { if (channels[i].type == kChannelTypeSpeech) { _vm->_mixer->stopHandle(channels[i].handle); _vm->_screen->keepTalkTextItemsAlive(); clearChannel(i); } } }
int FxMixer::createChannel() { const int index = m_fxChannels.size(); // create new channel m_fxChannels.push_back( new FxChannel( index, this ) ); // reset channel state clearChannel( index ); return index; }
void Player_AD::parseSlot(Channel *channel) { while (true) { const byte *curOffset = channel->currentOffset; switch (*curOffset) { case 1: // INSTRUMENT DEFINITION ++curOffset; channel->instrumentData[0] = *(curOffset + 0); channel->instrumentData[1] = *(curOffset + 2); channel->instrumentData[2] = *(curOffset + 9); channel->instrumentData[3] = *(curOffset + 8); channel->instrumentData[4] = *(curOffset + 4); channel->instrumentData[5] = *(curOffset + 3); channel->instrumentData[6] = 0; setupChannel(channel->hardwareChannel, curOffset); writeReg(0xA0 + channel->hardwareChannel, *(curOffset + 0)); writeReg(0xB0 + channel->hardwareChannel, *(curOffset + 1) & 0xDF); channel->currentOffset += 15; break; case 2: // NOTE DEFINITION ++curOffset; channel->state = kChannelStatePlay; noteOffOn(channel->hardwareChannel); parseNote(&channel->notes[0], *channel, curOffset + 0); parseNote(&channel->notes[1], *channel, curOffset + 5); return; case 0x80: // LOOP channel->currentOffset = channel->startOffset; break; default: // START OF CHANNEL // When we encounter a start of another channel while playback // it means that the current channel is finished. Thus, we will // stop it. clearChannel(*channel); channel->state = kChannelStateOff; return; } } }
void Player_AD::stopSfx(SfxSlot *sfx) { if (sfx->resource == -1) { return; } // 1. step: Clear all the channels. for (int i = 0; i < ARRAYSIZE(sfx->channels); ++i) { if (sfx->channels[i].state) { clearChannel(sfx->channels[i]); sfx->channels[i].state = kChannelStateOff; } if (sfx->channels[i].hardwareChannel != -1) { freeHWChannel(sfx->channels[i].hardwareChannel); sfx->channels[i].hardwareChannel = -1; } } // 2. step: Unlock the resource. _vm->_res->unlock(rtSound, sfx->resource); sfx->resource = -1; }
Sound::Sound(ToltecsEngine *vm) : _vm(vm) { for (int i = 0; i < kMaxChannels; i++) { clearChannel(i); } }