cellMic: Implement SIGSTATE_MICENG

This commit is contained in:
trigger 2025-02-20 01:57:41 -08:00 committed by GitHub
parent 26e0f56bf9
commit 1e01511ca0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 1 deletions

View file

@ -8,6 +8,7 @@
#include <Emu/Cell/lv2/sys_event.h>
#include <numeric>
#include <cmath>
#include "3rdparty/OpenAL/openal-soft/include/AL/alext.h"
@ -575,6 +576,28 @@ bool microphone_device::has_data() const
return mic_registered && mic_opened && mic_started && (rbuf_raw.has_data() || rbuf_dsp.has_data());
}
f32 microphone_device::calculate_energy_level()
{
const auto& buffer = device_type == microphone_handler::real_singstar ? ::at32(devices, 0).buf : temp_buf;
const size_t num_samples = buffer.size() / sizeof(s16);
f64 sum_squares = 0.0;
for (usz i = 0; i < num_samples; i++)
{
const be_t<s16> sample = read_from_ptr<be_t<s16>>(buffer, i * sizeof(s16));
const f64 normalized_sample = static_cast<f64>(sample) / -std::numeric_limits<s16>::min();
sum_squares += normalized_sample * normalized_sample;
}
const f32 rms = std::sqrt(sum_squares / num_samples);
const f32 decibels_max = 90.0f;
const f32 decibels_relative = 20.0f * std::log10(std::max(rms, 0.00001f));
const f32 decibels = decibels_max + (decibels_relative * 0.5f);
return std::clamp(decibels, 40.0f, decibels_max);
}
u32 microphone_device::capture_audio()
{
ensure(sample_size > 0);
@ -1089,7 +1112,7 @@ error_code cellMicGetSignalState(s32 dev_num, CellMicSignalState sig_state, vm::
*fval = 1.0f; // No gain applied
break;
case CELLMIC_SIGSTATE_MICENG:
*fval = 40.0f; // 40 decibels
*fval = device.calculate_energy_level();
break;
case CELLMIC_SIGSTATE_SPKENG:
*fval = 10.0f; // 10 decibels

View file

@ -289,6 +289,8 @@ public:
void update_audio();
bool has_data() const;
f32 calculate_energy_level();
bool is_registered() const { return mic_registered; }
bool is_opened() const { return mic_opened; }
bool is_started() const { return mic_started; }