Robot36: decoding SSTV images from audio on Android
Decode SSTV encoded audio signals to images
At a glance
- What is it?
- Robot36 is an Android application that decodes Slow Scan Television signals into images, from a live microphone, a recorded file or the audio of another app. The unexpected part of the repository is the hardware section, which works out the resistor and capacitor values for a line-level to microphone-level adapter that makes decoding far more reliable.
- Who is it for?
- Adopt Robot36 if you receive SSTV transmissions and want to turn them into images on an Android phone without a dedicated receiver and decoder. Do not expect it to work from an MP3 without artefacts, because the README is explicit that the lossy compression can introduce image noise, colour errors or decoding failures, so prefer an original WAV or FLAC.
- Can I use it commercially?
- Yes. 0BSD is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the application does, and the three ways audio gets in
Robot36 is an SSTV image decoder, and the README is organised around where the audio comes from rather than around features.
The microphone input decodes live SSTV audio. The file input imports WAV, which can be 8, 16, 24 or 32-bit integer PCM or 32 or 64-bit IEEE float, or FLAC, or MP3. And the playback capture input decodes audio playing in other apps on Android 10 or later, after granting system capture permission.
That last one is the most interesting and the most constrained. Android 10 introduced the ability for an app to capture the audio another app is playing, with the user's permission. That turns the phone into a receiver for any SSTV transmission that is playing out loud, whether it comes from a radio app, a browser or a message.
The file input has a detail that matters in practice. Mono and stereo files at 8 to 192 kHz use their own sample rate and channel count, independently of the microphone settings. So a 44.1 kHz stereo file and a live microphone signal at whatever rate the device uses do not have to be reconciled, and the decoder is not forcing a common rate across both paths.
The format list is also more careful than it first looks. WAV is accepted at 8, 16, 24 and 32-bit integer PCM and at 32 and 64-bit IEEE float, which is the full set of practical WAV encodings, and FLAC and MP3 are handled through the platform's own media components.
The project is by xdsopl, written in Java, with the 0BSD licence, the default branch v2, and a project page on Google Sites. The releases are v2.17 on 2026-09-15, v2.16 on 2025-11-11 and v2.15 on 2025-02-26, and the last push was on 2026-10-03.
File mode, and the difference between normal playback and Turbo
The file workflow is short. In File mode you tap plus to choose a file and then press Play.
Two things happen on that Play press, and they are different. Normal playback includes audible monitoring, which means you hear the audio as it is decoded. Turbo decodes without playback and without real-time pacing, so it runs as fast as the device can manage rather than at the speed the recording plays back.
The Turbo distinction matters because SSTV images are transmitted in real time, with the slowest common mode taking seconds per line, and a full image takes a meaningful fraction of a minute. A recording of a transmission is therefore the same duration as the transmission, and in Turbo mode the decoder is not bound by that duration at all. The README is careful to say the speed depends on the device and on the SSTV mode, so it is a practical speedup rather than a guarantee of instant decoding.
Two more behaviours are documented and both are the kind of detail that only matters after the first time something went wrong. Stopping and pressing Play again restarts the file, so the decoder does not resume from where it stopped. And at the end, the decoder drains its buffered audio so complete images can be saved when automatic saving is enabled.
That last one is the reason the drain exists. The final frame of an SSTV transmission is often incomplete, because the transmission stopped mid-frame, and if the decoder discarded its buffer at the end you would lose the last complete image in the file. Draining what is left costs nothing and can be worth one image.
The repository layout matches a normal Android application project. There is an app/ directory for the application module, build.gradle, settings.gradle, gradle.properties, the gradle wrapper with gradlew and gradlew.bat, and a fastlane/ directory, which is the tooling for automated store submissions. The topic list on the repository is just dsp and sstv, which is an accurate description of what this is.
The limitations, and why the file format matters more than usual
There is a Limitations section with three entries, and each one is a real constraint on how well decoding will work.
The first is about MP3. Prefer original WAV or FLAC recordings, because MP3 is lossy and may introduce image noise, colour errors, or decoding failures, and a brief, non-blocking notice appears on each MP3 selection. Other compressed formats are not currently supported.
This is the interesting one, because SSTV is unusually sensitive to lossy compression in a way that ordinary audio is not. An SSTV image is encoded as a series of audio tones, one scan line at a time, where the frequency carries the pixel value and the timing carries the position. A lossy codec smears the tone transitions and adds artifacts, and the decoder reads those artifacts as pixel values. The result is an image with noise, wrong colours, or no decode at all, and no amount of decoding cleverness recovers information the codec has already destroyed.
The second limitation is about precision. MP3 and FLAC use Android's media components, and on some devices 24-bit FLAC is output as 16-bit PCM, so full source precision is not guaranteed. That is a platform limitation rather than a design choice, and it means the practical ceiling on FLAC fidelity varies by phone.
The third is about playback capture: it depends on the source app allowing its audio to be captured, and it cannot capture every app or stream. Some apps set themselves as un-capturable, and protected streams will not appear at all.
None of these are bugs, and the way the README handles them is worth noting. The MP3 notice is non-blocking, so the app still lets you try an MP3 rather than refusing it, and it tells you once, at selection, that the result may be poor. The first entry also names the good paths, WAV and FLAC, so a user who wants clean images has an actionable instruction rather than a complaint.
Combined, the three limitations describe a tool that works best when you feed it the raw signal and degrades predictably otherwise, which is the right shape for something that is fundamentally about signal integrity.
The line-level converter, and why a phone needs one
The second half of the README is a hardware section, and it is the most distinctive part of the project.
The premise is that decoding SSTV signals is more reliable with a clean input, and that using a direct cable connection instead of acoustic coupling avoids echo, distortion and environmental noise. That is obvious in principle. The rest of the section works out how to do it on a phone, and the reason it is not obvious is that a phone's headset input is a microphone input, not a line input.
Most smartphones use TRRS connectors for headsets. In these connectors the sleeve and the second ring, next to the sleeve, serve dual roles: depending on the standard, one is the microphone input and the other is ground. The tip and first ring carry the left and right audio channels. And when a TRS plug is inserted into a TRRS jack, the sleeve and second ring are shorted together, which is what allows regular stereo headphones without a microphone to work correctly.
Using a line-level output, from a radio or a sound card, as a microphone input brings several problems, and the README lists them.
Line-level signals swing around 1 V while electret microphones produce signals in the millivolt range, so attenuation is needed. Electret microphones are biased via the TRRS connector, allowing their internal amplifiers to function, and that bias must be blocked to avoid distortion. And to make the smartphone recognise the input as a microphone, a resistor must be placed between the second ring and the sleeve.
Rather than working out which pin is MIC and which is GND for each device, the README recommends galvanic isolation, which avoids compatibility issues, eliminates ground loops, protects against damage and makes the result more dependable. That is the core of the design: the transformer does the level shifting and the isolation at once, so you do not have to know the pinout of the particular phone.
There is also a neat trick for reducing the power consumption of the line-out device. A higher impedance can be achieved by inserting a resistor in series with the primary winding of a 1:1 audio transformer, and if the source cannot drive high impedance the primary can be connected directly and attenuation applied on the secondary side, which increases power consumption and may heat the transformer.
And because the electret mic input is high-impedance and AC-coupled, the transformer's secondary can resonate if left unterminated. Adding a resistor across the secondary dampens this resonance and flattens the frequency response, with a value equal to the transformer's impedance being typical, and a lower value used to improve damping and add attenuation. The ratio of the series resistor on the primary to the parallel resistor on the secondary determines the overall attenuation.
The schematic, and the component values that go with it
The README gives a complete worked design, and the combination of a schematic and a full list of parts is what makes it buildable rather than merely described.
The circuit is this:
[Line IN] O---[R1]---+||+---+---|C1|---+---O [Ring 2]
S||S | |
T1: S||S [R2] [R3]
S||S | |
[Line GND] O----------+||+---+----------+---O [Sleeve]The symbols are then explained one by one. R1 is the 2.2 kOhm series resistor for primary side attenuation. T1 is the 1:1 audio transformer. C1 is the 2.2 microfarad capacitor for DC blocking. R2 is the 100 Ohm damping resistor across the secondary. R3 is the 2.2 kOhm MIC detect resistor between MIC and GND. Line IN and Line GND are the input from the radio or sound card, and Ring 2 and Sleeve are the TRRS plug connections to the smartphone.
The example values section gives the full specification. The transformer is a 1:1 audio transformer with 600 Ohm impedance and 140 Ohm DC resistance. The primary side gets a 2.2 kOhm resistor in series, with any value between 1 kOhm and 10 kOhm fine and a 10 kOhm potentiometer allowed for adjustment. The secondary side gets a 100 Ohm resistor across the winding for damping and attenuation. The DC blocking capacitor is a 2.2 microfarad film capacitor, with anything between 1 and 100 microfarad working and a note to avoid values below 1 microfarad to keep low-frequency SSTV content intact. And the microphone sensing resistor is 2.2 kOhm between the second ring and the sleeve, with values near 2 kOhm fine.
Two of those notes are the kind that come from having built the thing. The potentiometer on the primary side is there because the right attenuation depends on the source device, and the admonition to keep the DC blocking capacitor above 1 microfarad is there because a smaller value acts as a high-pass filter and will eat the low-frequency part of the signal, which in an SSTV transmission is where the darker pixel values live. That is the kind of detail that turns a schematic into instructions.
The result is a passive adapter, about five components, that turns a radio or sound card line output into something a phone will accept as a microphone input, without the noise, hum and distortion of acoustic coupling.
Editorial conclusion
Adopt Robot36 if you receive SSTV transmissions and want to turn them into images on an Android phone without a dedicated receiver and decoder. Do not expect it to work from an MP3 without artefacts, because the README is explicit that the lossy compression can introduce image noise, colour errors or decoding failures, so prefer an original WAV or FLAC. Before you wire anything up, read the converter section, because a line-level input into a phone microphone input needs attenuation, DC blocking and a microphone detect resistor, and the schematic in the README gives exact values.
Frequently asked questions
What does the Robot36 application do?
It decodes SSTV audio signals into images on Android. Audio can come from the microphone for live decoding, from imported WAV, FLAC or MP3 files, or from the playback capture of another app on Android 10 or later once system capture permission is granted.
What is the difference between normal playback and Turbo in Robot36?
Normal playback includes audible monitoring and paces the decode to the audio. Turbo decodes without playback and without real-time pacing, so the speed depends on the device and the SSTV mode, and stopping and pressing Play again restarts the file.
Why should I avoid MP3 files with Robot36?
Because MP3 is lossy and may introduce image noise, colour errors, or decoding failures, so the README advises preferring original WAV or FLAC recordings. A brief non-blocking notice appears on each MP3 selection, and other compressed formats are not currently supported.
What components does the Robot36 line-level adapter need?
A 1:1 audio transformer of 600 Ohm impedance, a 2.2 kOhm series resistor on the primary side, a 100 Ohm resistor across the secondary for damping, a 2.2 microfarad film capacitor for DC blocking and a 2.2 kOhm microphone detect resistor between the second ring and the sleeve of the TRRS plug.
Why does Robot36 document a hardware adapter at all?
Because decoding is more reliable with a clean input and a direct cable avoids echo, distortion and environmental noise. A phone's TRRS input is a microphone input with bias on it, so feeding it a line-level signal needs attenuation, DC blocking and a microphone detect resistor, and galvanic isolation avoids having to work out the pinout of each device.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/xdsopl-robot36)Was this useful?