Project Andio
This commit is contained in:
		
							
								
								
									
										100
									
								
								src/audio_core/in/audio_in.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/audio_core/in/audio_in.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "audio_core/audio_in_manager.h" | ||||
| #include "audio_core/in/audio_in.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
|  | ||||
| namespace AudioCore::AudioIn { | ||||
|  | ||||
| In::In(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_) | ||||
|     : manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event, | ||||
|                                                                             session_id_} {} | ||||
|  | ||||
| void In::Free() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     manager.ReleaseSessionId(system.GetSessionId()); | ||||
| } | ||||
|  | ||||
| System& In::GetSystem() { | ||||
|     return system; | ||||
| } | ||||
|  | ||||
| AudioIn::State In::GetState() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.GetState(); | ||||
| } | ||||
|  | ||||
| Result In::StartSystem() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.Start(); | ||||
| } | ||||
|  | ||||
| void In::StartSession() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     system.StartSession(); | ||||
| } | ||||
|  | ||||
| Result In::StopSystem() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.Stop(); | ||||
| } | ||||
|  | ||||
| Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|  | ||||
|     if (system.AppendBuffer(buffer, tag)) { | ||||
|         return ResultSuccess; | ||||
|     } | ||||
|     return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED; | ||||
| } | ||||
|  | ||||
| void In::ReleaseAndRegisterBuffers() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     if (system.GetState() == State::Started) { | ||||
|         system.ReleaseBuffers(); | ||||
|         system.RegisterBuffers(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool In::FlushAudioInBuffers() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.FlushAudioInBuffers(); | ||||
| } | ||||
|  | ||||
| u32 In::GetReleasedBuffers(std::span<u64> tags) { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.GetReleasedBuffers(tags); | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& In::GetBufferEvent() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return event->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| f32 In::GetVolume() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.GetVolume(); | ||||
| } | ||||
|  | ||||
| void In::SetVolume(f32 volume) { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     system.SetVolume(volume); | ||||
| } | ||||
|  | ||||
| bool In::ContainsAudioBuffer(u64 tag) { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.ContainsAudioBuffer(tag); | ||||
| } | ||||
|  | ||||
| u32 In::GetBufferCount() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.GetBufferCount(); | ||||
| } | ||||
|  | ||||
| u64 In::GetPlayedSampleCount() { | ||||
|     std::scoped_lock l{parent_mutex}; | ||||
|     return system.GetPlayedSampleCount(); | ||||
| } | ||||
|  | ||||
| } // namespace AudioCore::AudioIn | ||||
							
								
								
									
										147
									
								
								src/audio_core/in/audio_in.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/audio_core/in/audio_in.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <mutex> | ||||
|  | ||||
| #include "audio_core/in/audio_in_system.h" | ||||
|  | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
|  | ||||
| namespace Kernel { | ||||
| class KEvent; | ||||
| class KReadableEvent; | ||||
| } // namespace Kernel | ||||
|  | ||||
| namespace AudioCore::AudioIn { | ||||
| class Manager; | ||||
|  | ||||
| /** | ||||
|  * Interface between the service and audio in system. Mainly responsible for forwarding service | ||||
|  * calls to the system. | ||||
|  */ | ||||
| class In { | ||||
| public: | ||||
|     explicit In(Core::System& system, Manager& manager, Kernel::KEvent* event, size_t session_id); | ||||
|  | ||||
|     /** | ||||
|      * Free this audio in from the audio in manager. | ||||
|      */ | ||||
|     void Free(); | ||||
|  | ||||
|     /** | ||||
|      * Get this audio in's system. | ||||
|      */ | ||||
|     System& GetSystem(); | ||||
|  | ||||
|     /** | ||||
|      * Get the current state. | ||||
|      * | ||||
|      * @return Started or Stopped. | ||||
|      */ | ||||
|     AudioIn::State GetState(); | ||||
|  | ||||
|     /** | ||||
|      * Start the system | ||||
|      * | ||||
|      * @return Result code | ||||
|      */ | ||||
|     Result StartSystem(); | ||||
|  | ||||
|     /** | ||||
|      * Start the system's device session. | ||||
|      */ | ||||
|     void StartSession(); | ||||
|  | ||||
|     /** | ||||
|      * Stop the system. | ||||
|      * | ||||
|      * @return Result code | ||||
|      */ | ||||
|     Result StopSystem(); | ||||
|  | ||||
|     /** | ||||
|      * Append a new buffer to the system, the buffer event will be signalled when it is filled. | ||||
|      * | ||||
|      * @param buffer - The new buffer to append. | ||||
|      * @param tag    - Unique tag for this buffer. | ||||
|      * @return Result code. | ||||
|      */ | ||||
|     Result AppendBuffer(const AudioInBuffer& buffer, u64 tag); | ||||
|  | ||||
|     /** | ||||
|      * Release all completed buffers, and register any appended. | ||||
|      */ | ||||
|     void ReleaseAndRegisterBuffers(); | ||||
|  | ||||
|     /** | ||||
|      * Flush all buffers. | ||||
|      */ | ||||
|     bool FlushAudioInBuffers(); | ||||
|  | ||||
|     /** | ||||
|      * Get all of the currently released buffers. | ||||
|      * | ||||
|      * @param tags - Output container for the buffer tags which were released. | ||||
|      * @return The number of buffers released. | ||||
|      */ | ||||
|     u32 GetReleasedBuffers(std::span<u64> tags); | ||||
|  | ||||
|     /** | ||||
|      * Get the buffer event for this audio in, this event will be signalled when a buffer is filled. | ||||
|      * | ||||
|      * @return The buffer event. | ||||
|      */ | ||||
|     Kernel::KReadableEvent& GetBufferEvent(); | ||||
|  | ||||
|     /** | ||||
|      * Get the current system volume. | ||||
|      * | ||||
|      * @return The current volume. | ||||
|      */ | ||||
|     f32 GetVolume(); | ||||
|  | ||||
|     /** | ||||
|      * Set the system volume. | ||||
|      * | ||||
|      * @param volume - The volume to set. | ||||
|      */ | ||||
|     void SetVolume(f32 volume); | ||||
|  | ||||
|     /** | ||||
|      * Check if a buffer is in the system. | ||||
|      * | ||||
|      * @param tag - The tag to search for. | ||||
|      * @return True if the buffer is in the system, otherwise false. | ||||
|      */ | ||||
|     bool ContainsAudioBuffer(u64 tag); | ||||
|  | ||||
|     /** | ||||
|      * Get the maximum number of buffers. | ||||
|      * | ||||
|      * @return The maximum number of buffers. | ||||
|      */ | ||||
|     u32 GetBufferCount(); | ||||
|  | ||||
|     /** | ||||
|      * Get the total played sample count for this audio in. | ||||
|      * | ||||
|      * @return The played sample count. | ||||
|      */ | ||||
|     u64 GetPlayedSampleCount(); | ||||
|  | ||||
| private: | ||||
|     /// The AudioIn::Manager this audio in is registered with | ||||
|     Manager& manager; | ||||
|     /// Manager's mutex | ||||
|     std::recursive_mutex& parent_mutex; | ||||
|     /// Buffer event, signalled when buffers are ready to be released | ||||
|     Kernel::KEvent* event; | ||||
|     /// Main audio in system | ||||
|     System system; | ||||
| }; | ||||
|  | ||||
| } // namespace AudioCore::AudioIn | ||||
							
								
								
									
										213
									
								
								src/audio_core/in/audio_in_system.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								src/audio_core/in/audio_in_system.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,213 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include <mutex> | ||||
| #include "audio_core/audio_event.h" | ||||
| #include "audio_core/audio_manager.h" | ||||
| #include "audio_core/in/audio_in_system.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
|  | ||||
| namespace AudioCore::AudioIn { | ||||
|  | ||||
| System::System(Core::System& system_, Kernel::KEvent* event_, const size_t session_id_) | ||||
|     : system{system_}, buffer_event{event_}, | ||||
|       session_id{session_id_}, session{std::make_unique<DeviceSession>(system_)} {} | ||||
|  | ||||
| System::~System() { | ||||
|     Finalize(); | ||||
| } | ||||
|  | ||||
| void System::Finalize() { | ||||
|     Stop(); | ||||
|     session->Finalize(); | ||||
|     buffer_event->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| void System::StartSession() { | ||||
|     session->Start(); | ||||
| } | ||||
|  | ||||
| size_t System::GetSessionId() const { | ||||
|     return session_id; | ||||
| } | ||||
|  | ||||
| std::string_view System::GetDefaultDeviceName() { | ||||
|     return "BuiltInHeadset"; | ||||
| } | ||||
|  | ||||
| std::string_view System::GetDefaultUacDeviceName() { | ||||
|     return "Uac"; | ||||
| } | ||||
|  | ||||
| Result System::IsConfigValid(const std::string_view device_name, | ||||
|                              const AudioInParameter& in_params) { | ||||
|     if ((device_name.size() > 0) && | ||||
|         (device_name != GetDefaultDeviceName() && device_name != GetDefaultUacDeviceName())) { | ||||
|         return Service::Audio::ERR_INVALID_DEVICE_NAME; | ||||
|     } | ||||
|  | ||||
|     if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { | ||||
|         return Service::Audio::ERR_INVALID_SAMPLE_RATE; | ||||
|     } | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| Result System::Initialize(std::string& device_name, const AudioInParameter& in_params, | ||||
|                           const u32 handle_, const u64 applet_resource_user_id_) { | ||||
|     auto result{IsConfigValid(device_name, in_params)}; | ||||
|     if (result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     handle = handle_; | ||||
|     applet_resource_user_id = applet_resource_user_id_; | ||||
|     if (device_name.empty() || device_name[0] == '\0') { | ||||
|         name = std::string(GetDefaultDeviceName()); | ||||
|     } else { | ||||
|         name = std::move(device_name); | ||||
|     } | ||||
|  | ||||
|     sample_rate = TargetSampleRate; | ||||
|     sample_format = SampleFormat::PcmInt16; | ||||
|     channel_count = in_params.channel_count <= 2 ? 2 : 6; | ||||
|     volume = 1.0f; | ||||
|     is_uac = name == "Uac"; | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| Result System::Start() { | ||||
|     if (state != State::Stopped) { | ||||
|         return Service::Audio::ERR_OPERATION_FAILED; | ||||
|     } | ||||
|  | ||||
|     session->Initialize(name, sample_format, channel_count, session_id, handle, | ||||
|                         applet_resource_user_id, Sink::StreamType::In); | ||||
|     session->SetVolume(volume); | ||||
|     session->Start(); | ||||
|     state = State::Started; | ||||
|  | ||||
|     std::vector<AudioBuffer> buffers_to_flush{}; | ||||
|     buffers.RegisterBuffers(buffers_to_flush); | ||||
|     session->AppendBuffers(buffers_to_flush); | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| Result System::Stop() { | ||||
|     if (state == State::Started) { | ||||
|         session->Stop(); | ||||
|         session->SetVolume(0.0f); | ||||
|         state = State::Stopped; | ||||
|     } | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| bool System::AppendBuffer(const AudioInBuffer& buffer, const u64 tag) { | ||||
|     if (buffers.GetTotalBufferCount() == BufferCount) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     AudioBuffer new_buffer{ | ||||
|         .played_timestamp = 0, .samples = buffer.samples, .tag = tag, .size = buffer.size}; | ||||
|  | ||||
|     buffers.AppendBuffer(new_buffer); | ||||
|     RegisterBuffers(); | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void System::RegisterBuffers() { | ||||
|     if (state == State::Started) { | ||||
|         std::vector<AudioBuffer> registered_buffers{}; | ||||
|         buffers.RegisterBuffers(registered_buffers); | ||||
|         session->AppendBuffers(registered_buffers); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void System::ReleaseBuffers() { | ||||
|     bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)}; | ||||
|  | ||||
|     if (signal) { | ||||
|         // Signal if any buffer was released, or if none are registered, we need more. | ||||
|         buffer_event->GetWritableEvent().Signal(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| u32 System::GetReleasedBuffers(std::span<u64> tags) { | ||||
|     return buffers.GetReleasedBuffers(tags); | ||||
| } | ||||
|  | ||||
| bool System::FlushAudioInBuffers() { | ||||
|     if (state != State::Started) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     u32 buffers_released{}; | ||||
|     buffers.FlushBuffers(buffers_released); | ||||
|  | ||||
|     if (buffers_released > 0) { | ||||
|         buffer_event->GetWritableEvent().Signal(); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| u16 System::GetChannelCount() const { | ||||
|     return channel_count; | ||||
| } | ||||
|  | ||||
| u32 System::GetSampleRate() const { | ||||
|     return sample_rate; | ||||
| } | ||||
|  | ||||
| SampleFormat System::GetSampleFormat() const { | ||||
|     return sample_format; | ||||
| } | ||||
|  | ||||
| State System::GetState() { | ||||
|     switch (state) { | ||||
|     case State::Started: | ||||
|     case State::Stopped: | ||||
|         return state; | ||||
|     default: | ||||
|         LOG_ERROR(Service_Audio, "AudioIn invalid state!"); | ||||
|         state = State::Stopped; | ||||
|         break; | ||||
|     } | ||||
|     return state; | ||||
| } | ||||
|  | ||||
| std::string System::GetName() const { | ||||
|     return name; | ||||
| } | ||||
|  | ||||
| f32 System::GetVolume() const { | ||||
|     return volume; | ||||
| } | ||||
|  | ||||
| void System::SetVolume(const f32 volume_) { | ||||
|     volume = volume_; | ||||
|     session->SetVolume(volume_); | ||||
| } | ||||
|  | ||||
| bool System::ContainsAudioBuffer(const u64 tag) { | ||||
|     return buffers.ContainsBuffer(tag); | ||||
| } | ||||
|  | ||||
| u32 System::GetBufferCount() { | ||||
|     return buffers.GetAppendedRegisteredCount(); | ||||
| } | ||||
|  | ||||
| u64 System::GetPlayedSampleCount() const { | ||||
|     return session->GetPlayedSampleCount(); | ||||
| } | ||||
|  | ||||
| bool System::IsUac() const { | ||||
|     return is_uac; | ||||
| } | ||||
|  | ||||
| } // namespace AudioCore::AudioIn | ||||
							
								
								
									
										275
									
								
								src/audio_core/in/audio_in_system.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								src/audio_core/in/audio_in_system.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,275 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <atomic> | ||||
| #include <memory> | ||||
| #include <span> | ||||
| #include <string> | ||||
|  | ||||
| #include "audio_core/common/common.h" | ||||
| #include "audio_core/device/audio_buffers.h" | ||||
| #include "audio_core/device/device_session.h" | ||||
| #include "core/hle/service/audio/errors.h" | ||||
|  | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
|  | ||||
| namespace Kernel { | ||||
| class KEvent; | ||||
| } | ||||
|  | ||||
| namespace AudioCore::AudioIn { | ||||
|  | ||||
| constexpr SessionTypes SessionType = SessionTypes::AudioIn; | ||||
|  | ||||
| struct AudioInParameter { | ||||
|     /* 0x0 */ s32_le sample_rate; | ||||
|     /* 0x4 */ u16_le channel_count; | ||||
|     /* 0x6 */ u16_le reserved; | ||||
| }; | ||||
| static_assert(sizeof(AudioInParameter) == 0x8, "AudioInParameter is an invalid size"); | ||||
|  | ||||
| struct AudioInParameterInternal { | ||||
|     /* 0x0 */ u32_le sample_rate; | ||||
|     /* 0x4 */ u32_le channel_count; | ||||
|     /* 0x8 */ u32_le sample_format; | ||||
|     /* 0xC */ u32_le state; | ||||
| }; | ||||
| static_assert(sizeof(AudioInParameterInternal) == 0x10, | ||||
|               "AudioInParameterInternal is an invalid size"); | ||||
|  | ||||
| struct AudioInBuffer { | ||||
|     /* 0x00 */ AudioInBuffer* next; | ||||
|     /* 0x08 */ VAddr samples; | ||||
|     /* 0x10 */ u64 capacity; | ||||
|     /* 0x18 */ u64 size; | ||||
|     /* 0x20 */ u64 offset; | ||||
| }; | ||||
| static_assert(sizeof(AudioInBuffer) == 0x28, "AudioInBuffer is an invalid size"); | ||||
|  | ||||
| enum class State { | ||||
|     Started, | ||||
|     Stopped, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Controls and drives audio input. | ||||
|  */ | ||||
| class System { | ||||
| public: | ||||
|     explicit System(Core::System& system, Kernel::KEvent* event, size_t session_id); | ||||
|     ~System(); | ||||
|  | ||||
|     /** | ||||
|      * Get the default audio input device name. | ||||
|      * | ||||
|      * @return The default audio input device name. | ||||
|      */ | ||||
|     std::string_view GetDefaultDeviceName(); | ||||
|  | ||||
|     /** | ||||
|      * Get the default USB audio input device name. | ||||
|      * This is preferred over non-USB as some games refuse to work with the BuiltInHeadset | ||||
|      * (e.g Let's Sing). | ||||
|      * | ||||
|      * @return The default USB audio input device name. | ||||
|      */ | ||||
|     std::string_view GetDefaultUacDeviceName(); | ||||
|  | ||||
|     /** | ||||
|      * Is the given initialize config valid? | ||||
|      * | ||||
|      * @param device_name - The name of the requested input device. | ||||
|      * @param in_params   - Input parameters, see AudioInParameter. | ||||
|      * @return Result code. | ||||
|      */ | ||||
|     Result IsConfigValid(std::string_view device_name, const AudioInParameter& in_params); | ||||
|  | ||||
|     /** | ||||
|      * Initialize this system. | ||||
|      * | ||||
|      * @param device_name             - The name of the requested input device. | ||||
|      * @param in_params               - Input parameters, see AudioInParameter. | ||||
|      * @param handle                  - Unused. | ||||
|      * @param applet_resource_user_id - Unused. | ||||
|      * @return Result code. | ||||
|      */ | ||||
|     Result Initialize(std::string& device_name, const AudioInParameter& in_params, u32 handle, | ||||
|                       u64 applet_resource_user_id); | ||||
|  | ||||
|     /** | ||||
|      * Start this system. | ||||
|      * | ||||
|      * @return Result code. | ||||
|      */ | ||||
|     Result Start(); | ||||
|  | ||||
|     /** | ||||
|      * Stop this system. | ||||
|      * | ||||
|      * @return Result code. | ||||
|      */ | ||||
|     Result Stop(); | ||||
|  | ||||
|     /** | ||||
|      * Finalize this system. | ||||
|      */ | ||||
|     void Finalize(); | ||||
|  | ||||
|     /** | ||||
|      * Start this system's device session. | ||||
|      */ | ||||
|     void StartSession(); | ||||
|  | ||||
|     /** | ||||
|      * Get this system's id. | ||||
|      */ | ||||
|     size_t GetSessionId() const; | ||||
|  | ||||
|     /** | ||||
|      * Append a new buffer to the device. | ||||
|      * | ||||
|      * @param buffer - New buffer to append. | ||||
|      * @param tag    - Unique tag of the buffer. | ||||
|      * @return True if the buffer was appended, otherwise false. | ||||
|      */ | ||||
|     bool AppendBuffer(const AudioInBuffer& buffer, u64 tag); | ||||
|  | ||||
|     /** | ||||
|      * Register all appended buffers. | ||||
|      */ | ||||
|     void RegisterBuffers(); | ||||
|  | ||||
|     /** | ||||
|      * Release all registered buffers. | ||||
|      */ | ||||
|     void ReleaseBuffers(); | ||||
|  | ||||
|     /** | ||||
|      * Get all released buffers. | ||||
|      * | ||||
|      * @param tags - Container to be filled with the released buffers' tags. | ||||
|      * @return The number of buffers released. | ||||
|      */ | ||||
|     u32 GetReleasedBuffers(std::span<u64> tags); | ||||
|  | ||||
|     /** | ||||
|      * Flush all appended and registered buffers. | ||||
|      * | ||||
|      * @return True if buffers were successfully flushed, otherwise false. | ||||
|      */ | ||||
|     bool FlushAudioInBuffers(); | ||||
|  | ||||
|     /** | ||||
|      * Get this system's current channel count. | ||||
|      * | ||||
|      * @return The channel count. | ||||
|      */ | ||||
|     u16 GetChannelCount() const; | ||||
|  | ||||
|     /** | ||||
|      * Get this system's current sample rate. | ||||
|      * | ||||
|      * @return The sample rate. | ||||
|      */ | ||||
|     u32 GetSampleRate() const; | ||||
|  | ||||
|     /** | ||||
|      * Get this system's current sample format. | ||||
|      * | ||||
|      * @return The sample format. | ||||
|      */ | ||||
|     SampleFormat GetSampleFormat() const; | ||||
|  | ||||
|     /** | ||||
|      * Get this system's current state. | ||||
|      * | ||||
|      * @return The current state. | ||||
|      */ | ||||
|     State GetState(); | ||||
|  | ||||
|     /** | ||||
|      * Get this system's name. | ||||
|      * | ||||
|      * @return The system's name. | ||||
|      */ | ||||
|     std::string GetName() const; | ||||
|  | ||||
|     /** | ||||
|      * Get this system's current volume. | ||||
|      * | ||||
|      * @return The system's current volume. | ||||
|      */ | ||||
|     f32 GetVolume() const; | ||||
|  | ||||
|     /** | ||||
|      * Set this system's current volume. | ||||
|      * | ||||
|      * @param The new volume. | ||||
|      */ | ||||
|     void SetVolume(f32 volume); | ||||
|  | ||||
|     /** | ||||
|      * Does the system contain this buffer? | ||||
|      * | ||||
|      * @param tag - Unique tag to search for. | ||||
|      * @return True if the buffer is in the system, otherwise false. | ||||
|      */ | ||||
|     bool ContainsAudioBuffer(u64 tag); | ||||
|  | ||||
|     /** | ||||
|      * Get the maximum number of usable buffers (default 32). | ||||
|      * | ||||
|      * @return The number of buffers. | ||||
|      */ | ||||
|     u32 GetBufferCount(); | ||||
|  | ||||
|     /** | ||||
|      * Get the total number of samples played by this system. | ||||
|      * | ||||
|      * @return The number of samples. | ||||
|      */ | ||||
|     u64 GetPlayedSampleCount() const; | ||||
|  | ||||
|     /** | ||||
|      * Is this system using a USB device? | ||||
|      * | ||||
|      * @return True if using a USB device, otherwise false. | ||||
|      */ | ||||
|     bool IsUac() const; | ||||
|  | ||||
| private: | ||||
|     /// Core system | ||||
|     Core::System& system; | ||||
|     /// (Unused) | ||||
|     u32 handle{}; | ||||
|     /// (Unused) | ||||
|     u64 applet_resource_user_id{}; | ||||
|     /// Buffer event, signalled when a buffer is ready | ||||
|     Kernel::KEvent* buffer_event; | ||||
|     /// Session id of this system | ||||
|     size_t session_id{}; | ||||
|     /// Device session for this system | ||||
|     std::unique_ptr<DeviceSession> session; | ||||
|     /// Audio buffers in use by this system | ||||
|     AudioBuffers<BufferCount> buffers{BufferCount}; | ||||
|     /// Sample rate of this system | ||||
|     u32 sample_rate{}; | ||||
|     /// Sample format of this system | ||||
|     SampleFormat sample_format{SampleFormat::PcmInt16}; | ||||
|     /// Channel count of this system | ||||
|     u16 channel_count{}; | ||||
|     /// State of this system | ||||
|     std::atomic<State> state{State::Stopped}; | ||||
|     /// Name of this system | ||||
|     std::string name{}; | ||||
|     /// Volume of this system | ||||
|     f32 volume{1.0f}; | ||||
|     /// Is this system's device USB? | ||||
|     bool is_uac{false}; | ||||
| }; | ||||
|  | ||||
| } // namespace AudioCore::AudioIn | ||||
		Reference in New Issue
	
	Block a user