So here is my final project during my undergrad final year, and i got to be honest... it was bad. And i will explain why.
Table of Contents
Background
Besides only as a developer, i am also a musician. And i need to find a way "How to make sure everyone in a small band stay in tempo without any complicated in-ear-monitoring setup?". Hence why this idea came to my mind.
I chose to use Nearby Connections API only because i have used it in my other project. And it also claimed that it is "high-bandwidth, low-latency, and fully encrypted to enable fast, secure data transfers.".
Idea & Implementation
The idea is to create a simple metronome app that can connect to other devices that uses the same app using client-server approach. The server can play/pause/set tempo/configure the metronome, while other devices/clients that is joined to the server can only receives the server's command.
I decided to use MVVM approach to my app. There are only two Fragment
s that serves as UI: the metronome page and the client-finding page. And there are only two Service
s that will run in the background: the metronome, and the connection manager. Every changes is applied to the UI using Binding Adapters and every function calls (and returns) from the UI to the Service
s has to go from the only global ViewModel
.
As mentioned, there are two services; MetronomeService
is responsible to do all the metronome stuff, and the ConnectionManagerService
- as the name implies - manages all the connection stuff. ConnectionManagerService
is also the only instance that has all the Nearby Connection API implementations.
Results and Regrets
The whole idea turns out to be a huge mistake. I cannot even sync the metronome ticks while being played together! It somehow started all synced but gradually turned not synced when played with the exact same tempo. I also implemented naive latency compensation but turns out Nearby's latency was too spread out. Nearby mentioned that they used combination of Bluetooth and Wi-Fi and it turns out to be true. But when the switch from Bluetooth to Wi-Fi happens, the latency just spikes uncontrollably between devices in the same server.
The mistakes turns out to be on both Services. On MetronomeService
, there is a possibility that the low latency audio not consistently played throughout devices. And on ConnectionManagerService
, the lack of granular control in Nearby makes things just... uncontrollable.
Future Works (!!!)
I really want this project to be successful and help musicians to do gigs better. It wont be updated in near future but i have made a simple roadmap for this app:
- Complete UI/UX redesign. The current ones looks like a bunch of placeholders.
- Replace current metronome audio implementation with something better. Oboe came out to my mind when i am thinking about this but i didn't have much time to implement that.
- Replace Nearby with Native Wi-Fi API. I do not know if it's possible but i was thinking to make the device that acts as a server also acts as a Wi-Fi Router that only accepts connections from clients that uses the app. I know there will be security obstacles to tackle out of this idea but if you have insights about what to use/what to do, please let me know!
- More metronome features! Right now, it is only a metronome that plays a beep in constant beats per minute. I want to add more features such as subdivisions, more sounds, accentuations, etc.
I really want to thank all stakeholders who helped me in this project. It was really a learning process throughout the project. By the way, here's the repo!
barjuandavis / wesync_kotlin
Wesync: Synchronized Metronome application made using Native Android SDK (Kotlin) and Nearby Connections API.
wesync_kotlin
And happy graduation to all of us!
Top comments (1)
Glad you're sticking with it Barjuan. It sounds really cool :)