sdl_mixer (3): if mono requested, capture stereo

Workaround for SDL3 mixer, that doesn't respect selected ch_count=1 now.

Reduced the channel count later in audio stack (this will work for other
acaps as well).
This commit is contained in:
Martin Pulec
2025-03-31 11:29:41 +02:00
parent 85679c4fad
commit 39554640f9
4 changed files with 52 additions and 5 deletions

View File

@@ -1141,6 +1141,11 @@ static void *audio_sender_thread(void *arg)
continue;
audio_frame2 bf_n(buffer);
if (audio_capture_channels != 0 &&
(int) audio_capture_channels !=
bf_n.get_channel_count()) {
bf_n.change_ch_count((int) audio_capture_channels);
}
// RESAMPLE
int resample_to = s->resample_to;

View File

@@ -37,7 +37,7 @@
/**
* @file
* @todo errata (SDL3 vs SDL2)
* 1. 1 channel capture (-a ch=1) seem no longer work
* 1. 1 channel capture (-a ch=1) seem no longer work but there is a workaround
* 2. unsufficient performance (generates overflow even in default config)
*/
@@ -205,6 +205,24 @@ static void try_open_soundfont() {
}
}
/// handle SDL 3.0.0 mixer not being able to capture mono
static void
adjust_ch_count(struct state_sdl_mixer_capture *s)
{
int frequency = 0;
SDL_AudioFormat format = { 0 };
int channels = 0;
Mix_QuerySpec(&frequency, &format, &channels);
if (audio_capture_channels > 0 &&
channels != (int) audio_capture_channels) {
MSG(INFO,
"%d channel capture seem to be broken with SDL3 "
"mixer - capture %d and reduce drop second later\n",
s->audio.ch_count, channels);
s->audio.ch_count = channels;
}
}
static void * audio_cap_sdl_mixer_init(struct module *parent, const char *cfg)
{
UNUSED(parent);
@@ -234,10 +252,6 @@ static void * audio_cap_sdl_mixer_init(struct module *parent, const char *cfg)
}
#ifdef HAVE_SDL3
if (s->audio.ch_count == 1) {
MSG(WARNING,
"! channel capture seem to be broken with SDL3 mixer...\n");
}
SDL_AudioSpec spec = {
.format = audio_format,
.channels = s->audio.ch_count,
@@ -251,6 +265,7 @@ static void * audio_cap_sdl_mixer_init(struct module *parent, const char *cfg)
log_msg(LOG_LEVEL_ERROR, MOD_NAME "error initalizing sound: %s\n", Mix_GetError());
goto error;
}
adjust_ch_count(s);
const char *filename = s->req_filename;
if (!filename) {
filename = load_song1();

View File

@@ -332,6 +332,32 @@ void audio_frame2::change_bps(int new_bps)
channels = std::move(new_channels);
}
/**
* simple ch_count changer - excess channels dropped, missing copied from the
* last one
*/
void audio_frame2::change_ch_count(int ch_count)
{
if ((unsigned) ch_count == channels.size()) {
return;
}
if ((unsigned) ch_count < channels.size()) {
channels.resize(ch_count);
return;
}
const channel &last_ch = channels.at(channels.size() - 1);
for (unsigned i = channels.size(); i < (unsigned) ch_count; ++i) {
std::unique_ptr<char[]> data =
std::unique_ptr<char[]>(new char[last_ch.len]);
memcpy(data.get(), last_ch.data.get(), last_ch.len);
channel ch = { std::move(data), last_ch.len, last_ch.len,
last_ch.fec_params };
channels.push_back(std::move(ch));
}
}
void audio_frame2::set_timestamp(int64_t ts)
{
assert(ts >= -1);

View File

@@ -178,6 +178,7 @@ public:
void set_fec_params(int channel, fec_desc const &);
[[nodiscard]] static audio_frame2 copy_with_bps_change(audio_frame2 const &frame, int new_bps);
void change_bps(int new_bps);
void change_ch_count(int new_ch_count);
/**
* @note
* bps of the frame needs to be 16 bits!