void Player_AD::stopSound(int sound) { Common::StackLock lock(_mutex); if (sound == _soundPlaying) { stopMusic(); } else { for (int i = 0; i < ARRAYSIZE(_sfx); ++i) { if (_sfx[i].resource == sound) { stopSfx(&_sfx[i]); } } } }
void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping, int volume) { if (channel >= NUM_SFX_CHANNELS) { warning("unknown sfx channel"); return; } stopSfx(channel); debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel); Channel *ch = &_channels[channel]; Audio::AudioStream *input = loadChannelData(filename, ch, looping); if (volume == -1) { volume = ch->volume; } _mixer->playStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume); }
Player_AD::SfxSlot *Player_AD::allocateSfxSlot(int priority) { // First pass: Check whether there's a unused slot for (int i = 0; i < ARRAYSIZE(_sfx); ++i) { if (_sfx[i].resource == -1) { return &_sfx[i]; } } // Second pass: Look for a slot with lower priority for (int i = 0; i < ARRAYSIZE(_sfx); ++i) { if (_sfx[i].priority <= priority) { // Stop the old sfx stopSfx(&_sfx[i]); return &_sfx[i]; } } return nullptr; }
void SoundMan_ns::execute(int command, const char *parm = 0) { uint32 n = strtoul(parm, 0, 10); bool b = (n == 1) ? true : false; switch (command) { case SC_PLAYMUSIC: if (_musicType == MUSIC_CHARACTER) playCharacterMusic(parm); else if (_musicType == MUSIC_LOCATION) playLocationMusic(parm); else playMusic(); break; case SC_STOPMUSIC: stopMusic(); break; case SC_SETMUSICTYPE: _musicType = n; break; case SC_SETMUSICFILE: setMusicFile(parm); break; case SC_PLAYSFX: playSfx(parm, _sfxChannel, _sfxLooping, _sfxVolume); break; case SC_STOPSFX: stopSfx(n); break; case SC_SETSFXCHANNEL: _sfxChannel = n; break; case SC_SETSFXLOOPING: _sfxLooping = b; break; case SC_SETSFXVOLUME: _sfxVolume = n; break; case SC_PAUSE: pause(b); break; } }
Player_AD::SfxSlot *Player_AD::allocateSfxSlot(int priority) { // We always reaLlocate the slot with the lowest priority in case none is // free. SfxSlot *sfx = nullptr; int minPrio = priority; for (int i = 0; i < ARRAYSIZE(_sfx); ++i) { if (_sfx[i].resource == -1) { return &_sfx[i]; } else if (_sfx[i].priority <= minPrio) { minPrio = _sfx[i].priority; sfx = &_sfx[i]; } } // In case we reallocate a slot stop the old one. if (sfx) { stopSfx(sfx); } return sfx; }
int Player_AD::allocateHWChannel(int priority, SfxSlot *owner) { // We always reaLlocate the channel with the lowest priority in case none // is free. int channel = -1; int minPrio = priority; for (int i = 0; i < _numHWChannels; ++i) { if (!_hwChannels[i].allocated) { channel = i; break; } // We don't allow SFX to reallocate their own channels. Otherwise we // would call stopSfx in the midst of startSfx and that can lead to // horrible states... // We also prevent the music from reallocating its own channels like // in the original. if (_hwChannels[i].priority <= minPrio && _hwChannels[i].sfxOwner != owner) { minPrio = _hwChannels[i].priority; channel = i; } } if (channel != -1) { // In case the HW channel belongs to a SFX we will completely // stop playback of that SFX. // TODO: Maybe be more fine grained in the future and allow // detachment of individual channels of a SFX? if (_hwChannels[channel].allocated && _hwChannels[channel].sfxOwner) { stopSfx(_hwChannels[channel].sfxOwner); } _hwChannels[channel].allocated = true; _hwChannels[channel].priority = priority; _hwChannels[channel].sfxOwner = owner; } return channel; }