reTONE
In development · coming soonFree · Android 4.0+

Technical notes

Specs, how conversion and output work, tested devices and other details. This continues from Features.

Main specs

Android4.0 and later
CPUARM (armeabi-v7a, arm64-v8a)
PermissionsStorage access and others. Internet access is used only when Network features is on
Formats read by reTONE's engineWAV, AIFF/AIFC, DSF, DFF (uncompressed), FLAC
Tracks processed by reTONE's engineAndroid 4.x: all FLAC and WAV. Android 5–9: FLAC and WAV whose rate differs from the output, or with a bit depth above 16 bits
Sample rate conversionKaiser-window FIR filter (polyphase). Within ±0.001 dB up to 20 kHz (design value; for conversions between rates of 44.1 kHz or higher)
Format passed from the engine to Android32-bit float on Android 5 and later, 16-bit (with dither) on 4.x. The bit depth at the phone's output depends on the phone
USB DACUSB Audio Class 2 (Class 1 untested). Tracks at rates the DAC supports are sent without resampling. 32-bit subslots preferred (24- or 16-bit if unavailable). Native DSD under certain conditions
SigningAll distributed versions are signed with the same key

Supported formats

Formats the phone's Android can play are played with the phone's decoder and sound processing. DSD, AIFF, and hi-res FLAC and WAV that Android can't read are played by reTONE's engine.

Played by AndroidFLAC, AAC, MP3, Ogg Vorbis, WAV and more (Opus on Android 5 and later)
Played by reTONE's engineDSD (DSF, DFF), AIFF, 32-bit WAV, ALAC (when the phone can't play it; from 0.68.0). On Android 4.x, all FLAC and WAV
Not supportedDST-compressed DFF, APE, WMA Lossless

Technical details

With lossless or uncompressed tracks, any correctly written decoder restores the same data. Setting aside the phone's sound effects, the sound mainly changes in three places: sample rate conversion, bit-depth truncation, and volume calculation and the mixer. reTONE takes care of those.

Background: what affects sound quality

Lossless tracks such as FLAC and uncompressed tracks such as WAV are restored to exactly the original data by any correctly written decoder, whichever app plays them. What can change the sound is the processing after decoding (the three steps below, plus the phone's sound effects).

Sample rate conversion

Many Android phones fix their output at a rate such as 48 kHz. Tracks at a different rate, such as CD audio or hi-res audio, are resampled every time they play. The quality of that conversion varies by phone.

Bit-depth truncation

On older Android versions, 24-bit tracks are truncated to 16 bits.

Volume calculation and the mixer

Volume calculation and mixing with other apps' sound also happen just before the output.

reTONE works on this part. Where conversion is needed, reTONE does it itself, and where it can be avoided, it doesn't convert. With USB DACs, audio goes to the DAC without passing through Android's audio processing. However, there's no way to check the signal the phone actually outputs, so we can't guarantee bit-perfect output.

The audio path

When the phone's output rate is fixed at 48 kHz or similar, it can't be changed without root, so tracks at a different rate (44.1 kHz CD audio, or 88.2, 96 or 192 kHz hi-res audio) can't play without conversion. On Android 4.x to 9, reTONE resamples tracks played by its engine with high quality before handing them to Android, so Android's conversion doesn't run (for the conversion quality, see "Resampling filter" below). With USB DACs and on phones that support direct output, no conversion is done at all.

Android 4.xFLAC, WAV, DSD, AIFF
Track file reTONE engineResamples instead of Android (only when needed) AndroidReceives 16-bit, no conversion Speaker / earphones
Android 5–9DSD, AIFF, and FLAC/WAV that need conversion
Track file reTONE engineResamples instead of Android AndroidReceives float, no rate conversion (on phones with 16-bit output, reduced to 16 bits here) Speaker / earphones
Android 10 and laterPhones that support direct output
Track file reTONERepacks 16-bit lossless audio as 24-bit AndroidDirect output Speaker / earphonesAt the track's own rate
USB DACConnected via OTG (all tracks)
Track file reTONERates the DAC supports are sent as is, others are resampledBypasses Android USB DAC

Handled by reTONEHandled by Android

Tracks whose sample rate matches the phone's output need no conversion, so none happens even with Android's standard playback. Formats that don't go through reTONE's engine, such as MP3 and AAC, use Android's standard playback, and Android resamples them if their rate differs from the phone's output (when playing through a USB DAC, reTONE sends these too). DSD and AIFF are played by reTONE's engine even on Android 10 and later.

In detail

reTONE changes how much it handles depending on the track format, the Android version and the output. For PCM tracks, sample rate conversion happens at most once on any path (for DSD, at most once after the DSD-to-PCM stage). With Bluetooth, the phone and the Bluetooth codec process the audio further after this. Playback is built on Android's MediaPlayer and AudioTrack, and reTONE's engine (written in C) handles decoding and conversion before them.

Android 4.x: Many Android 4.x phones open the music output thread at a fixed rate such as 48 kHz, and tracks at a different rate, such as 44.1 kHz or 96 kHz, are resampled inside Android's mixer before they play. Apps have no way to stop this conversion. The standard decoder in 4.x may also reduce 24-bit FLAC to 16 bits, or fail to open 192 kHz FLAC. So on 4.x, reTONE's engine reads all FLAC and WAV, as well as DSF, DFF and AIFF, converts them once to the phone's output rate (the value of AudioTrack.getNativeOutputSampleRate), and hands them over as 16-bit. Android's mixer accepts 16-bit audio at the same rate as is, so no sample rate conversion happens on the Android side. When reducing to 16 bits, reTONE applies TPDF dither, and when the output is 44.1 kHz or 48 kHz, it uses error-feedback noise shaping (Lipshitz, Vanderkooy and Wannamaker's 5-tap E-weighted filter) to move quantization noise to less audible frequencies. If clipping occurs, the fed-back error is limited to ±4 LSB to prevent oscillation. The coefficients were designed for 44.1 kHz and are also used at 48 kHz. The total amount of noise increases, but it's moved to high frequencies where the ear is less sensitive. However, if you set Android's volume below maximum, Android's mixer rounds to 16 bits again after applying the volume, which reduces the benefit of noise shaping. This doesn't apply to phones that adjust the volume in hardware. Either way, no sample rate conversion takes place. MP3, AAC and similar formats play through Android's standard path even on 4.x.

Android 5–9: The Android mixer in this generation accepts float, so reTONE's engine passes float audio to AudioTrack without dither. On phones with 16-bit output, Android then rounds it to 16 bits (Android doesn't apply dither at this point). FLAC and WAV tracks whose sample rate differs from the phone's output rate would be resampled by Android's mixer if passed as is, and tracks above 16 bits would be truncated to 16 bits. AOSP's default resampler uses medium dynamic quality (DYN_MED) when the quality setting (af.resampler.quality) isn't set, and drops to an even lower quality when the estimated load of the resamplers in use at the same time exceeds a limit. On the phone we checked, this setting wasn't set. reTONE's engine resamples only the tracks that meet these conditions, and you can turn this off with the "Conversion by reTONE" setting. 16-bit tracks at the phone's output rate (such as CD audio on a 44.1 kHz phone) need no conversion, so they play through Android's standard path.

Direct output (Android 10 and later; availability depends on the phone): Availability of "direct output," which sends audio at the track's rate without going through the mixer, and "offload," which decodes compressed audio on the chip, depends on the phone and the output. On Android 10 and later, an app can ask the phone with AudioTrack.isDirectPlaybackSupported whether a given format, rate and bit depth can be output directly to the current output. reTONE uses this path only when the phone says yes, and otherwise plays through Android's standard path. The answer differs by output, so reTONE asks again each time earphones or USB are plugged in or unplugged. On the phone we checked, the only formats that couldn't be output directly were 16-bit PCM at 44.1, 48 and 88.2 kHz (CD audio falls into this group). 24-bit and float could be output directly at the track's rate, and MP3 and AAC (tracks 60 seconds or longer) went to offload. So reTONE decodes 16-bit lossless audio (FLAC, ALAC, WAV) to PCM with the phone's decoder and passes it to MediaPlayer through MediaDataSource as a 24-bit WAV with the lower 8 bits filled with zeros. The upper 16 bits are unchanged. Before switching, it actually decodes the first block to confirm that real 16-bit PCM comes out, and falls back to the standard path if it can't confirm this. 24-bit and high-rate lossless audio, and MP3 and AAC, already go to direct output or offload, so they're passed as is. Apps have no way to read which output the phone actually used, so "DIRECT" on the player screen is an expectation based on the phone's answer (on the phone we checked, it matched the system's records). With offload, we also can't check whether the sample rate changes inside the chip. On this path, the phone's software sound effects (such as DTS) aren't applied, while the DAC's hardware settings (such as filters) still take effect. It can be turned on or off in Settings.

Direct output to USB DACs: When you connect a USB DAC to a phone with USB host support (OTG), reTONE sends data straight to the DAC without going through Android's audio path. On the phone we checked, Android's standard path converted audio to 16-bit/48 kHz for the USB DAC (an output for 32-bit/192 kHz was also open, but it wasn't used for music). reTONE's direct output works as follows.

  • Using the phone's USB host API, reTONE finds the DAC, gets your permission, and reads the USB descriptors (USB Audio Class 2.0: the clock ID, the alternate settings of the playback interface, the output endpoint and the feedback endpoint).
  • It takes the DAC over from Android's driver (claimInterface) and prefers a PCM, 2-channel, 32-bit alternate setting (24-bit or 16-bit if unavailable).
  • It reads the supported sample rates with the clock source's GET RANGE. If the track's rate is in range, it sets it with SET CUR and confirms it with GET CUR. Only tracks at unsupported rates are resampled, once, by reTONE. Tracks at rates the DAC supports get no sample rate conversion and no dither. Tracks up to 24 bits are sent with the original data placed unchanged in the upper bits of a 32-bit word (from 0.69.0, when using the DAC's volume or when adjusting the volume on the DAC itself). With 16-bit DACs, tracks that are exactly 16-bit get no dither, and TPDF dither is applied only to tracks with more than 16 bits of resolution.
  • Transfers are handled on the C side with usbdevfs isochronous transfers. For High Speed DACs that take audio every 0.125 ms (most of them), 1 ms of audio (8 microframes) is grouped into one transfer, and 64 of these are kept queued ahead. For DACs with a longer interval, each transfer holds 32 packets and fewer are queued, keeping about 64 ms ahead. Asynchronous DACs report the number of frames per microframe from the feedback endpoint, and reTONE adjusts how much it sends to match. The format of that value varies by DAC, so reTONE detects it from what arrives. Volume is applied right before sending, so changes take effect immediately.
  • During this time, MP3, AAC and similar formats are also decoded to PCM with the phone's decoder (MediaCodec) before sending, so reTONE plays every track. Unplugging the DAC pauses playback. If the DAC isn't returned to Android, for example after a force stop, reTONE returns it right after an update, and when you open reTONE with "USB DAC direct output" turned off.

Many phones of the Android 4.1 generation can't use a USB DAC as an audio output, but reTONE's direct output uses only the USB host function, so it can still send audio. With our 2012 test phone (Android 4.1) and a battery-powered DAC, 24-bit/192 kHz played without conversion. We have tested USB Audio Class 2.0 DACs; Class 1.0 DACs are untested. Older phones can supply only a small current over USB, so bus-powered DACs may not be recognized. We've also seen a case where Wi-Fi radio interference reached the DAC through the USB cable and caused intermittent noise. Playback doesn't need a connection, so we recommend switching to airplane mode when listening through a USB DAC.

Resampling filter

0-20-40-60-80-100-120-1400102030 Frequency (kHz) dB Flat to 20 kHz Stopbandfrom 24.1 kHz
Response of the filter used for 44.1 kHz → 48 kHz conversion (calculated with the same formulas as the app).Phones with float output (target 120 dB) Phones with 16-bit output (target 100 dB)
  • Flat to 20 kHzDeviation up to 20 kHz is under 0.001 dB (calculated). It doesn't reduce any audible sound.
  • Stopband attenuation of at least 120 dB / 100 dBCalculated values for phones with float output and phones with 16-bit output (about −122 dB / about −102 dB for 44.1 kHz → 48 kHz). Aliasing measured with a 30 kHz input signal (the amount appearing in 0–20 kHz, before rounding to 16 bits) was at least 104.6 dB below the original signal.
  • −1 dB only when resamplingThis leaves headroom for inter-sample peaks above 0 dBFS (the highest we measured on commercial recordings was +0.59 dB). Resampled tracks are 1 dB quieter than tracks that aren't resampled.
In detail

Sample rate conversion recalculates the waveform between the original samples, so the quality of the filter shows directly in the sound. reTONE's filter is an FIR filter made by applying a Kaiser window to a sinc function. It uses a polyphase structure, which splits the coefficients into groups to match the conversion ratio and computes only what's needed. The design rests on two criteria: don't reduce audible sound, and keep the aliasing caused by conversion well suppressed.

  • Passband: flat to 20 kHz (within ±0.001 dB by design; for conversions between rates of 44.1 kHz or higher).
  • Stopband: starts at "the lower rate − 20 kHz." Between 44.1 kHz and 48 kHz, that's 24.1 kHz. Aliasing that falls in this range appears above 20 kHz and stays out of the audible band (up to 20 kHz).
  • Attenuation (design target): 120 dB for phones with float output (Android 5 and later), 100 dB for phones with 16-bit output (Android 4.x). The filter length and window are designed with a 2 dB margin over the target so the calculated value exceeds the target for every conversion (for 44.1 → 48 kHz, the calculated values are about 122 dB and about 102 dB). Residual aliasing at −100 dB is well below the 16-bit noise floor (around −93 dBFS full-band, including dither), so 100 dB of attenuation is audibly no different from 120 dB.
  • Taps: determined from the attenuation and the transition band using the Kaiser window formula (86 taps for 44.1 ↔ 48 kHz at 120 dB).
  • 2:1 stages: Stages that halve the rate exactly, such as 96 → 48 kHz, use a half-band filter, in which half the coefficients are zero and the rest are symmetric, cutting multiplications to about a quarter of a normal filter. 192 → 48 kHz uses two half-band stages, and remaining ratios such as 88.2 → 48 kHz are handled by a polyphase filter.

In measurements, 1 kHz, 19 kHz and 19.9 kHz signals came out at the same level within 0.01 dB. With a 30 kHz input, the aliasing appearing in 0–20 kHz was at least 104.6 dB below the original signal at 44.1 kHz and 48 kHz output, and at least 116 dB below for conversion from 192 kHz (measured before rounding to 16 bits). These are values at a single frequency. By design, the whole stopband is suppressed to at least the attenuation targets above.

Because conversion creates new points between the original samples, loud tracks can end up with points above 0 dBFS. When we converted several commercial recordings we had to 48 kHz, points above 0 dBFS made up 0.0001–0.001% of the total, with maximums of +0.38 to +0.59 dB. These get clipped at 16-bit output or in the phone's mixer, so when resampling, and only then, reTONE lowers the level by 1 dB, leaving headroom above the measured maximum. Tracks that aren't resampled are left unchanged, so on the same phone, resampled tracks are 1 dB quieter.

Volume isn't applied inside reTONE's engine. It's applied in Android's mixer (the AudioTrack volume). Applying it inside the engine would delay changes until the roughly 500 ms of audio buffered in AudioTrack finished playing, making the volume keys feel sluggish. On phones with 16-bit output, lowering the volume makes Android round to 16 bits again (Android doesn't apply dither at this point).

The calculations are written in C and use ARM NEON instructions to process the left and right channels together. The filter's inner loop reads coefficients as vectors and uses four accumulators to hide latency. Dither, including random numbers, rounding, clipping and error feedback, is also done entirely in NEON, avoiding transfers between NEON and general-purpose registers, which are slow on older cores (Cortex-A9).

Did you know?Phone makers choose Android's resampling quality

The part of Android that converts sample rates offers several quality levels, from simple calculations to heavier ones that use more computation for better accuracy. Which one is used is determined by a setting on the phone, and that setting is decided by the phone maker.

On phones running Android 5 or later where the maker hasn't set it, the medium level, DYN_MED, is used (on Android 4.4, the simplest level, LOW). Also, when the estimated load of the resamplers in use at the same time exceeds a limit, the resamplers beyond the limit drop to the next lower level (actual CPU load isn't measured). On the phones we checked, two Android 4.4 phones had the value set to 4 (VERY_HIGH), and one Android 9 phone had no setting, so it used DYN_MED. This means the same track gets different resampling quality depending on the phone.

Setting valueLevelHow it converts (stock Android)Stopband attenuation (design)
1LOWLinear interpolation between the two neighboring samples; the lightest method. Used on Android 4.4 when not setNo dedicated filter
2MEDCubic interpolation over several neighboring samplesNo dedicated filter
3HIGHUses a sinc filterNot stated in the source
4VERY_HIGHUses a longer filter than HIGH. Coefficients are loaded from a phone component (libaudio-resampler.so); without it, same as HIGHNot stated in the source
5DYN_LOWBuilds a filter on the fly to match the conversion ratio80 dB
6DYN_MEDSame as above, with a longer filter than DYN_LOW84 dB
7DYN_HIGHSame as above, with the longest filter98 dB
Not set—DYN_MED on Android 5 and later (LOW on Android 4.4). Drops to the next lower level when many are in use at once84 dB
reTONE—Designed independently of the phone's setting. Flat to 20 kHz (the attenuation target depends on the output format)100 dB (16-bit output)
120 dB (float output)

The setting is named af.resampler.quality. The table is based on the stock Android source code for Android 13 (the Android 4.4 entries are based on the Android 4.4 source), and may not apply if the maker has modified it. All "Stopband attenuation (design)" figures are filter design targets. reTONE is designed so that the calculated value exceeds the target for every conversion.

Where reTONE handles the conversion, reTONE's resampling is used regardless of this setting.

USB DAC volume

There are three places where the volume can be lowered. Which one is used depends on how the DAC is built and what you choose when you first connect it.

Inside reTONEDigitalDAC digital volumeControlled over USBThe DAC itselfKnob or buttons
DACs with volume control over USBSent at maximumMoves with the volume keys—
DACs without itMoves with the volume keys——
When "On the DAC" is chosenSent at maximumMaximumAdjusted on the DAC
In detail

There are three places to lower the volume: ① inside reTONE, applied to the data (digital), ② the DAC's internal digital volume, controlled over USB, and ③ the knob or buttons on the DAC itself. reTONE chooses between ① and ② automatically, and asks you only whether ③ exists.

② Volume over USB: USB Audio Class has a volume mechanism called the Feature Unit, and GET RANGE reads its minimum, maximum and step size (in units of 1/256 dB). reTONE converts its volume (a single gain combining Android's steps and the fine volume) to dB. If it falls within this range, reTONE sends it to the DAC and keeps its own output at maximum. Only when the volume goes below the range is the shortfall applied to the PCM with ①. 0 is mute.

① Inside reTONE: For DACs without Feature Unit volume, reTONE applies the volume to the 32-bit data before sending it. It's applied right before sending, so the volume keys respond immediately.

③ The DAC itself: Whether the DAC has its own volume control can't be read over USB. So the first time you connect a DAC, reTONE asks once for "How the DAC's volume is set" (On the DAC / With the phone's volume keys / Not sure). If you choose "On the DAC," both ② and ① are fixed at maximum, and pressing the volume keys changes nothing (a message tells you so). With DACs that have an analog volume control, avoiding digital attenuation lets you get the most out of the DAC. The choice is remembered for each DAC model (USB vendor ID and product ID) and can be changed with the "DAC volume" setting.

When "On the DAC" is chosen, or when the DAC's volume is used (within the DAC's volume range), tracks at rates the DAC supports are sent without changing the data. Only when you set the volume below the DAC's range does reTONE apply the remainder. However, we can't check what happens on the phone or DAC side, so we can't guarantee bit-perfect output.

Native DSD

DSF/DFF tracks
DAC supports native DSD
and its volume can be controlled over USB
and "Sending DSD" is set to "Send as DSD"
YesSend as DSDe.g. DSD64 → USB AUDIO • DSD64 DIRECT
NoConvert to PCM88.2 kHz PCM for DSD64

reTONE can't change the volume of DSD itself, so the DAC must allow volume control. If DSD tracks cut out, choose "Convert to PCM" in the "Sending DSD" setting. DoP isn't supported.

In detail

DSF and DFF tracks are sent as DSD, without conversion to PCM, only when the DAC supports native DSD and its volume can be controlled over USB. reTONE can't change the volume of DSD itself, so volume control on the DAC side is required. The player screen shows something like "DSD64 → USB AUDIO • DSD64 DIRECT."

It's sent as follows.

  • Native DSD works with DACs whose USB descriptors include an alternate setting for raw data (TYPE I RAW DATA).
  • DSD bits are packed 4 bytes at a time into a 32-bit word per channel, with the oldest bit at the top. DSF stores bits LSB first, so the bits are reversed before packing. Words are sent big-endian (the same assumption as Linux's DSD_U32_BE). This repacking is done in C, and the transfer ring buffer holds about 500 ms.
  • The DAC clock is set to "DSD rate ÷ 32" (88.2 kHz for DSD64, 176.4 kHz for DSD128).
  • Silence, pauses and track ends are filled with the DSD silence pattern 0x69.

This byte order and bit order were verified by correct playback on the DAC we tested. They haven't been checked with other DACs yet, and DoP (DSD over PCM) isn't supported. DST-compressed DFF can't be read either.

Sending DSD (setting): "Sending DSD" appears under "Sound" in settings only while a DAC that can use native DSD is connected. The default is "Send as DSD" (the DAC plays DSD directly), and you can switch to "Convert to PCM" (reTONE converts it to PCM). If DSD tracks cut out, or if you prefer PCM playback, choose to convert to PCM. The choice is remembered for each DAC model, and switching reopens the current track at the same position. We found a DAC that briefly cut out with DSD recordings whose modulation exceeded the 50% reference level. The transfer was normal, so this appears to be due to the DAC's design. Converting to PCM prevents the dropouts in that case too.

DSD → PCM conversion: When native DSD isn't used (with DACs that don't meet the conditions, when "Convert to PCM" is chosen, and for output to Bluetooth, earphones or the speaker), reTONE converts DSD to PCM in two stages.

  • Stage 1: The DSD bitstream is decimated by a factor of 32, 64 and so on into PCM at about 88.2 kHz or higher (DSD64 by 32 to 88.2 kHz, DSD128 by 64 to 88.2 kHz). The filter is a Kaiser-window FIR filter. The passband extends to the larger of 20 kHz and a quarter of the output rate, the stopband starts at "output rate − passband," and the attenuation is 100 dB for 16-bit output and 110 dB for float and USB. The number of taps is determined by the Kaiser window formula. The calculation uses 16-bit table lookups, and the tables are built once per configuration and reused. In measurements, the response at 20 kHz was 0.000 dB, and aliasing below 20 kHz was −101 dB (100 dB design) / −110 to −117 dB (110 dB design).
  • Stage 2: If needed, the same resampler described in the filter section converts once to the phone's output rate (such as 44.1 kHz or 48 kHz built-in output).
  • Level: Converted so that SACD 0 dB (50% modulation) becomes −6 dBFS (a common convention; from 0.69.0. Earlier versions used −12 dBFS and played 6 dB quieter).

When sending PCM to a USB DAC, reTONE sends PCM at "DSD rate ÷ 32" (88.2 kHz for DSD64, 176.4 kHz for DSD128, 352.8 kHz for DSD256) as is, without the stage 2 conversion, if the DAC supports it. Because DSD is converted to PCM, DIRECT isn't shown in this case.

Load

reTONE's CPU usage relative to one core on our 2012 test phone (Android 4.1, 2 cores).

Redrawing the player screen (during actual playback)About 2%
Outputting CD audio as is (at maximum clock)About 2%
Converting 24-bit/192 kHz to 44.1 kHz (at maximum clock)About 10%
0%50%100%

"Redrawing the player screen" was measured during actual playback and doesn't include decoding. The other two come from running the same calculations as reTONE's engine at maximum clock, converted to a percentage of real time. During actual playback the phone lowers its clock, so the figures shown on the phone look 2 to 3 times higher.

In detail

reTONE aims to "do nothing when stopped" and "draw nothing while playing with the screen off." Periodic work runs only during playback: every second with the screen on and every 5 seconds with it off, and the seek bar on the player screen redraws only itself every 250 ms. The clock and battery are updated by notifications from the system, without polling.

reTONE's CPU usage relative to one core on our 2012 test phone (Android 4.1, 2-core Cortex-A9).

  • Stopped: 0%.
  • Playing with the screen off: drawing stops. Tracks played with Android's standard playback use almost 0%, while tracks played by reTONE's engine (FLAC, WAV and others on Android 4.x) add the decoding and conversion load below.
  • Playing with the player screen shown: about 2% (measured during actual playback; mostly seek bar redrawing, not including decoding).
  • reTONE's engine outputting CD audio (16-bit/44.1 kHz) as is at 44.1 kHz: about 2%. Converting to 48 kHz for output: about 4%.
  • Converting 24-bit/96 kHz to 48 kHz: about 5%. To 44.1 kHz: about 7%.
  • Converting 24-bit/192 kHz to 44.1 kHz: about 10% (calculation only) to about 15% (rough estimate of the total playback load, scaled to maximum clock).
  • Sending 24-bit/192 kHz to a USB DAC without conversion: about 20% (measured during actual playback, screen on, including the transfer thread).

The engine figures from "CD audio" to "24-bit/192 kHz" come from running the same calculations at full speed at maximum clock and converting them to a percentage of real time. During actual playback the phone lowers its clock to between 200 MHz and 1 GHz, so the figures shown on the phone look 2 to 3 times higher (20–29% for 24-bit/192 kHz). How the code is written also makes a big difference: the current implementation in C and NEON had about a third to a fifth of the load of an earlier prototype written in Java.

For DSD-to-PCM conversion, with that 2012 phone and a battery-powered DAC, converting DSD64 to 88.2 kHz PCM and sending it over USB took about 11.8% for the conversion and about 5.8% for the USB transfer (at about 1 GHz). When DSD64 played through the built-in output (48 kHz) on an Android 4.4 phone, the decoding thread used 23.8%, but the phone kept its clock at the minimum 300 MHz, so simply scaling by the clock ratio gives about 3% at maximum clock.

On the phones we tested, the load while the screen was on depended more on screen resolution than on CPU speed (Android 4.x appears to redraw the whole screen even for small updates). A 1080 × 1920 phone used about 4% on the player screen, and a 1440 × 3120 phone running Android 11 used about 8.5% (relative to one of its 8 cores; about 1% of the whole phone). Older phones have small screens and high-resolution phones have more processing power, so for now the redraw rate is the same on all phones.

Tested devices

PhoneAndroidChecked
WalkmanSony NW-Z1000 series4.0.4Launch, screens
Xperia PSony LT22i4.1.2Main features, hands-on
AQUOS PHONE ZETA (docomo)SHARP SH-02E4.1.2Main features, hands-on
Acoustic Research AR-M204.3Launch, 24-bit/96 kHz FLAC playback
AQUOS CRYSTAL (SoftBank)SHARP 305SH4.4.2Main features, hands-on
URBANO L03 (au)KYOCERA KYY234.4.2Main features, hands-on
Xperia Z4 Tablet (au)Sony SOT315.0.2Main features, hands-on
VAIO Phone AVAIO VPA0516.0.1Launch, playback
Nexus 6Motorola Nexus 67.1.1Launch
Galaxy S8 (docomo)Samsung SC-02J9Main features, hands-on
Xperia XZ1Sony G83419Launch
Android One X5 (Y!mobile)LG X5-LG11Main features, hands-on
Galaxy A41 (docomo)Samsung SC-41A12Launch, library, playback
Pixel 3 XLGoogle Pixel 3 XL12Launch
Xiaomi 12S UltraXiaomi 2203121C15Main features, hands-on
Galaxy Z Fold5 Field testSamsung Galaxy Z Fold516Launch, foldable layout
Pixel 10a Field testGoogle Pixel 10a17Launch
Pixel 11 Pro Fold Field testGoogle Pixel 11 Pro Fold17Launch, foldable layout

Field test Results from volunteers testing reTONE on their own phones.

USB DAC direct output: combinations tried

PhoneUSB DACResult
Galaxy S8Android 9Hidizs S9 Probus-poweredWorks. PCM (the DAC reports 44.1–768 kHz; tested with 44.1–192 kHz tracks), native DSD, DAC volume
Galaxy S8Android 9OPPO HA-2battery-poweredWorks
AQUOS PHONE ZETA SH-02EAndroid 4.1OPPO HA-2battery-poweredWorks. 24-bit/96 kHz played without resampling
AQUOS PHONE ZETA SH-02EAndroid 4.1Hidizs S9 Probus-poweredWorks. No speed drift or dropouts
Android One X5Android 11Hidizs S9 Probus-poweredWorks
Xperia PAndroid 4.1OPPO HA-2battery-poweredWorks. 24-bit/192 kHz and 96 kHz played without resampling
Xperia PAndroid 4.1Hidizs S9 Probus-poweredNot recognized. The phone can’t supply enough power
URBANO L03Android 4.4OPPO HA-2battery-poweredDoesn’t work. Android reports USB host support, but the phone won’t act as host over OTG
AQUOS CRYSTAL 305SHAndroid 4.4—Doesn’t work. No USB host support

USB DACs and phones: why results vary

How USB DAC direct output behaves depends on the phone and the DAC. The part of a phone that acts as the USB host (the host controller) differs by era and maker, and those differences show most in isochronous transfers, where audio has to flow at a steady rate without gaps. DACs differ too: how often they take in audio, how they report the rate they want, and where they get power. reTONE doesn’t branch on phone models. It measures what actually happens when you plug in, and adapts. In the table below, musb, EHCI and xHCI were tested on real phones; the others are based on published documentation.

Controller familyCommon problemsWhat reTONE does
musbSome phones from around 2010–2013 (TI, ST-Ericsson, older MediaTek)Gaps between transfers leave the DAC slightly short of data (crackles, dropouts)Measures the real return interval and packs more data to make up the shortfall
EHCIOlder Qualcomm, Tegra, some ExynosCompletions come back in batches; if it falls behind, some data is skippedJudges by a long-term average
DWC2Older Rockchip, some Kirin and Amlogic tabletsData not aligned to 4 bytes can cause noisePrefers 32-bit (4-byte) formats
xHCIAlmost every USB-C phone (around 2015 on)Completions come back in batches; delays cause skipped dataJudges by a long-term average and keeps enough data queued ahead
MediaTek xHCIRecent MediaTek phonesStrict bandwidth allocation may reject high sample ratesNot handled yet
  • Service interval: most DACs take audio every 0.125 ms; some every 0.25 ms or 1 ms. reTONE sizes each packet to match.
  • Rate feedback: most DACs tell the phone how fast to send (asynchronous mode), and the format of that report varies by device. reTONE detects and adapts to most of these formats automatically (0.88.0 and later). Some have no feedback and follow the phone’s rate instead (adaptive mode).
  • Power: some DACs have their own battery or power supply; bus-powered DACs run on the phone’s power alone and may not be detected on older phones that can’t supply enough. Even a battery-powered DAC may charge from the phone and drain it faster.
  • DSD: most DACs that accept native DSD use the same layout (32-bit, big-endian), but there are exceptions.

Manufacturer sound settings

"Sound" in the bottom menu opens the maker's sound settings screen if the phone has one, or Android's sound settings if not. You can choose which screen it opens with the "Sound settings" setting.

PhoneScreen opened
SHARP AQUOS CRYSTAL 305SHHarman Clari-Fi/LiveStage
KYOCERA URBANO L03 (KYY23)Dolby
Sony Xperia PSound effects (Equalizer, ClearBass, VPT, xLOUD and more)
LG Android One X5Sound quality and effects (Hi-Fi Quad DAC, digital filter, DTS:X and more)
Samsung Galaxy S8SoundAlive

Whether the maker's settings apply to reTONE's playback depends on the phone.

What it doesn’t do

  • There's no equalizer, volume normalization, crossfade or waveform display. reTONE puts lightness first and doesn't apply effects to the sound.
  • Lyrics display isn't supported.
  • reTONE doesn't play streams itself. Its role ends at opening the streaming app, and playback and its sound quality depend on that app and the phone.
  • By default, reTONE doesn't use the network at all. It connects only if you turn on Network features in Settings, and then only when you ask it to or for checks you've chosen. While sharing is on, it also accepts connections from phones you've allowed. It collects no data about you.
  • Controls from Android Auto or Wear OS aren't supported. (Playback controls in notifications, on Android's lock screen and from Bluetooth devices are supported from 0.87.0.)
  • reTONE's engine can't play DST-compressed DFF, APE or WMA Lossless, and there are no plans to support them. Please convert them to FLAC or a similar format.
  • Doesn't run on Android 3.x or earlier.
  • On phones without USB host support (OTG), USB DAC direct output isn't available. The "USB DAC direct output" setting appears dimmed, with the message "This device does not support USB devices."
  • The phone and DAC combinations tested with USB DAC direct output are limited. We haven't checked whether other phones or DACs work. Some phones report USB host support to Android but can't act as host over OTG. The tested combinations are listed under "USB DAC direct output combinations tested."
  • DoP isn't supported. Native DSD requires a DAC that supports native DSD and allows volume control over USB. With other DACs, DSD is converted to PCM before sending.
  • While USB DAC direct output is in use, other apps' sound doesn't play through the USB DAC. It plays from the phone's speaker.
  • We can't guarantee bit-perfect output, because apps have no way to check how the phone actually outputs audio.
  • reTONE doesn't change the audio path to the phone's built-in DAC (such as bypassing sample rate conversion or forcing offload playback), because that requires root or the phone maker's signature.
  • While the screen is off, holding a volume key for continuous change, or using the volume keys to skip tracks, isn't supported, because Android doesn't pass the keys to apps.
  • Exporting playlists (M3U and others) and importing Android's shared playlists aren't supported.
  • Editing tags and deleting or moving files aren't supported.
  • reTONE isn't currently distributed on Google Play.