Skip to content
In development, not on Google Play yet

Loudly

Turns a room full of phones into one speaker: every phone plays the same song at the same moment, with no internet.

Role
Solo developer
Platform
Android
Stack
Kotlin, Jetpack Compose
Started
April 2026
Loudly party room: the host's room code, an everyone-in-sync banner and the playing track

Two problems, one app.

For the people using it

Friends, music, and nobody brought a speaker.

It started at a jam with friends in college. Nobody had a speaker, but everyone had a phone. Loudly turns those phones into one sound system: one person hosts, everyone else joins with a code, and every phone plays the same song at the same moment.

Why it's hard

Press play on five phones and they drift apart in seconds.

Every phone has a different processor, scheduler and speaker delay, and ears hear 20 to 30 ms as an echo. Sonos, AirPlay and Chromecast solve this with their own hardware. Loudly does it in software, on ordinary Android phones, with no internet. I'm building it alone.

What was at stake.

  1. Ears are unforgiving

    A gap of 20 to 30 ms between two phones already sounds like an echo.

  2. No two phones are alike

    Different processors, schedulers and speaker delays all pull the timing apart.

  3. No internet, no server

    Discovery, timing and the music itself all have to travel phone to phone.

  4. Links change mid-song

    A connection can drop to Bluetooth or a guest can walk away, and the party has to carry on.

If you only read one part, read this.

~11 ms timing error, by the app's own reading

Steady on two phones on 8 October 2026, and in sync by ear. A microphone test is still to come.

0 internet needed

Phones talk directly over Wi-Fi Direct or Bluetooth, picked automatically.

5+ phones tested together

In one room, playing the same song.

15 phones per room, the goal

One host and up to 14 guests. Scaling to it is the work now.

From no speaker to one big one.

  1. Host

    Create a room in one tap.

    Loudly home: one room, one speaker, with Create Room and Join Room buttons

    Hosting is one tap; joining is a 6-character code.

    One room, one speaker. The host creates a room; everyone else joins it. Rooms you've hosted are kept for next time.

    • Jetpack Compose
    • Material 3
    • Navigation
  2. Name it

    Name the room, get a code.

    Create a room sheet with the name Friday jam and a Create and start hosting button

    A 6-character code is generated automatically.

    Give the room a name friends will recognise. The code is made for you and the room is saved, so the next party starts faster.

    • Room
    • DataStore
  3. Join

    Join by code, or just walk in.

    Join a room screen with six code boxes and a nearby-rooms scanner, no rooms found yet

    Wi-Fi Direct or Bluetooth, chosen automatically.

    Guests type the code or pick the room from the nearby list. Phones connect to each other directly, with no internet needed.

    • Nearby Connections
    • Wi-Fi Direct
    • Bluetooth
  4. Play

    Every phone, the same moment.

    Party room playing a track, with an everyone-in-sync banner and the speakers list

    Live sync status for the room, and for every speaker.

    The host picks a song from their library and controls play, pause, seek, volume and track for the whole room. A banner says whether everyone is in sync, and late joiners drop into the song mid-play.

    • MediaCodec
    • AudioTrack
    • Opus

One app, taken apart.

Layer 1

What you tap

Jetpack Compose and Material 3, with one ViewModel, state and intent per screen. Screens never touch audio or radios.

  • Jetpack Compose
  • Material 3
  • MVI

Layer 2

What keeps time

Pure Kotlin rules in the middle, and one sync engine that is the only place allowed to work out clock offsets.

  • SyncEngine
  • Audio pipeline
  • Use cases
  • Hilt
  • Flow

Layer 3

What makes the sound

Android's own decoders and low-level audio output, with Opus over a peer-to-peer link.

  • Nearby Connections
  • MediaCodec
  • AudioTrack
  • Opus

One song, start to finish.

  1. Room created: The host gets a 6-character code
  2. Guests join: By code or nearby, peer to peer
  3. Clocks agree: Every phone's clock is lined up
  4. Song streams: Sent to every phone as Opus
  5. Play together: Every phone starts at the same instant
  6. Late joiners: Snap into the song mid-play

Everything happens phone to phone. There is no server anywhere in the loop.

HostLoudlyGuests

Calls I made, and why.

One place owns time.

Only the sync engine works out clock offsets and drift. Screens never touch audio, codecs or radios, so timing bugs have one place to live.

Never fail silently.

When a guest drops to a slow Bluetooth link, the room says so, the sync targets relax and the stream bitrate falls from 128 to 48 kbps.

128 → 48 kbps on slow links

People leave and come back.

A guest that loses the host tries three times, four seconds apart. The host keeps a dropped guest's place for 15 seconds, and a returning guest rejoins mid-song.

Measured, not guessed.

Changes are checked on real phones with the app's own timing readings, and by ear. A microphone recording of the phones playing together is the next check.

Where it stands.

Loudly isn't on Google Play yet. On 8 October 2026, on two phones, the app's own timing reading settled at about 11 ms and the music was in sync by ear. A microphone test on two and three phones is next. The screens here are from a test build on an emulator.

timing error, app reading on two phones
~11 ms
internet or servers needed
0
phones tested together
5+
phones per room, the goal
15

What I'd build for you.

If your product lives in real time

Audio, timing and live updates where milliseconds matter, measured on real devices.

If your app has to work offline

Peer-to-peer features that keep going with no internet and no server.

If you're hiring for Android

Kotlin from Compose screens down to MediaCodec and AudioTrack, with coroutines and Flow throughout.

If you have a hard problem

Someone who checks on real devices before claiming a result.

What's next.

  • A microphone test on two and three phones
  • Release on Google Play

Built with.

  • Kotlin
  • Jetpack Compose
  • Material 3
  • Hilt
  • Coroutines and Flow
  • Nearby Connections
  • MediaCodec
  • AudioTrack
  • Opus
  • Room
  • DataStore
See the whole stack
Next projectGeoFenceA group shares a fenced area, and the moment anyone leaves it, everyone else is told, without GPS drift crying wolf.