cellMic: Try to open device with different sample rates

This commit is contained in:
Megamouse 2025-03-27 01:02:34 +01:00
parent 282fbcc3e5
commit 41bb966519
3 changed files with 57 additions and 43 deletions

View file

@ -423,36 +423,40 @@ error_code microphone_device::open_microphone(const u8 type, const u32 dsp_r, co
break;
}
ALCdevice* device = nullptr;
// Make sure we use a proper sampling rate
const auto fixup_samplingrate = [this](u32& rate) -> bool
// TODO: The used sample rate may vary for Sony's camera devices
const std::array<u32, 7> samplingrates = { raw_samplingrate, 48000u, 32000u, 24000u, 16000u, 12000u, 8000u };
for (u32 samplingrate : samplingrates)
{
// TODO: The used sample rate may vary for Sony's camera devices
const std::array<u32, 7> samplingrates = { rate, 48000u, 32000u, 24000u, 16000u, 12000u, 8000u };
const auto test_samplingrate = [&samplingrates](const u32& rate)
if (!std::any_of(samplingrates.cbegin() + 1, samplingrates.cend(), [samplingrate](u32 r){ return r == samplingrate; }))
{
// TODO: actually check if device supports sampling rates
return std::any_of(samplingrates.cbegin() + 1, samplingrates.cend(), [&rate](const u32& r){ return r == rate; });
};
for (u32 samplingrate : samplingrates)
{
if (test_samplingrate(samplingrate))
{
// Use this sampling rate
raw_samplingrate = samplingrate;
cellMic.notice("Using sampling rate %d.", samplingrate);
return true;
}
cellMic.warning("Requested sampling rate %d, but we do not support it. Trying next sampling rate...", samplingrate);
continue;
}
return false;
};
cellMic.notice("Trying sampling rate %d with %d channel(s)", samplingrate, num_channels);
if (!fixup_samplingrate(raw_samplingrate))
device = open_device(devices[0].name, samplingrate, num_al_channels, inbuf_size);
if (!device)
{
continue;
}
// Use this sampling rate
raw_samplingrate = samplingrate;
cellMic.notice("Using sampling rate %d and %d channel(s)", raw_samplingrate, num_channels);
break;
}
if (!device)
{
cellMic.error("Failed to open capture device '%s' (raw_samplingrate=%d, num_al_channels=0x%x, inbuf_size=%d)", devices[0].name, raw_samplingrate, num_al_channels, inbuf_size);
#ifdef _WIN32
cellMic.error("Make sure microphone use is authorized under \"Microphone privacy settings\" in windows configuration");
#endif
return CELL_MICIN_ERROR_DEVICE_NOT_SUPPORT;
}
@ -460,29 +464,19 @@ error_code microphone_device::open_microphone(const u8 type, const u32 dsp_r, co
ensure(!devices.empty());
ALCdevice* device = alcCaptureOpenDevice(devices[0].name.c_str(), raw_samplingrate, num_al_channels, inbuf_size);
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
{
cellMic.error("Error opening capture device %s (error=%s, device=*0x%x)", devices[0].name, fmt::alc_error{device, err}, device);
#ifdef _WIN32
cellMic.error("Make sure microphone use is authorized under \"Microphone privacy settings\" in windows configuration");
#endif
return CELL_MICIN_ERROR_DEVICE_NOT_SUPPORT;
}
devices[0].device = device;
devices[0].buf.resize(inbuf_size, 0);
if (device_type == microphone_handler::singstar && devices.size() >= 2)
{
// Open a 2nd microphone into the same device
device = alcCaptureOpenDevice(devices[1].name.c_str(), raw_samplingrate, AL_FORMAT_MONO16, inbuf_size);
num_al_channels = AL_FORMAT_MONO16;
device = open_device(devices[1].name, raw_samplingrate, num_al_channels, inbuf_size);
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
if (!device)
{
// Ignore it and move on
cellMic.error("Error opening 2nd SingStar capture device %s (error=%s, device=*0x%x)", devices[1].name, fmt::alc_error{device, err}, device);
cellMic.error("Failed to open 2nd SingStar capture device '%s' (raw_samplingrate=%d, num_al_channels=0x%x, inbuf_size=%d)", devices[1].name, raw_samplingrate, num_al_channels, inbuf_size);
}
else
{
@ -517,7 +511,7 @@ error_code microphone_device::close_microphone()
{
if (alcCaptureCloseDevice(micdevice.device) != ALC_TRUE)
{
cellMic.error("Error closing capture device %s", micdevice.name);
cellMic.error("Error closing capture device '%s'", micdevice.name);
}
micdevice.device = nullptr;
@ -539,7 +533,7 @@ error_code microphone_device::start_microphone()
alcCaptureStart(micdevice.device);
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
{
cellMic.error("Error starting capture of device %s (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
cellMic.error("Error starting capture of device '%s' (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
stop_microphone();
return CELL_MICIN_ERROR_FATAL;
}
@ -558,7 +552,7 @@ error_code microphone_device::stop_microphone()
alcCaptureStop(micdevice.device);
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
{
cellMic.error("Error stopping capture of device %s (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
cellMic.error("Error stopping capture of device '%s' (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
}
}
#endif
@ -637,7 +631,7 @@ u32 microphone_device::capture_audio()
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
{
cellMic.error("Error getting number of captured samples of device %s (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
cellMic.error("Error getting number of captured samples of device '%s' (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
return CELL_MICIN_ERROR_FATAL;
}
@ -655,7 +649,7 @@ u32 microphone_device::capture_audio()
if (ALCenum err = alcGetError(micdevice.device); err != ALC_NO_ERROR)
{
cellMic.error("Error capturing samples of device %s (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
cellMic.error("Error capturing samples of device '%s' (error=%s)", micdevice.name, fmt::alc_error{micdevice.device, err});
}
}
@ -667,6 +661,21 @@ u32 microphone_device::capture_audio()
// Private functions
#ifndef WITHOUT_OPENAL
ALCdevice* microphone_device::open_device(std::string& name, u32 samplingrate, ALCenum num_al_channels, u32 buf_size)
{
ALCdevice* device = alcCaptureOpenDevice(name.c_str(), samplingrate, num_al_channels, buf_size);
if (ALCenum err = alcGetError(device); err != ALC_NO_ERROR || !device)
{
cellMic.warning("Failed to open capture device '%s' (error=%s, device=*0x%x, samplingrate=%d, num_al_channels=0x%x, buf_size=%d)", name, fmt::alc_error{device, err}, device, samplingrate, num_al_channels, buf_size);
device = nullptr;
}
return device;
}
#endif
void microphone_device::get_data(const u32 num_samples)
{
if (num_samples == 0)

View file

@ -326,6 +326,10 @@ private:
static inline void variable_byteswap(const void* src, void* dst);
inline u32 convert_16_bit_pcm_to_float(const std::vector<u8>& buffer, u32 num_bytes);
#ifndef WITHOUT_OPENAL
ALCdevice* open_device(std::string& name, u32 samplingrate, ALCenum num_al_channels, u32 buf_size);
#endif
u32 capture_audio();
void get_data(const u32 num_samples);

View file

@ -28,9 +28,9 @@ void microphone_creator::refresh_list()
{
if (const char* devices = alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER))
{
while (*devices != 0)
while (devices && *devices != 0)
{
cfg_log.notice("Found microphone: %s", devices);
cfg_log.notice("Found microphone: '%s'", devices);
m_microphone_list.append(devices);
devices += strlen(devices) + 1;
}
@ -43,6 +43,7 @@ void microphone_creator::refresh_list()
if (const char* device = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER))
{
cfg_log.notice("Found default microphone: '%s'", device);
m_microphone_list.append(device);
}
}