mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-06 13:31:55 +00:00
Ensures the stereo audio queue is the same length (in time) as the mono.
This commit is contained in:
parent
d55d077a95
commit
ea1c8a3b81
@ -168,10 +168,12 @@ struct MachineRunner {
|
||||
|
||||
struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate {
|
||||
// This is empirically the best that I can seem to do with SDL's timer precision.
|
||||
static constexpr int buffer_size = 1024;
|
||||
static constexpr int buffered_samples = 1024;
|
||||
bool is_stereo = false;
|
||||
|
||||
void speaker_did_complete_samples(Outputs::Speaker::Speaker *speaker, const std::vector<int16_t> &buffer) final {
|
||||
std::lock_guard<std::mutex> lock_guard(audio_buffer_mutex_);
|
||||
const auto buffer_size = buffered_samples * (is_stereo ? 2 : 1);
|
||||
if(audio_buffer_.size() > buffer_size) {
|
||||
audio_buffer_.erase(audio_buffer_.begin(), audio_buffer_.end() - buffer_size);
|
||||
}
|
||||
@ -181,9 +183,10 @@ struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate {
|
||||
void audio_callback(Uint8 *stream, int len) {
|
||||
std::lock_guard<std::mutex> lock_guard(audio_buffer_mutex_);
|
||||
|
||||
std::size_t sample_length = static_cast<std::size_t>(len) / sizeof(int16_t);
|
||||
std::size_t copy_length = std::min(sample_length, audio_buffer_.size());
|
||||
int16_t *target = static_cast<int16_t *>(static_cast<void *>(stream));
|
||||
// SDL buffer length is in bytes, so there's no need to adjust for stereo/mono in here.
|
||||
const std::size_t sample_length = static_cast<std::size_t>(len) / sizeof(int16_t);
|
||||
const std::size_t copy_length = std::min(sample_length, audio_buffer_.size());
|
||||
int16_t *const target = static_cast<int16_t *>(static_cast<void *>(stream));
|
||||
|
||||
std::memcpy(stream, audio_buffer_.data(), copy_length * sizeof(int16_t));
|
||||
if(copy_length < sample_length) {
|
||||
@ -661,13 +664,14 @@ int main(int argc, char *argv[]) {
|
||||
desired_audio_spec.freq = 48000; // TODO: how can I get SDL to reveal the output rate of this machine?
|
||||
desired_audio_spec.format = AUDIO_S16;
|
||||
desired_audio_spec.channels = 1 + int(speaker->get_is_stereo());
|
||||
desired_audio_spec.samples = SpeakerDelegate::buffer_size;
|
||||
desired_audio_spec.samples = SpeakerDelegate::buffered_samples;
|
||||
desired_audio_spec.callback = SpeakerDelegate::SDL_audio_callback;
|
||||
desired_audio_spec.userdata = &speaker_delegate;
|
||||
|
||||
speaker_delegate.audio_device = SDL_OpenAudioDevice(nullptr, 0, &desired_audio_spec, &obtained_audio_spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
|
||||
speaker->set_output_rate(obtained_audio_spec.freq, desired_audio_spec.samples, speaker->get_is_stereo());
|
||||
speaker->set_output_rate(obtained_audio_spec.freq, desired_audio_spec.samples, obtained_audio_spec.channels == 2);
|
||||
speaker_delegate.is_stereo = obtained_audio_spec.channels == 2;
|
||||
speaker->set_delegate(&speaker_delegate);
|
||||
SDL_PauseAudioDevice(speaker_delegate.audio_device, 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user