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; | ||||
|     } | ||||
| 
 | ||||
|     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}; | ||||
|     impl->sample_queue->Push(samples); | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,9 +42,6 @@ ConfigureAudio::ConfigureAudio(QWidget* parent) | |||
|     connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, | ||||
|             &ConfigureAudio::updateAudioInputDevices); | ||||
| 
 | ||||
|     ui->input_type_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | ||||
|     ui->input_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | ||||
| 
 | ||||
|     this->setConfiguration(); | ||||
|     connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, | ||||
|             &ConfigureAudio::updateAudioOutputDevices); | ||||
|  | @ -142,12 +139,7 @@ void ConfigureAudio::updateAudioOutputDevices(int sink_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::updateAudioInputDevices(int index) {} | ||||
| 
 | ||||
| void ConfigureAudio::retranslateUi() { | ||||
|     ui->retranslateUi(this); | ||||
|  |  | |||
|  | @ -46,8 +46,10 @@ public: | |||
|      */ | ||||
|     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; | ||||
| 
 | ||||
|     /// Value from 0 - 100 to adjust the mic gain setting. Called by Core
 | ||||
|  | @ -111,8 +113,4 @@ private: | |||
|     std::vector<u8> CACHE_16_BIT; | ||||
| }; | ||||
| 
 | ||||
| void RegisterMic(std::shared_ptr<Mic::Interface> mic); | ||||
| 
 | ||||
| std::shared_ptr<Mic::Interface> GetCurrentMic(); | ||||
| 
 | ||||
| } // namespace Frontend::Mic
 | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #ifdef HAVE_CUBEB | ||||
| #include "audio_core/cubeb_input.h" | ||||
| #endif | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/frontend/mic.h" | ||||
|  | @ -12,6 +15,7 @@ | |||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/shared_memory.h" | ||||
| #include "core/hle/service/mic_u.h" | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| namespace Service::MIC { | ||||
| 
 | ||||
|  | @ -129,6 +133,9 @@ struct MIC_U::Impl { | |||
|     } | ||||
| 
 | ||||
|     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 (!mic->IsSampling()) { | ||||
|             return; | ||||
|  | @ -311,13 +318,49 @@ struct MIC_U::Impl { | |||
|         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; | ||||
|     Core::TimingEventType* buffer_write_event = nullptr; | ||||
|     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory; | ||||
|     u32 client_version = 0; | ||||
|     bool allow_shell_closed = false; | ||||
|     bool clamp = false; | ||||
|     std::shared_ptr<Frontend::Mic::Interface> mic; | ||||
|     std::unique_ptr<Frontend::Mic::Interface> mic; | ||||
|     Core::Timing& timing; | ||||
|     State state{}; | ||||
| }; | ||||
|  | @ -407,7 +450,7 @@ MIC_U::MIC_U(Core::System& system) | |||
|         {0x00100040, &MIC_U::SetClientVersion, "SetClientVersion"}, | ||||
|     }; | ||||
| 
 | ||||
|     impl->mic = Frontend::Mic::GetCurrentMic(); | ||||
|     impl->CreateMic(); | ||||
|     RegisterHandlers(functions); | ||||
| } | ||||
| 
 | ||||
|  | @ -415,25 +458,20 @@ MIC_U::~MIC_U() { | |||
|     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) { | ||||
|     auto& service_manager = system.ServiceManager(); | ||||
|     std::make_shared<MIC_U>(system)->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| } // 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); | ||||
|     ~MIC_U(); | ||||
| 
 | ||||
|     void ReloadMic(); | ||||
| 
 | ||||
| private: | ||||
|     /**
 | ||||
|      * MIC::MapSharedMem service function | ||||
|  | @ -190,6 +192,8 @@ private: | |||
|     std::unique_ptr<Impl> impl; | ||||
| }; | ||||
| 
 | ||||
| void ReloadMic(Core::System& system); | ||||
| 
 | ||||
| void InstallInterfaces(Core::System& system); | ||||
| 
 | ||||
| } // namespace Service::MIC
 | ||||
|  |  | |||
|  | @ -3,17 +3,14 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <utility> | ||||
| #if HAVE_CUBEB | ||||
| #include "audio_core/cubeb_input.h" | ||||
| #endif | ||||
| #include "audio_core/dsp_interface.h" | ||||
| #include "core/core.h" | ||||
| #include "core/frontend/emu_window.h" | ||||
| #include "core/frontend/mic.h" | ||||
| #include "core/gdbstub/gdbstub.h" | ||||
| #include "core/hle/service/hid/hid.h" | ||||
| #include "core/hle/service/ir/ir_rst.h" | ||||
| #include "core/hle/service/ir/ir_user.h" | ||||
| #include "core/hle/service/mic_u.h" | ||||
| #include "core/settings.h" | ||||
| #include "video_core/renderer_base.h" | ||||
| #include "video_core/video_core.h" | ||||
|  | @ -61,20 +58,8 @@ void Apply() { | |||
|         if (cam) { | ||||
|             cam->ReloadCameraDevices(); | ||||
|         } | ||||
|     } | ||||
|     // TODO support mic hotswapping by creating the new impl, and copying any parameters to it.
 | ||||
|     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; | ||||
| 
 | ||||
|         Service::MIC::ReloadMic(system); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -105,6 +90,8 @@ void LogSettings() { | |||
|     LogSetting("Audio_OutputEngine", Settings::values.sink_id); | ||||
|     LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching); | ||||
|     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; | ||||
|     LogSetting("Camera_OuterRightName", Settings::values.camera_name[OuterRightCamera]); | ||||
|     LogSetting("Camera_OuterRightConfig", Settings::values.camera_config[OuterRightCamera]); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue