PS3 BT/USB Audio Passthrough

(Note: this blog post will be long winded, walking you through how I went about this, but you can skip all the technical detail and jump to the bottom for the goodies, click or head to Patched libaudio.sprx)

Arguably one of the best things about the PS4 is it''s controller, so naturally when I play on my PS3 I hook the DS4 before I let loose.

However, my most favourite feature has to be audio pass-through, as I game mainly at night in my room, so I can''t have the TV on max volume or any volume at all, and so it was ashame the PS3 couldn''t make use of this feature.

But can''t it? the PS3 does have an BT/USB audio out option but it seems for some reason only geared for voice chat, but that got me thinking, from an Library API point of view it makes sense to keep everything as similar as possible, if not the same at all with few changes, so it could be possible that the difference between audio to the TV and voice chat audio is as simple as:

audioOut = TV;

vs

audioOut = VOICE_CHAT;

entertained by the idea, i decided to start searching, the 1st place i checked was RPCS3, what better place to know how the console works then looking at it''s (effective) re-write.

I quickly found this

	CELL_AUDIO_PORTATTR_BGM            = 0x0000000000000010ULL,
	CELL_AUDIO_PORTATTR_INITLEVEL      = 0x0000000000001000ULL,
	CELL_AUDIO_PORTATTR_OUT_NO_ROUTE   = 0x0000000000100000ULL,
	CELL_AUDIO_PORTATTR_OUT_PERSONAL_0 = 0x0000000001000000ULL,
	CELL_AUDIO_PORTATTR_OUT_PERSONAL_1 = 0x0000000002000000ULL,
	CELL_AUDIO_PORTATTR_OUT_PERSONAL_2 = 0x0000000004000000ULL,
	CELL_AUDIO_PORTATTR_OUT_PERSONAL_3 = 0x0000000008000000ULL,
	CELL_AUDIO_PORTATTR_OUT_SECONDARY  = 0x0000000000000001ULL, 
    ...
    struct CellAudioPortParam
    { 
        be_t<u64> nChannel;
        be_t<u64> nBlock;
        be_t<u64> attr;
        be_t<float> level;
    }; 
    ...
    error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum);

what does that mean? it means my theory is correct, you see when a game wants to play audio, it has to select what and how to play it and it does that by calling cellAudioPortOpen() irrespective if it''s game music, character speaking or party member chat, the difference is the specific parameters that are passed, in this case attr seems to control where the audio is played... and just to be absolutely certain, I decided to look for a music player-esque homebrew to see if they do call this method and if so, how?, so I found CDG Player:

	AudioPortParam params;

	params.numChannels = AUDIO_CHANNEL_COUNT;
	params.numBlocks = AUDIO_BLOCK_COUNT;
	params.attr = 0;
	params.level = 1;

	audioPortOpen(&params, &audio_port);

params.attr = 0; they''re passing 0, so that''s likely the default value, but we want 0x1ULL, so what does that mean??? do we need to go around and patch every game and update every homebrew? NO, we can do one better, audioPortOpen() is part of PS3 library (the place where functions are stored), we can just edit the library and force params.attr to equal 0x1ULL, simple, right? if only insert sad emoji.
(Side note, it would have been smarter of me at this stage, to actually set this value to 0x1ULL, compile this app and see if it would even work... but me being me, with no foresight decided to do it the hard way..)

I decided to edit the library, it sounds simple, edit it and make sure it''s always set attr to 0x1ULL, how hard can it be... well 1st I need to figure out how can I decrypt and re-encypt the sprx libraries luckly @Zecoxao helped me with that one, next I needed to edit the library in... Assembly(ASM)... PowerPC(PPC) ASM... I barely know X86 ASM, and had Zer0 knowledge in PPC ASM... what am I to do???? well with some starting pointers from @AlexAltea and alot of googling and reading, a long night ensued, I started about 8:21PM and it wasn''t before 4:00AM that I decided to call it a night... (I woke up again at 7:00AM to a call from my cousin, on the other side of the global, worried that Amazon has double charged him for his PC build order of $1000 dollar, which I helped him pick.. long story short, he''s heading to or is in work and wanted me to deal with Amazon CS, when that was done I probably got another 2 hours of sleep)

Resuming where i left off.... earlier that morning XD
I went straight back to ASM reading, I''m reading the library trying to understand what it''s doing
Screen-Shot-2017-12-05-at-13.08.18
thats just a basic snippet of what I''m looking at, you can imagine for someone who has practically no experience in ASM trying to find attr isn''t as easy as it sounds, it took me all morning and into the afternoon and just about 1:30PM it clicked, well enough of it clicked for me to understand whats going on and what I need to edit, now to figure out HOW to edit it XD lucky enough the rest of this tale is much shorter, by 2:30PM i got it, yes I correctly modified the library and got audio coming out of DS4 audio jack. WINNING!!!!

Screen-Shot-2017-12-05-at-23.15.19

In RED are the instructions I removed, they check to make sure you''ve selected valid channel configuration (2 & 8 channels) if not they fail.
I removed them to make space for the instructions I added in GREEN, you see this is how to set attr to 0x1ULL.
then in YELLOW, I just had to modify the jump to the new offset, since we don''t have the conditions I removed in RED.

you may wonder, could removing those channel checks cause issues... I don''t believe so, since if those checks fail, they would most likely fail to every PS3 out there, so any games using invalid options wouldn''t be able to play sounds/music in game... and you can imagine a game with no sounds?? do you remember the last game that was published with no sounds? so it''s very very unlikely for devs to be using an invalid value, but in the very off chance they are?? since the check is removed, there is a chance they''ll crash the game or could just continue on like nothing is happening, potentially without sound, but as I already mentioned, they''re somewhat redundant in our case, thus safe to remove.
(there are few nop instructions below in the code, I''ve contemplated rearranging the code and removing them instead of removing the checks, but there was little harm to be done in the current implementation and this involved the least amount of changes, so i went with it.)

if you want to patch libaudio.sprx yourself these are the offsets and changes for 4.82 CEX (Rebug).

< 0000000000000F80  E8 03 00 00 2F A0 00 00  41 9E 00 0C 2F A0 00 02
< 0000000000000F90  40 9E 01 44 E8 7E 00 08  2F A3 00 02 41 9E 00 1C
---
> 0000000000000F80  38 00 00 01 F8 1E 00 10  E8 03 00 00 2F A0 00 00
> 0000000000000F90  41 9E 00 28 E8 7E 00 08  2F A3 00 02 41 9E 00 1C

Patched libaudio.sprx

Download: Patched libaudio.sprx
Note:This is for FW 4.82 CEX (Rebug) and I''m only going to provide them for FW I''m on(aka latest).(It''s has been reported that this library worked directly with 4.81 REX without resigning or modification, so you can try it at your own discretion)

How To Push libaudio.sprx To PS3

Fair warning: while modding this library in itself poses no real risk, modifying/deleting other files could cause issue.
With that said, even if you wipe your entire /dev_flash you can still access the recovery, as such you can reflash your FW.

Now, /dev_flash isn''t writable by default so you must mount it as /dev_blind. you can use different file manager to do so, but I''ve done it with WebMan MOD (open Setup->"webMAN MOD Setup"->"Enable /dev_blind (writable /dev_flash) on startup").

Then, using FTP or from USB, copy the patched libaudio.sprx to /dev_blind/sys/external/ (be sure to backup your original libaudio.sprx 1st, I renamed mine where it was to libaudio.sprx.bak), once you''re done make sure to unmount your /dev_blind and then go back to PS3 XMB.

The fun part is over, in the XMB go to "Settings"->"Accessory Settings"->"Audio Device Settings", and set your output device to your USB/BT Audio device, in my case the "Wireless Controller"(DS4), press OK and start your favourite game.

Note:

  1. This will only work with DS4 V2 and it has to connected by usb, but you can also use it with BT/USB headsets, we can''t at the moment connect to the BT audio chip on it
  2. Audio will automatically go to your TV if your selected output device is not connect to the PS3.
  3. This will only redirect Game Audio to your BT/USB device, the UI audio will remain on the TV.
  4. I also dont have any BT audio devices to test, so confirmation would be nice, Thanks.

P.S. If anyone have any idea how to connect to DS4 BT audio chip please let me know(even if it''s just for the PC), as such we can only get audio to DS4 via USB at the moment.

Never go full nop nop.
You can always contact me @Zer0xFF if you have any quaries, questions or concerns.