Hey there! This is the project I've submmited to WWDC 2022 and got approved (hehe), it's a very short app, but it was a very big challenge for me to make it and I'm very proud of it.
The goal of my app is to show you how music works in a fundamental level, how sound waves make us feel things.
It was made for iPad, so please run it in one or a simulator to have a nice experience.
Well, good news! I updated the repository so it has an app version of my project rather than a playground version, which means that by having the code in the main branch you will just need to run my project as you would with any other app in xcode!
You can also use the playgrounds version if you like, it's in the playground branch!
If you want to run it in a playground here are the options I know work:
- Run it in the simulator in XCode, the simulalator can be very slow and the animations might not be so fluid.
- Deploy it on an iOS or iPadOS device, using the simulator is way better if you're not deploying on an iPad. When you deploy it, the sound might not be working properly at first, so try to reopen it or pause and play the sound again.
- Open this code in the Swift Playgrounds App (this is obviously the preferred option).
To use the Swift Playgrounds App
- You can simply download the Swift Playgrounds App for free in the iPad App Store
- Download my code here
- And open it in the Swift Playgrounds App.
It's a sound frequency generator with a graphical interface that can be edited in real time. You can control 3 sound waves that are added up to form a resultant wave, you can listen to this wave at the same time that you see its form drawn on the screen. The waves' frequencies can be controlled by sliders, pickers and buttons. The app has 4 pages, each one with a different wave controller interface.
In each page there is also an info button that you can tap to read some text to learn about the basics of tuning systems, every text is related to the page you access it from. It's really cool to toy with it, I promise.
Here's a little of onboarding on the code I've written.
I've separated the app's core logic in 3 parts: wave abstraction, wave drawing and sound generation. Let's start from the beggining.
So, to show and play waves, I needed first to find a way to compute and process them. So I created a protocol called Wave, that represented the important information I needed about a general wave (a pure wave or a resultant of the sum of 3 pure waves)
Then I made the actual abstractions for the kinds of waves I would need in my app.
PureWave:
And a WaveSum:
Now that I had a way to represent the waves, I had to draw them.
Alright, so to draw and show the drawings on the screen I made a SwiftUI view that displays in its body a custom shape, called WavePath:
So now that I had a way to draw any kind of wave I wanted on the screen, I needed to play them
This was definetively the hardest thing I had to code in this project. First there wasn't a lot of documentation about how to generate pure frequency sounds programmaticaly in swift, I had to dig a lot to find something, and I did! This is the amazing medium post explaining how to use the AVSourceNode, which is the property of the Synth class that does all the sound generation magic, you can see that my code is completely based on what Grant explains there.
However, the approach he made in the medium post did not allow me to change the sound in real time, there were some severe bugs to the sound playing when I edited the sound wave frequency while listening to it. To fix that, I dug a little deeper and saw that he had a github repository with updated code! And guess what? He made it in a way that the sound could be edited in real time without deafening the user! (Grant, I have no idea who you are, but your posts made this project possible, so mad respect, and thank you :D)
After studying his code I made the corrections in my own code and also adapted it to not only play a single frequency (as his project), but 3 frequencies at the same time!
It was an amazing experience and I could not feel more rewarded when I pressed play... and it simply played the sound I was telling it to play.
Of course this isn't near all that I went through to make this work. There were a lot of much harder to solve bugs and I had to break and rebuild my head multiple times to get to a UI that satisfied me, felt good and didn't break my Synth, wave drawing or any other features.
So that's it, hope you enjoy playing with my project as much as I enjoyed making it (I REALLY did)!