summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/audio
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/audio')
-rw-r--r--src/core/hle/service/audio/audren_u.cpp60
-rw-r--r--src/core/hle/service/audio/audren_u.h1
2 files changed, 45 insertions, 16 deletions
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 8a7bf8a79..5b0b7f17e 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -160,7 +160,8 @@ private:
class IAudioDevice final : public ServiceFramework<IAudioDevice> {
public:
- explicit IAudioDevice(Core::System& system) : ServiceFramework("IAudioDevice") {
+ explicit IAudioDevice(Core::System& system, u32_le revision_num)
+ : ServiceFramework("IAudioDevice"), revision{revision_num} {
static const FunctionInfo functions[] = {
{0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
{1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
@@ -196,25 +197,40 @@ private:
"AudioTvOutput",
"AudioUsbDeviceOutput",
}};
+ enum class DeviceType {
+ AHUBHeadphones,
+ AHUBSpeakers,
+ HDA,
+ USBOutput,
+ };
void ListAudioDeviceName(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "called");
- const std::size_t num_names_requested = ctx.GetWriteBufferSize() / sizeof(AudioDeviceName);
- const std::size_t num_to_copy = std::min(num_names_requested, audio_device_names.size());
- std::vector<AudioDeviceName> name_buffer(num_to_copy);
+ const bool usb_output_supported =
+ IsFeatureSupported(AudioFeatures::AudioUSBDeviceOutput, revision);
+ const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioDeviceName);
- for (std::size_t i = 0; i < num_to_copy; i++) {
- const auto& device_name = audio_device_names[i];
+ std::vector<AudioDeviceName> name_buffer;
+ name_buffer.reserve(audio_device_names.size());
- device_name.copy(name_buffer[i].data(), device_name.size());
+ for (std::size_t i = 0; i < count && i < audio_device_names.size(); i++) {
+ const auto type = static_cast<DeviceType>(i);
+
+ if (!usb_output_supported && type == DeviceType::USBOutput) {
+ continue;
+ }
+
+ const auto& device_name = audio_device_names[i];
+ auto& entry = name_buffer.emplace_back();
+ device_name.copy(entry.data(), device_name.size());
}
ctx.WriteBuffer(name_buffer);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u32>(num_to_copy));
+ rb.Push(static_cast<u32>(name_buffer.size()));
}
void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) {
@@ -271,6 +287,7 @@ private:
rb.PushCopyObjects(audio_output_device_switch_event.readable);
}
+ u32_le revision = 0;
Kernel::EventPair buffer_event;
Kernel::EventPair audio_output_device_switch_event;
@@ -597,12 +614,16 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
}
void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_Audio, "called");
+ IPC::RequestParser rp{ctx};
+ const u64 aruid = rp.Pop<u64>();
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ LOG_DEBUG(Service_Audio, "called. aruid={:016X}", aruid);
+ // Revisionless variant of GetAudioDeviceServiceWithRevisionInfo that
+ // always assumes the initial release revision (REV1).
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IAudioDevice>(system);
+ rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1'));
}
void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
@@ -612,14 +633,19 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
}
void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ struct Parameters {
+ u32 revision;
+ u64 aruid;
+ };
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ IPC::RequestParser rp{ctx};
+ const auto [revision, aruid] = rp.PopRaw<Parameters>();
- // TODO(ogniK): Figure out what is different based on the current revision
+ LOG_DEBUG(Service_Audio, "called. revision={:08X}, aruid={:016X}", revision, aruid);
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IAudioDevice>(system);
+ rb.PushIpcInterface<IAudioDevice>(system, revision);
}
void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) {
@@ -636,6 +662,8 @@ bool IsFeatureSupported(AudioFeatures feature, u32_le revision) {
const u32_be version_num = revision - Common::MakeMagic('R', 'E', 'V', '0');
switch (feature) {
+ case AudioFeatures::AudioUSBDeviceOutput:
+ return version_num >= 4U;
case AudioFeatures::Splitter:
return version_num >= 2U;
case AudioFeatures::PerformanceMetricsVersion2:
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 0f3aad501..4e0ccc792 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -36,6 +36,7 @@ private:
// Describes a particular audio feature that may be supported in a particular revision.
enum class AudioFeatures : u32 {
+ AudioUSBDeviceOutput,
Splitter,
PerformanceMetricsVersion2,
VariadicCommandBuffer,