DEV Community

Barjuan Davis P.
Barjuan Davis P.

Posted on • Edited on

Synchronized Metronome on Android! 🎹 🎼 🎶 (it was bad.)

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 Fragments that serves as UI: the metronome page and the client-finding page. And there are only two Services 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 Services 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!

GitHub logo 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)

Collapse
 
aquahamzah profile image
Hamzah Malik

Glad you're sticking with it Barjuan. It sounds really cool :)