mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Remove global state and add mic hot swapping
This commit is contained in:
		
							parent
							
								
									182d672c15
								
							
						
					
					
						commit
						f5df13eb24
					
				
					 6 changed files with 71 additions and 52 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue