Developing iOS tweaks: A case study of fetching system's audio buffer from sandboxed processes.

in #utopian-io6 years ago

Repositories

The projects I'm discussing are available here: audio visualizer and TCP/IP server for audio data.

Introduction; the issue

I'm a (relatively new to the scene) iOS tweak developer. I've forked the excellent Mitsuha tweak (audio visualizer for Music and Spotify) to upgrade it to iOS 11. "Mitsuha for Music" previously used an unreliable and extremely unstable method of getting audio data to visualize - assigning a new AudioMix to the AVPlayerItem. It was problematic - when the user skipped tracks the audio player left Mitsuha trying to visualize data from an object that no longer existed (sometimes Music replaced the AudioMix with a new instance leaving us with dangling pointers). This resulted in a segmentation fault. Spotify version was not plagued with such issues.

Looking for a solution

This left me searching for a more reliable method. The code present in Spotify version was a part of the answer. Instead of creating our own AudioMix and MTAudioProcessingTap (and so on) it relied on a clean hook of the AudioUnitRender function. This wasn't possible from the Music app, though.

I've stumbled upon an old call recording code snippet from StackOverflow - this solved another part of the riddle. I've swiftly put together a tweak that hooked into mediaserverd and instead of hooking into AudioUnitProcess (which I've tried in my first commit regarding this experiment) I've created a hook on the AudioUnitRender function (seen here). This allowed me to get audio data that's not influenced by the system media volume setting (at least on most devices; this is definitely the case with my iPhone 7+).

Getting access to the system-wide audio buffer from a sandboxed process

Now the last thing I had to achieve was to find a way to transmit the audio buffer data from mediaserverd to a sandboxed process (Music app!). I've tried everything described on the IPC page on the exceptionally informative iphonedevwiki, but the only way with the least amount of overhead added was to use either POSIX sockets or TCP/IP. POSIX sockets weren't possible on iOS 11 with sandboxed processes as clients, so I've chosen the latter. The initial implementation can be seen in the same commit I've mentioned earlier.

Fixing stability issues that became noticeable while implementing a new feature

Implementing a stable TCP/IP server was not easy. Despite many libraries being available for that purpose (for Objective-C) I've decided to do it the good old-fashioned C way to minimize overhead - keep that in mind this is a critical system process we're hooking into.

One issue I had at the beginning was that when I've manually killed mediaserverd the client would crash. This wasn't a problem in the Music app - mediaserverd usually restarted itself automatically, and restarting the app wasn't that big of a problem for the end user. At that point, though, I've been working on a visualizer for the lock screen - this meant hooking into SpringBoard (the iOS UI). When SpringBoard crashed it unloaded all the apps from memory - a huge potential for data loss.

Another issue with SpringBoard crashing was that when it came back (all daemons automatically restart themselves) it spammed mediaserverd with connection requests which brought it down (and consecutively SpringBoard also crashed due to the client sockets being unexpectedly closed).

I've added lots of checks (here and here) to combat these issues. This might've increased the overhead, but so far no users reported random crashes or freezes. I also haven't pushed any updates to the AudioSnapshotServer (the MSHook tweak seen in the commits I've linked - it was split into its own repo while I was preparing a stable release of MitsuhaXI 0.4.0) after 1.0.0. I believe it's stable now.

GitHub account

@Ominousness

Sort:  

@nepeta, I gave you an upvote on your first post! Please give me a follow and I will give you a follow in return!

Please also take a moment to read this post regarding bad behavior on Steemit.

Glad to finally see you on steem, have fun! :)

And don't forget me once you are rich :p

Welcome to Steem as well.
I think having some real code examples of what you did inside the post is always useful as well to show what you've done.

Thanks for the contribution and welcome to Utopian.io!

I saw you talking on Discord about the fact you were waiting on an account, so I'm really glad to see you finally got one and can start contributing! It was a very interesting read and it seems to be a great project, so I'm looking forward to see what else you contribute!

For future contributions I would suggest doing something similar to the updates you posted on Reddit and then shortly explain how you implemented the most important changes. Also, adding some images to your post is always appreciated.

Glad to have you on board!

Click here to see how your contribution was evaluated.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you!

I'd prefer to stay away from my reddit writing style on Steemit. My reddit posts are focused on getting people to try out and use my tweak instead of explaining the technological aspect behind it.

Maybe he meant the changelog?
I like changelogs, they are good for a general overview on what you did ;) :)

And then further describing the technological aspect behind it :)

But of course the specifics are up to you :)

Also gratulations for your first (very successfull) post here on steemit ;)

Congratulations @nepeta! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes received
Award for the number of upvotes

Click on any badge to view your own Board of Honor on SteemitBoard.

To support your work, I also upvoted your post!
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

Upvote this notification to help all Steemit users. Learn why here!

Hey @nepeta
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Contributing on Utopian
Learn how to contribute on our website or by watching this tutorial on Youtube.

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Congratulations @nepeta!
Your post was mentioned in the Steemit Hit Parade for newcomers in the following category:

  • Pending payout - Ranked 2 with $ 167,88

I also upvoted your post to increase its reward
If you like my work to promote newcomers and give them more visibility on Steemit, feel free to vote for my witness! You can do it here or use SteemConnect

hello, i like this post, i voted for you, i have followed you, hihi you, i have a private blog about coffee in steemit, maybe you like, i will share your opinion You will know there are many good things about my coffee blog, follow me, and vote for me, thank you, make a funny steemit