mirror of
https://github.com/citra-mirror/citra.git
synced 2024-08-19 18:13:21 +02:00
Remove global state and add mic hot swapping
This commit is contained in:
parent
182d672c15
commit
f5df13eb24
@ -113,7 +113,7 @@ long CubebInput::Impl::DataCallback(cubeb_stream* stream, void* user_data, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 const* data = reinterpret_cast<u8 const*>(input_buffer);
|
const u8* data = reinterpret_cast<const u8*>(input_buffer);
|
||||||
std::vector<u8> samples{data, data + num_frames * impl->sample_size_in_bytes};
|
std::vector<u8> samples{data, data + num_frames * impl->sample_size_in_bytes};
|
||||||
impl->sample_queue->Push(samples);
|
impl->sample_queue->Push(samples);
|
||||||
|
|
||||||
|
@ -42,9 +42,6 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
|
|||||||
connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureAudio::updateAudioInputDevices);
|
&ConfigureAudio::updateAudioInputDevices);
|
||||||
|
|
||||||
ui->input_type_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
|
||||||
ui->input_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
|
||||||
|
|
||||||
this->setConfiguration();
|
this->setConfiguration();
|
||||||
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureAudio::updateAudioOutputDevices);
|
&ConfigureAudio::updateAudioOutputDevices);
|
||||||
@ -142,12 +139,7 @@ void ConfigureAudio::updateAudioOutputDevices(int sink_index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::updateAudioInputDevices(int index) {
|
void ConfigureAudio::updateAudioInputDevices(int index) {}
|
||||||
// TODO: Don't hardcode this to the index for "Real Device" without making it a constant
|
|
||||||
// somewhere
|
|
||||||
ui->input_device_combo_box->setEnabled(index == 1 &&
|
|
||||||
!Core::System::GetInstance().IsPoweredOn());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureAudio::retranslateUi() {
|
void ConfigureAudio::retranslateUi() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
|
@ -46,8 +46,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual Samples Read() = 0;
|
virtual Samples Read() = 0;
|
||||||
|
|
||||||
/// Adjusts the Parameters. Implementations should update the parameters field in addition to
|
/**
|
||||||
/// changing the mic to sample according to the new parameters. Called by Core
|
* Adjusts the Parameters. Implementations should update the parameters field in addition to
|
||||||
|
* changing the mic to sample according to the new parameters. Called by Core
|
||||||
|
*/
|
||||||
virtual void AdjustSampleRate(u32 sample_rate) = 0;
|
virtual void AdjustSampleRate(u32 sample_rate) = 0;
|
||||||
|
|
||||||
/// Value from 0 - 100 to adjust the mic gain setting. Called by Core
|
/// Value from 0 - 100 to adjust the mic gain setting. Called by Core
|
||||||
@ -111,8 +113,4 @@ private:
|
|||||||
std::vector<u8> CACHE_16_BIT;
|
std::vector<u8> CACHE_16_BIT;
|
||||||
};
|
};
|
||||||
|
|
||||||
void RegisterMic(std::shared_ptr<Mic::Interface> mic);
|
|
||||||
|
|
||||||
std::shared_ptr<Mic::Interface> GetCurrentMic();
|
|
||||||
|
|
||||||
} // namespace Frontend::Mic
|
} // namespace Frontend::Mic
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#ifdef HAVE_CUBEB
|
||||||
|
#include "audio_core/cubeb_input.h"
|
||||||
|
#endif
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/mic.h"
|
#include "core/frontend/mic.h"
|
||||||
@ -12,6 +15,7 @@
|
|||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
#include "core/hle/service/mic_u.h"
|
#include "core/hle/service/mic_u.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
|
||||||
namespace Service::MIC {
|
namespace Service::MIC {
|
||||||
|
|
||||||
@ -129,6 +133,9 @@ struct MIC_U::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UpdateSharedMemBuffer(u64 userdata, s64 cycles_late) {
|
void UpdateSharedMemBuffer(u64 userdata, s64 cycles_late) {
|
||||||
|
if (change_mic_impl_requested.exchange(false)) {
|
||||||
|
CreateMic();
|
||||||
|
}
|
||||||
// If the event was scheduled before the application requested the mic to stop sampling
|
// If the event was scheduled before the application requested the mic to stop sampling
|
||||||
if (!mic->IsSampling()) {
|
if (!mic->IsSampling()) {
|
||||||
return;
|
return;
|
||||||
@ -311,13 +318,49 @@ struct MIC_U::Impl {
|
|||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateMic() {
|
||||||
|
std::unique_ptr<Frontend::Mic::Interface> new_mic;
|
||||||
|
switch (Settings::values.mic_input_type) {
|
||||||
|
case Settings::MicInputType::None:
|
||||||
|
new_mic = std::make_unique<Frontend::Mic::NullMic>();
|
||||||
|
break;
|
||||||
|
case Settings::MicInputType::Real:
|
||||||
|
#if HAVE_CUBEB
|
||||||
|
new_mic = std::make_unique<AudioCore::CubebInput>();
|
||||||
|
#else
|
||||||
|
new_mic = std::make_unique<Frontend::Mic::NullMic>();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case Settings::MicInputType::Static:
|
||||||
|
new_mic = std::make_unique<Frontend::Mic::StaticMic>();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_CRITICAL(Audio, "Mic type not found. Defaulting to null mic");
|
||||||
|
new_mic = std::make_unique<Frontend::Mic::NullMic>();
|
||||||
|
}
|
||||||
|
// If theres already a mic, copy over any data to the new mic impl
|
||||||
|
if (mic) {
|
||||||
|
new_mic->SetGain(mic->GetGain());
|
||||||
|
new_mic->SetPower(mic->GetPower());
|
||||||
|
auto params = mic->GetParameters();
|
||||||
|
if (mic->IsSampling()) {
|
||||||
|
mic->StopSampling();
|
||||||
|
new_mic->StartSampling(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mic = std::move(new_mic);
|
||||||
|
change_mic_impl_requested.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::atomic<bool> change_mic_impl_requested = false;
|
||||||
Kernel::SharedPtr<Kernel::Event> buffer_full_event;
|
Kernel::SharedPtr<Kernel::Event> buffer_full_event;
|
||||||
Core::TimingEventType* buffer_write_event = nullptr;
|
Core::TimingEventType* buffer_write_event = nullptr;
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
|
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
|
||||||
u32 client_version = 0;
|
u32 client_version = 0;
|
||||||
bool allow_shell_closed = false;
|
bool allow_shell_closed = false;
|
||||||
bool clamp = false;
|
bool clamp = false;
|
||||||
std::shared_ptr<Frontend::Mic::Interface> mic;
|
std::unique_ptr<Frontend::Mic::Interface> mic;
|
||||||
Core::Timing& timing;
|
Core::Timing& timing;
|
||||||
State state{};
|
State state{};
|
||||||
};
|
};
|
||||||
@ -407,7 +450,7 @@ MIC_U::MIC_U(Core::System& system)
|
|||||||
{0x00100040, &MIC_U::SetClientVersion, "SetClientVersion"},
|
{0x00100040, &MIC_U::SetClientVersion, "SetClientVersion"},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl->mic = Frontend::Mic::GetCurrentMic();
|
impl->CreateMic();
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,25 +458,20 @@ MIC_U::~MIC_U() {
|
|||||||
impl->mic->StopSampling();
|
impl->mic->StopSampling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MIC_U::ReloadMic() {
|
||||||
|
impl->change_mic_impl_requested.store(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReloadMic(Core::System& system) {
|
||||||
|
auto micu = system.ServiceManager().GetService<Service::MIC::MIC_U>("mic:u");
|
||||||
|
if (!micu)
|
||||||
|
return;
|
||||||
|
micu->ReloadMic();
|
||||||
|
}
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto& service_manager = system.ServiceManager();
|
auto& service_manager = system.ServiceManager();
|
||||||
std::make_shared<MIC_U>(system)->InstallAsService(service_manager);
|
std::make_shared<MIC_U>(system)->InstallAsService(service_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::MIC
|
} // namespace Service::MIC
|
||||||
|
|
||||||
namespace Frontend::Mic {
|
|
||||||
static std::shared_ptr<Mic::Interface> current_mic;
|
|
||||||
|
|
||||||
void RegisterMic(std::shared_ptr<Mic::Interface> mic) {
|
|
||||||
current_mic = mic;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Mic::Interface> GetCurrentMic() {
|
|
||||||
if (!current_mic) {
|
|
||||||
current_mic = std::make_shared<Mic::NullMic>();
|
|
||||||
}
|
|
||||||
return current_mic;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Frontend::Mic
|
|
||||||
|
@ -19,6 +19,8 @@ public:
|
|||||||
explicit MIC_U(Core::System& system);
|
explicit MIC_U(Core::System& system);
|
||||||
~MIC_U();
|
~MIC_U();
|
||||||
|
|
||||||
|
void ReloadMic();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* MIC::MapSharedMem service function
|
* MIC::MapSharedMem service function
|
||||||
@ -190,6 +192,8 @@ private:
|
|||||||
std::unique_ptr<Impl> impl;
|
std::unique_ptr<Impl> impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ReloadMic(Core::System& system);
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system);
|
void InstallInterfaces(Core::System& system);
|
||||||
|
|
||||||
} // namespace Service::MIC
|
} // namespace Service::MIC
|
||||||
|
@ -3,17 +3,14 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#if HAVE_CUBEB
|
|
||||||
#include "audio_core/cubeb_input.h"
|
|
||||||
#endif
|
|
||||||
#include "audio_core/dsp_interface.h"
|
#include "audio_core/dsp_interface.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "core/frontend/mic.h"
|
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/hle/service/hid/hid.h"
|
#include "core/hle/service/hid/hid.h"
|
||||||
#include "core/hle/service/ir/ir_rst.h"
|
#include "core/hle/service/ir/ir_rst.h"
|
||||||
#include "core/hle/service/ir/ir_user.h"
|
#include "core/hle/service/ir/ir_user.h"
|
||||||
|
#include "core/hle/service/mic_u.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
@ -61,20 +58,8 @@ void Apply() {
|
|||||||
if (cam) {
|
if (cam) {
|
||||||
cam->ReloadCameraDevices();
|
cam->ReloadCameraDevices();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// TODO support mic hotswapping by creating the new impl, and copying any parameters to it.
|
Service::MIC::ReloadMic(system);
|
||||||
switch (Settings::values.mic_input_type) {
|
|
||||||
case Settings::MicInputType::None:
|
|
||||||
Frontend::Mic::RegisterMic(std::make_shared<Frontend::Mic::NullMic>());
|
|
||||||
break;
|
|
||||||
case Settings::MicInputType::Real:
|
|
||||||
#if HAVE_CUBEB
|
|
||||||
Frontend::Mic::RegisterMic(std::make_shared<AudioCore::CubebInput>());
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case Settings::MicInputType::Static:
|
|
||||||
Frontend::Mic::RegisterMic(std::make_shared<Frontend::Mic::StaticMic>());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +90,8 @@ void LogSettings() {
|
|||||||
LogSetting("Audio_OutputEngine", Settings::values.sink_id);
|
LogSetting("Audio_OutputEngine", Settings::values.sink_id);
|
||||||
LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching);
|
LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching);
|
||||||
LogSetting("Audio_OutputDevice", Settings::values.audio_device_id);
|
LogSetting("Audio_OutputDevice", Settings::values.audio_device_id);
|
||||||
|
LogSetting("Audio_InputDeviceType", static_cast<int>(Settings::values.mic_input_type));
|
||||||
|
LogSetting("Audio_InputDevice", Settings::values.mic_input_device);
|
||||||
using namespace Service::CAM;
|
using namespace Service::CAM;
|
||||||
LogSetting("Camera_OuterRightName", Settings::values.camera_name[OuterRightCamera]);
|
LogSetting("Camera_OuterRightName", Settings::values.camera_name[OuterRightCamera]);
|
||||||
LogSetting("Camera_OuterRightConfig", Settings::values.camera_config[OuterRightCamera]);
|
LogSetting("Camera_OuterRightConfig", Settings::values.camera_config[OuterRightCamera]);
|
||||||
|
Loading…
Reference in New Issue
Block a user