AGS: Dispose SOUNDCLIP when stopped playing

From upstream 60d40072b429a641f6fcbf3cdb8c60809fc3f770
This commit is contained in:
Paul Gilbert 2022-03-19 12:25:27 -07:00
parent d013cdfe3d
commit 0988fbbe78
4 changed files with 75 additions and 15 deletions

View File

@ -51,19 +51,6 @@ namespace AGS {
/* Synced up to upstream: ---
* ----
*
* Commits still pending to be ported:
* cae84d689019313cad49b6dca7e916866b90e49e
* - We have slightly different blending code, commit needs
* to be modified to take that into account
*
* Skipped upstream commits:
* 22b0f2b93e314b167f80e89a9dd138202a7e28a7
* * Engine: merged SOUNDCLIP and CLIP_OPENAL
* ScummVM has it's own sound clip classes, so doesn't have CLIP_OPENAL
* ff05f69f2361c34212b6ba1db0f22b2c1ba38d7b
* Engine: "transactional" SOUNDCLIP
* ScummVM doesn't have the OPENAL decoder
*/
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200

View File

@ -795,6 +795,21 @@ void update_audio_system_on_game_loop() {
_G(audio_doing_crossfade) = false;
if (_G(loopcounter) % 5 == 0) {
update_ambient_sound_vol();
update_directional_sound_vol();
}
// Update and sync logical game channels with the audio backend
for (int i = 0; i < _GP(game).numGameChannels; ++i) {
auto *ch = AudioChans::GetChannel(i);
if (ch) { // update the playing channel, and if it's finished then dispose it
if (ch->is_ready() && !ch->update()) {
delete ch;
AudioChans::SetChannel(i, nullptr);
}
}
}
}
void stopmusic() {

View File

@ -64,6 +64,55 @@ void SOUNDCLIP::apply_directional_modifier(int mod) {
adjust_volume();
}
bool SOUNDCLIP::update() {
if (!is_ready())
return false;
if (_paramsChanged) {
auto vol_f = static_cast<float>(get_final_volume()) / 255.0f;
if (vol_f < 0.0f) {
vol_f = 0.0f;
}
if (vol_f > 1.0f) {
vol_f = 1.0f;
}
auto speed_f = static_cast<float>(_speed) / 1000.0f;
if (speed_f <= 0.0) {
speed_f = 1.0f;
}
// Sets the pan position, ranging from -100 (left) to +100 (right)
auto panning_f = (static_cast<float>(_panning) / 100.0f);
if (panning_f < -1.0f) {
panning_f = -1.0f;
}
if (panning_f > 1.0f) {
panning_f = 1.0f;
}
//audio_core_slot_configure(slot_, vol_f, speed_f, panning_f);
_paramsChanged = false;
}
/*
float pos_f, posms_f;
PlaybackState core_state = audio_core_slot_get_play_state(slot_, pos_f, posms_f);
pos = static_cast<int>(pos_f);
posMs = static_cast<int>(posms_f);
if (state == core_state || core_state == PlayStateError || core_state == PlayStateFinished) {
state = core_state;
return is_ready();
}
switch (state) {
case PlaybackState::PlayStatePlaying:
state = audio_core_slot_play(slot_);
break;
}
*/
return is_ready();
}
/*------------------------------------------------------------------*/
SoundClipWaveBase::SoundClipWaveBase(Audio::AudioStream *stream, bool repeat) :

View File

@ -160,15 +160,24 @@ struct SOUNDCLIP {
*/
void apply_directional_modifier(int mod);
inline bool is_ready() { return is_playing(); }
/**
* Returns if the clip is still playing, otherwise it's finished
*/
bool update();
protected:
virtual void adjust_volume() = 0;
// mute mode overrides the volume; if set, any volume assigned is stored
// in properties, but not applied to playback itself
bool _muted;
bool _muted = false;
// speed of playback, in clip ms per real second
int _speed;
int _speed = 0;
bool _paramsChanged = false;
// helper function for calculating volume with applied modifiers
inline int get_final_volume() const {