more refactoring, audio loopback kinda working

This commit is contained in:
2024-05-03 13:59:50 +02:00
parent 803bce93fb
commit 568d1a3f93
5 changed files with 163 additions and 39 deletions

View File

@@ -1,10 +1,9 @@
#include "./sdl_audio_frame_stream2.hpp"
#include "SDL_audio.h"
#include <iostream>
#include <vector>
SDLAudioInputDevice::SDLAudioInputDevice(void) : _stream{nullptr, &SDL_DestroyAudioStream} {
SDLAudioInputDeviceDefault::SDLAudioInputDeviceDefault(void) : _stream{nullptr, &SDL_DestroyAudioStream} {
constexpr SDL_AudioSpec spec = { SDL_AUDIO_S16, 1, 48000 };
_stream = {
@@ -70,10 +69,102 @@ SDLAudioInputDevice::SDLAudioInputDevice(void) : _stream{nullptr, &SDL_DestroyAu
});
}
SDLAudioInputDevice::~SDLAudioInputDevice(void) {
SDLAudioInputDeviceDefault::~SDLAudioInputDeviceDefault(void) {
// TODO: pause audio device?
_thread_should_quit = true;
_thread.join();
// TODO: what to do if readers are still present?
}
int32_t SDLAudioOutputDeviceDefaultInstance::size(void) {
return -1;
}
std::optional<AudioFrame> SDLAudioOutputDeviceDefaultInstance::pop(void) {
assert(false);
// this is an output device, there is no data to pop
return std::nullopt;
}
bool SDLAudioOutputDeviceDefaultInstance::push(const AudioFrame& value) {
if (!static_cast<bool>(_stream)) {
return false;
}
// verify here the fame has the same sample type, channel count and sample freq
// if something changed, we need to either use a temporary stream, just for conversion, or reopen _stream with the new params
// because of data temporality, the second options looks like a better candidate
if (
value.sample_rate != _last_sample_rate ||
value.channels != _last_channels ||
(value.isF32() && _last_format != SDL_AUDIO_F32) ||
(value.isS16() && _last_format != SDL_AUDIO_S16)
) {
const auto device_id = SDL_GetAudioStreamDevice(_stream.get());
SDL_FlushAudioStream(_stream.get());
const SDL_AudioSpec spec = {
static_cast<SDL_AudioFormat>((value.isF32() ? SDL_AUDIO_F32 : SDL_AUDIO_S16)),
static_cast<int>(value.channels),
static_cast<int>(value.sample_rate)
};
_stream = {
SDL_OpenAudioDeviceStream(device_id, &spec, nullptr, nullptr),
&SDL_DestroyAudioStream
};
}
// HACK
assert(value.isS16());
auto data = value.getSpan<int16_t>();
if (data.size == 0) {
std::cerr << "empty audio frame??\n";
}
if (SDL_PutAudioStreamData(_stream.get(), data.ptr, data.size * sizeof(int16_t)) < 0) {
std::cerr << "put data error\n";
return false; // return true?
}
_last_sample_rate = value.sample_rate;
_last_channels = value.channels;
_last_format = value.isF32() ? SDL_AUDIO_F32 : SDL_AUDIO_S16;
return true;
}
SDLAudioOutputDeviceDefaultInstance::SDLAudioOutputDeviceDefaultInstance(void) : _stream(nullptr, nullptr) {
}
SDLAudioOutputDeviceDefaultInstance::SDLAudioOutputDeviceDefaultInstance(SDLAudioOutputDeviceDefaultInstance&& other) : _stream(std::move(other._stream)) {
}
SDLAudioOutputDeviceDefaultInstance::~SDLAudioOutputDeviceDefaultInstance(void) {
}
SDLAudioOutputDeviceDefaultInstance SDLAudioOutputDeviceDefaultFactory::create(void) {
SDLAudioOutputDeviceDefaultInstance new_instance;
constexpr SDL_AudioSpec spec = { SDL_AUDIO_S16, 1, 48000 };
new_instance._stream = {
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec, nullptr, nullptr),
&SDL_DestroyAudioStream
};
new_instance._last_sample_rate = spec.freq;
new_instance._last_channels = spec.channels;
new_instance._last_format = spec.format;
if (!static_cast<bool>(new_instance._stream)) {
std::cerr << "SDL open audio device failed!\n";
}
const auto audio_device_id = SDL_GetAudioStreamDevice(new_instance._stream.get());
SDL_ResumeAudioDevice(audio_device_id);
return new_instance;
}