AGS: added AudioChannel.SeekMs() to coplement PositionMs

From upstream 59a5cacb8ed61e41dd8ef0641dd5de156caf8d32
This commit is contained in:
Thierry Crozat 2022-10-10 19:56:35 +01:00
parent e248b50d6e
commit 26716156af
6 changed files with 52 additions and 4 deletions

View File

@ -178,10 +178,17 @@ void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition) {
quitprintf("!AudioChannel.Seek: invalid seek position %d", newPosition);
auto *ch = AudioChans::GetChannelIfPlaying(channel->id);
if (ch) {
if (ch)
ch->seek(newPosition);
}
}
void AudioChannel_SeekMs(ScriptAudioChannel *channel, int newPosition) {
if (newPosition < 0)
quitprintf("!AudioChannel.SeekMs: invalid seek position %d", newPosition);
auto* ch = AudioChans::GetChannelIfPlaying(channel->id);
if (ch)
ch->seek_ms(newPosition);
}
void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos) {
@ -266,6 +273,10 @@ RuntimeScriptValue Sc_AudioChannel_Seek(void *self, const RuntimeScriptValue *pa
API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_Seek);
}
RuntimeScriptValue Sc_AudioChannel_SeekMs(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SeekMs);
}
// void | ScriptAudioChannel *channel, int xPos, int yPos
RuntimeScriptValue Sc_AudioChannel_SetRoomLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_PINT2(ScriptAudioChannel, AudioChannel_SetRoomLocation);
@ -295,6 +306,7 @@ void RegisterAudioChannelAPI() {
ccAddExternalObjectFunction("AudioChannel::Pause^0", Sc_AudioChannel_Pause);
ccAddExternalObjectFunction("AudioChannel::Resume^0", Sc_AudioChannel_Resume);
ccAddExternalObjectFunction("AudioChannel::Seek^1", Sc_AudioChannel_Seek);
ccAddExternalObjectFunction("AudioChannel::SeekMs^1", Sc_AudioChannel_SeekMs);
ccAddExternalObjectFunction("AudioChannel::SetRoomLocation^2", Sc_AudioChannel_SetRoomLocation);
ccAddExternalObjectFunction("AudioChannel::Stop^0", Sc_AudioChannel_Stop);
ccAddExternalObjectFunction("AudioChannel::get_ID", Sc_AudioChannel_GetID);

View File

@ -39,6 +39,7 @@ int AudioChannel_GetVolume(ScriptAudioChannel *channel);
int AudioChannel_SetVolume(ScriptAudioChannel *channel, int newVolume);
void AudioChannel_Stop(ScriptAudioChannel *channel);
void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition);
void AudioChannel_SeekMs(ScriptAudioChannel *channel, int newPosition);
void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos);
} // namespace AGS3

View File

@ -47,9 +47,14 @@ void MYMIDI::poll() {
}
void MYMIDI::seek(int pos) {
// pos is the beat number
warning("TODO: MYMIDI::seek");
}
void MYMIDI::seek_ms(int pos_ms) {
warning("TODO: MYMIDI::seek_ms");
}
int MYMIDI::get_pos() {
// We don't know ms with midi
return 0;

View File

@ -40,6 +40,7 @@ struct MYMIDI : public SOUNDCLIP {
void poll() override;
void seek(int pos) override;
void seek_ms(int pos_ms) override;
int get_pos() override;

View File

@ -194,11 +194,19 @@ bool SoundClipWaveBase::is_paused() {
}
void SoundClipWaveBase::seek(int offset) {
// TODO: for backward compatibility we need to reimplement seeking
// to a position which units are defined according to the sound type:
// - WAV / VOC - the sample number
// - OGG / MP3 - milliseconds
seek_ms(offset);
}
void SoundClipWaveBase::seek_ms(int pos_ms) {
Audio::SeekableAudioStream *stream =
dynamic_cast<Audio::SeekableAudioStream *>(_stream);
if (stream) {
stream->seek(Audio::Timestamp(offset));
stream->seek(Audio::Timestamp(pos_ms));
} else {
warning("Audio stream did not support seeking");
}

View File

@ -34,6 +34,12 @@
namespace AGS3 {
// SOUNDCLIP's state and parameter updates sync with the audio core in
// batches, only when the engine updates the game, never while the user script
// is being executed. The sync is performed by calling update().
// This is to ensure that the clip reference, state and properties don't change
// in the middle of the script's command sequence.
// TODO: one of the biggest problems with sound clips currently is that it
// provides several methods of applying volume, which may ignore or override
// each other, and does not shape a consistent interface.
@ -66,7 +72,21 @@ struct SOUNDCLIP {
virtual int play() = 0;
virtual void pause() = 0;
virtual void resume() = 0;
/**
* Seeks to the position, where pos units depend on the audio type:
* - MIDI - the beat number
* - MOD / XM / S3M - the pattern number
* - WAV / VOC - the sample number
* - OGG / MP3 - milliseconds
*/
virtual void seek(int offset) = 0;
/**
* Seeks to the position in milliseconds
*/
virtual void seek_ms(int pos_ms) = 0;
virtual int play_from(int position) = 0;
virtual bool is_playing() = 0; // true if playing or paused. false if never played or stopped.
virtual bool is_paused() = 0; // true if paused
@ -208,6 +228,7 @@ public:
bool is_playing() override;
bool is_paused() override;
void seek(int offset) override;
void seek_ms(int pos_ms) override;
int get_pos() override;
int get_pos_ms() override;
int get_length_ms() override;