@ -160,7 +160,8 @@ private:
class IAudioDevice final : public ServiceFramework < IAudioDevice > {
class IAudioDevice final : public ServiceFramework < IAudioDevice > {
public :
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 [ ] = {
static const FunctionInfo functions [ ] = {
{ 0 , & IAudioDevice : : ListAudioDeviceName , " ListAudioDeviceName " } ,
{ 0 , & IAudioDevice : : ListAudioDeviceName , " ListAudioDeviceName " } ,
{ 1 , & IAudioDevice : : SetAudioDeviceOutputVolume , " SetAudioDeviceOutputVolume " } ,
{ 1 , & IAudioDevice : : SetAudioDeviceOutputVolume , " SetAudioDeviceOutputVolume " } ,
@ -196,25 +197,40 @@ private:
" AudioTvOutput " ,
" AudioTvOutput " ,
" AudioUsbDeviceOutput " ,
" AudioUsbDeviceOutput " ,
} } ;
} } ;
enum class DeviceType {
AHUBHeadphones ,
AHUBSpeakers ,
HDA ,
USBOutput ,
} ;
void ListAudioDeviceName ( Kernel : : HLERequestContext & ctx ) {
void ListAudioDeviceName ( Kernel : : HLERequestContext & ctx ) {
LOG_WARNING ( Service_Audio , " (STUBBED) called " ) ;
LOG_DEBU G ( 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 ) ;
ctx . WriteBuffer ( name_buffer ) ;
IPC : : ResponseBuilder rb { ctx , 3 } ;
IPC : : ResponseBuilder rb { ctx , 3 } ;
rb . Push ( RESULT_SUCCESS ) ;
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 ) {
void SetAudioDeviceOutputVolume ( Kernel : : HLERequestContext & ctx ) {
@ -271,6 +287,7 @@ private:
rb . PushCopyObjects ( audio_output_device_switch_event . readable ) ;
rb . PushCopyObjects ( audio_output_device_switch_event . readable ) ;
}
}
u32_le revision = 0 ;
Kernel : : EventPair buffer_event ;
Kernel : : EventPair buffer_event ;
Kernel : : EventPair audio_output_device_switch_event ;
Kernel : : EventPair audio_output_device_switch_event ;
@ -597,12 +614,16 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
}
}
void AudRenU : : GetAudioDeviceService ( 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 . Push ( RESULT_SUCCESS ) ;
rb . PushIpcInterface < IAudioDevice > ( system ) ;
rb . PushIpcInterface < IAudioDevice > ( system , Common : : MakeMagic ( ' R ' , ' E ' , ' V ' , ' 1 ' ) ) ;
}
}
void AudRenU : : OpenAudioRendererAuto ( Kernel : : HLERequestContext & ctx ) {
void AudRenU : : OpenAudioRendererAuto ( Kernel : : HLERequestContext & ctx ) {
@ -612,14 +633,19 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
}
}
void AudRenU : : GetAudioDeviceServiceWithRevisionInfo ( 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 . Push ( RESULT_SUCCESS ) ;
rb . PushIpcInterface < IAudioDevice > ( system ) ;
rb . PushIpcInterface < IAudioDevice > ( system , revision ) ;
}
}
void AudRenU : : OpenAudioRendererImpl ( Kernel : : HLERequestContext & ctx ) {
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 ' ) ;
const u32_be version_num = revision - Common : : MakeMagic ( ' R ' , ' E ' , ' V ' , ' 0 ' ) ;
switch ( feature ) {
switch ( feature ) {
case AudioFeatures : : AudioUSBDeviceOutput :
return version_num > = 4U ;
case AudioFeatures : : Splitter :
case AudioFeatures : : Splitter :
return version_num > = 2U ;
return version_num > = 2U ;
case AudioFeatures : : PerformanceMetricsVersion2 :
case AudioFeatures : : PerformanceMetricsVersion2 :