The engine, live

Hear the difference

Press one. The recording plays, the waveform draws, and the engine works through it stage by stage in front of you. It gets a heart rate, it gets a mother, or it gets nothing, and it tells you which.

Nothing selected

Pick a recording

Nothing is uploaded and nothing leaves this page. The audio is fetched, analysed in your browser and forgotten when you close the tab.

Signal clarity0%
  • load the recording at 1000 Hz
  • band pass 20 to 200 Hz, then Shannon envelope
  • autocorrelation window by window
  • comb scoring and octave repair
  • track across windows
  • decide, or refuse to

Nothing here is uploaded. The audio file is fetched, decoded and analysed inside this tab, and it is gone when you close it. There is no account, no cookie and no request to any other domain. Open your browser network tab and check.

What you are actually watching

This is not a demo animation with the answers written in. It is the real signal chain, ported line by line from the Python that was validated against the research databases, and it is doing the work while you look at it.

  1. Resample to 1000 Hz. Heart sounds live under 200 Hz, so everything above is thrown away first. Polyphase resampling, same filter design as the reference implementation.
  2. Band pass, 20 to 200 Hz. A fourth order Butterworth as four cascaded biquads, causal, with the exact coefficients the app uses. Below 20 Hz is body movement and rumble, above 200 Hz is almost never a heart.
  3. Shannon envelope. The trick that makes the quiet second sound survive. Squaring alone favours the loud thump, and a fetal second sound is not loud.
  4. Autocorrelation, window by window. Eight second windows, two second hop, normalised so long lags are not penalised. Penalising them is exactly how a mother at 70 turns into a baby at 140.
  5. Comb scoring with a structural tie break. A comb rejects the gap between the two sounds of one beat. When two candidate periods are harmonically related and the comb cannot separate them, the shape of the folded cycle decides.
  6. Track and repair octaves. A heart cannot double its rate in two seconds. Isolated slips are repaired against the running median, and whatever is still far away is dropped rather than guessed at.
  7. Decide, or refuse. A rate is published only when enough windows agree, the rhythm sits in the fetal band and the track is stable. Otherwise the verdict is the mother, or nothing.

Why the second clip matters more than the first

Anybody can build something that reacts to a strong heartbeat. The hard part of this category is the mother, because her pulse is the loudest thing in the room and at rest it sits at exactly the frequency that, doubled, lands in the middle of the fetal range.

That is the trap. An app that just looks for the strongest repeating thing will find your pulse, double it, and hand you a beautiful 142. It is one of the two complaints that dominate the reviews of this category. In the corpus of 1,995 reviews we read, 171 of them describe hearing their own heart and not being able to tell.

The engine has three separate defences against that, and you can see the effect on clip two. It knows the maternal band from the fetal band. It refuses rhythms that are an exact integer multiple of the loud one, because two real hearts never sit at exactly 2.000 to 1. And in the app, not in this browser demo, it reads your actual pulse from your Apple Watch or your camera and refuses anything that matches it or its harmonics. The long version is here.

Where the recordings come from

All three are real audio from open databases hosted by PhysioNet, downloadable by anyone. We did not record them and we did not clean them up. Each clip is 20 seconds, converted to 1000 Hz mono and normalised in volume so you can hear it, which changes nothing the engine cares about.

PhysioNet distributes both databases under the Open Data Commons Attribution Licence. Attribution given here, as the licence asks.
ClipSourceLicence
A baby at 35 weeksShiraz University Fetal Heart Sounds Database, record f86. Database pageOpen Data Commons Attribution
A mother's own heartSame database, maternal recording m111Open Data Commons Attribution
Nothing in itPhysioNet CinC Challenge 2016 heart sound set, record f0034. Database pageOpen Data Commons Attribution

How we know the browser agrees with the app

A tool like this is worthless if it is a simplified copy of the real thing. So the port is checked against the reference implementation by a script, not by eye.

Ten control recordings, chosen to hit every branch of the decision and spanning four different sample rates, are run through the reference Python and through the browser engine, and sixteen fields are compared per case: the verdict, the heart rate to two decimal places, which path produced it, the coverage and coherence to four decimals, the tracking spread, the second rhythm and its source. All ten match on all sixteen. The check runs before every deploy and the build stops if it does not.

The same script also regenerates the filter coefficients from scratch and compares them with the ones baked into the browser engine, so the two cannot drift apart quietly. The largest disagreement anywhere in the filter design is 2.78 times ten to the minus seventeen, which is the floor of double precision arithmetic.

What this tool does not prove

It proves the engine is real, that it is the same engine, and that it will refuse when there is nothing there. It does not prove your iPhone will pick up your baby through your own belly, because these recordings were made with dedicated sensors and not with a phone.

That measurement is the one thing standing between this app and a launch date, and it is being done with real recordings before any of the interface is finished. When we have it, the number goes on this page whatever it says.

Know the day it opens

One email, the day Firstsong is on the App Store, with the price on the first line. If the phone measurement comes back badly, that email will say so instead.

One email, the day it opens

Firstsong is not on the App Store yet. Leave an address and you get exactly one message when it is, with the price on the first line. No newsletter, no drip, no partner offers. You can reply to that email and a person reads it.

Stored on our own server, never sold, never shared. Your IP is hashed, not kept. Nothing about your pregnancy is asked for or stored.

Questions about the tool

Is the audio really analysed in my browser?

Yes. Open the network tab before you press a clip. You will see one request for a WAV file from this domain and nothing else, ever. There is no server doing the maths.

Why does the baby clip sound so muffled?

Because that is what it sounds like. The useful band is 20 to 200 Hz, which is below almost everything you normally listen to. Anything crisper than this in a competing app is either a filter making it pretty or a recording that is not coming from a belly.

Can I test my own recording here?

Not yet. Accepting uploads would mean handling audio of someone's pregnancy on a server, and we would rather not hold that at all than promise to hold it carefully. If that changes it will be file selection that never leaves your browser, same as this.

Why 1000 Hz? That sounds low.

Because it is exactly twice the top of the useful range with room to spare, and it is the rate the engine works at internally. Serving the clips at the engine's own working rate means the audio you hear and the numbers you see come from the same samples, with no conversion in between to argue about.

What happens on the clip with nothing in it?

The coverage comes out at zero, which means not one window in the whole recording found a rhythm it trusted. The engine reports no heartbeat found. That is the correct answer and it is the one the category avoids giving.

Keep reading

Last checked 2026-08-23