Merge pull request #130 from Splendide-Imaginarius/seek-double

Audio: use double for seeking
This commit is contained in:
Splendide Imaginarius 2024-09-27 17:34:12 +00:00 committed by GitHub
commit c58d708faa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 35 additions and 26 deletions

View file

@ -44,7 +44,7 @@ struct ALDataSource
/* If the source doesn't support seeking, it will /* If the source doesn't support seeking, it will
* reset back to the beginning */ * reset back to the beginning */
virtual void seekToOffset(float seconds) = 0; virtual void seekToOffset(double seconds) = 0;
/* The frame count right after wrap around */ /* The frame count right after wrap around */
virtual uint32_t loopStartFrames() = 0; virtual uint32_t loopStartFrames() = 0;

View file

@ -112,7 +112,7 @@ void ALStream::stop()
state = Stopped; state = Stopped;
} }
void ALStream::play(float offset) void ALStream::play(double offset)
{ {
if (!source) if (!source)
return; return;
@ -173,13 +173,14 @@ ALStream::State ALStream::queryState()
return state; return state;
} }
float ALStream::queryOffset() double ALStream::queryOffset()
{ {
if (state == Closed || !source) if (state == Closed || !source)
return 0; return 0;
float procOffset = static_cast<float>(procFrames) / source->sampleRate(); double procOffset = static_cast<double>(procFrames) / source->sampleRate();
// TODO: getSecOffset returns a float, we should improve precision to double.
return procOffset + AL::Source::getSecOffset(alSrc); return procOffset + AL::Source::getSecOffset(alSrc);
} }
@ -289,7 +290,7 @@ void ALStream::stopStream()
procFrames = 0; procFrames = 0;
} }
void ALStream::startStream(float offset) void ALStream::startStream(double offset)
{ {
AL::Source::clearQueue(alSrc); AL::Source::clearQueue(alSrc);

View file

@ -64,7 +64,7 @@ struct ALStream
AtomicFlag threadTermReq; AtomicFlag threadTermReq;
AtomicFlag needsRewind; AtomicFlag needsRewind;
float startOffset; double startOffset;
float pitch; float pitch;
@ -93,13 +93,13 @@ struct ALStream
void close(); void close();
void open(const std::string &filename); void open(const std::string &filename);
void stop(); void stop();
void play(float offset = 0); void play(double offset = 0);
void pause(); void pause();
void setVolume(float value); void setVolume(float value);
void setPitch(float value); void setPitch(float value);
State queryState(); State queryState();
float queryOffset(); double queryOffset();
bool queryNativePitch(); bool queryNativePitch();
private: private:
@ -107,7 +107,7 @@ private:
void openSource(const std::string &filename); void openSource(const std::string &filename);
void stopStream(); void stopStream();
void startStream(float offset); void startStream(double offset);
void pauseStream(); void pauseStream();
void resumeStream(); void resumeStream();

View file

@ -292,7 +292,7 @@ Audio::Audio(RGSSThreadData &rtData)
void Audio::bgmPlay(const char *filename, void Audio::bgmPlay(const char *filename,
int volume, int volume,
int pitch, int pitch,
float pos, double pos,
int track) int track)
{ {
if (track == -127) { if (track == -127) {
@ -356,7 +356,7 @@ void Audio::bgmSetVolume(int volume, int track)
void Audio::bgsPlay(const char *filename, void Audio::bgsPlay(const char *filename,
int volume, int volume,
int pitch, int pitch,
float pos) double pos)
{ {
p->bgs.play(filename, volume, pitch, pos); p->bgs.play(filename, volume, pitch, pos);
} }
@ -407,12 +407,12 @@ void Audio::setupMidi()
shState->midiState().initIfNeeded(shState->config()); shState->midiState().initIfNeeded(shState->config());
} }
float Audio::bgmPos(int track) double Audio::bgmPos(int track)
{ {
return p->getTrackByIndex(track)->playingOffset(); return p->getTrackByIndex(track)->playingOffset();
} }
float Audio::bgsPos() double Audio::bgsPos()
{ {
return p->bgs.playingOffset(); return p->bgs.playingOffset();
} }

View file

@ -41,7 +41,7 @@ public:
void bgmPlay(const char *filename, void bgmPlay(const char *filename,
int volume = 100, int volume = 100,
int pitch = 100, int pitch = 100,
float pos = 0, double pos = 0,
int track = -127); int track = -127);
void bgmStop(int track = -127); void bgmStop(int track = -127);
void bgmFade(int time, int track = -127); void bgmFade(int time, int track = -127);
@ -51,7 +51,7 @@ public:
void bgsPlay(const char *filename, void bgsPlay(const char *filename,
int volume = 100, int volume = 100,
int pitch = 100, int pitch = 100,
float pos = 0); double pos = 0);
void bgsStop(); void bgsStop();
void bgsFade(int time); void bgsFade(int time);
@ -67,8 +67,8 @@ public:
void seStop(); void seStop();
void setupMidi(); void setupMidi();
float bgmPos(int track = 0); double bgmPos(int track = 0);
float bgsPos(); double bgsPos();
void reset(); void reset();

View file

@ -76,7 +76,7 @@ AudioStream::~AudioStream()
void AudioStream::play(const std::string &filename, void AudioStream::play(const std::string &filename,
int volume, int volume,
int pitch, int pitch,
float offset) double offset)
{ {
finiFadeOutInt(); finiFadeOutInt();
@ -217,7 +217,7 @@ void AudioStream::fadeOut(int duration)
unlockStream(); unlockStream();
} }
void AudioStream::seek(float offset) void AudioStream::seek(double offset)
{ {
lockStream(); lockStream();
stream.play(offset); stream.play(offset);
@ -248,7 +248,7 @@ float AudioStream::getVolume(VolumeType type)
return volumes[type]; return volumes[type];
} }
float AudioStream::playingOffset() double AudioStream::playingOffset()
{ {
return stream.queryOffset(); return stream.queryOffset();
} }

View file

@ -127,10 +127,10 @@ struct AudioStream
void play(const std::string &filename, void play(const std::string &filename,
int volume, int volume,
int pitch, int pitch,
float offset = 0); double offset = 0);
void stop(); void stop();
void fadeOut(int duration); void fadeOut(int duration);
void seek(float offset); void seek(double offset);
/* Any access to this classes 'stream' member, /* Any access to this classes 'stream' member,
* whether state query or modification, must be * whether state query or modification, must be
@ -141,7 +141,7 @@ struct AudioStream
void setVolume(VolumeType type, float value); void setVolume(VolumeType type, float value);
float getVolume(VolumeType type); float getVolume(VolumeType type);
float playingOffset(); double playingOffset();
private: private:
float volumes[VolumeTypeCount]; float volumes[VolumeTypeCount];

View file

@ -885,7 +885,7 @@ struct MidiSource : ALDataSource, MidiReadHandler
} }
/* Midi sources cannot seek, and so always reset to beginning */ /* Midi sources cannot seek, and so always reset to beginning */
void seekToOffset(float) void seekToOffset(double)
{ {
/* Reset synth */ /* Reset synth */
fluid.synth_system_reset(synth); fluid.synth_system_reset(synth);

View file

@ -144,13 +144,20 @@ struct SDLSoundSource : ALDataSource
return sample->actual.rate; return sample->actual.rate;
} }
void seekToOffset(float seconds) void seekToOffset(double seconds)
{ {
if (seconds <= 0) if (seconds <= 0)
{
Sound_Rewind(sample); Sound_Rewind(sample);
}
else else
{
// Unfortunately there is no easy API in SDL_sound for seeking with better precision than 1ms.
// TODO: Work around this by manually consuming the remaining samples.
// TODO: Also we're flooring here when we probably should be rounding.
Sound_Seek(sample, static_cast<uint32_t>(seconds * 1000)); Sound_Seek(sample, static_cast<uint32_t>(seconds * 1000));
} }
}
uint32_t loopStartFrames() uint32_t loopStartFrames()
{ {

View file

@ -156,7 +156,7 @@ struct VorbisSource : ALDataSource
return info.rate; return info.rate;
} }
void seekToOffset(float seconds) void seekToOffset(double seconds)
{ {
if (seconds <= 0) if (seconds <= 0)
{ {
@ -164,6 +164,7 @@ struct VorbisSource : ALDataSource
currentFrame = 0; currentFrame = 0;
} }
// TODO: We're flooring here when we probably should be rounding.
currentFrame = seconds * info.rate; currentFrame = seconds * info.rate;
if (loop.valid && currentFrame > loop.end) if (loop.valid && currentFrame > loop.end)