fix audio desync for realsies, stderr to log.txt
This commit is contained in:
@@ -117,6 +117,14 @@ namespace anm2ed::resource
|
||||
MIX_StopTrack(track, 0);
|
||||
}
|
||||
|
||||
void Audio::track_detach(MIX_Mixer* mixer)
|
||||
{
|
||||
if (!track) return;
|
||||
if (mixer && MIX_GetTrackMixer(track) != mixer) return;
|
||||
MIX_DestroyTrack(track);
|
||||
track = nullptr;
|
||||
}
|
||||
|
||||
bool Audio::is_playing() const { return track && MIX_TrackPlaying(track); }
|
||||
|
||||
Audio::Audio(const Audio& other)
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace anm2ed::resource
|
||||
bool is_valid();
|
||||
void play(bool loop = false, MIX_Mixer* = nullptr);
|
||||
void stop(MIX_Mixer* = nullptr);
|
||||
void track_detach(MIX_Mixer* = nullptr);
|
||||
bool is_playing() const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "audio_stream.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
@@ -10,16 +12,46 @@ namespace anm2ed
|
||||
void AudioStream::callback(void* userData, MIX_Mixer* mixer, const SDL_AudioSpec* spec, float* pcm, int samples)
|
||||
{
|
||||
auto self = (AudioStream*)userData;
|
||||
if (!self->isFirstCallbackCaptured)
|
||||
{
|
||||
self->firstCallbackCounter = SDL_GetPerformanceCounter();
|
||||
self->isFirstCallbackCaptured = true;
|
||||
}
|
||||
self->callbackSamples = samples;
|
||||
self->stream.insert(self->stream.end(), pcm, pcm + samples);
|
||||
}
|
||||
|
||||
AudioStream::AudioStream(MIX_Mixer* mixer) { MIX_GetMixerFormat(mixer, &spec); }
|
||||
|
||||
void AudioStream::capture_begin(MIX_Mixer* mixer) { MIX_SetPostMixCallback(mixer, callback, this); }
|
||||
void AudioStream::capture_begin(MIX_Mixer* mixer)
|
||||
{
|
||||
stream.clear();
|
||||
callbackSamples = 0;
|
||||
captureStartCounter = SDL_GetPerformanceCounter();
|
||||
firstCallbackCounter = 0;
|
||||
isFirstCallbackCaptured = false;
|
||||
MIX_SetPostMixCallback(mixer, callback, this);
|
||||
}
|
||||
|
||||
void AudioStream::capture_end(MIX_Mixer* mixer)
|
||||
{
|
||||
MIX_SetPostMixCallback(mixer, nullptr, this);
|
||||
stream.clear();
|
||||
}
|
||||
}
|
||||
|
||||
double AudioStream::callback_latency_seconds_get() const
|
||||
{
|
||||
auto freq = std::max(spec.freq, 1);
|
||||
auto channels = std::max(spec.channels, 1);
|
||||
auto framesPerCallback = (double)callbackSamples / (double)channels;
|
||||
return framesPerCallback / (double)freq;
|
||||
}
|
||||
|
||||
double AudioStream::capture_start_delay_seconds_get() const
|
||||
{
|
||||
if (!isFirstCallbackCaptured || captureStartCounter == 0 || firstCallbackCounter < captureStartCounter) return 0.0;
|
||||
auto frequency = SDL_GetPerformanceFrequency();
|
||||
if (frequency == 0) return 0.0;
|
||||
return (double)(firstCallbackCounter - captureStartCounter) / (double)frequency;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,15 @@ namespace anm2ed
|
||||
public:
|
||||
std::vector<float> stream{};
|
||||
SDL_AudioSpec spec{};
|
||||
int callbackSamples{};
|
||||
Uint64 captureStartCounter{};
|
||||
Uint64 firstCallbackCounter{};
|
||||
bool isFirstCallbackCaptured{};
|
||||
|
||||
AudioStream(MIX_Mixer*);
|
||||
void capture_begin(MIX_Mixer*);
|
||||
void capture_end(MIX_Mixer*);
|
||||
double callback_latency_seconds_get() const;
|
||||
double capture_start_delay_seconds_get() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user