The heal cue sounded fine in the editor. On a tester's three-year-old Android phone the pickup made a short tick with no sense of recovery attached. The file was 108 KB of 44.1 kHz stereo, the cue ran 610 ms, and the reverb tail was still ringing when the player was already back in the fight.
None of that is a mixing problem. A byte budget is a duration budget: at 22.05 kHz mono 16-bit, 30 KB is about 0.7 seconds, and no EQ setting changes the frame count. Cutting the cue to fit that clock is the easy half; keeping it readable on a phone speaker afterward is where the work sits.
What 30 KB Actually Buys
The arithmetic turns the limit into a clock. Assume 30 KB means 30,720 bytes.
| Format | Bytes per second | Max duration in 30 KB |
|---|---|---|
| 44.1 kHz mono 16-bit | 88,200 | 0.35 s |
| 22.05 kHz mono 16-bit | 44,100 | 0.70 s |
| 16 kHz mono 16-bit | 32,000 | 0.96 s |
| Ogg Vorbis, 128 kbps | 16,000 | 1.9 s |
| Ogg Vorbis, 96 kbps | 12,000 | 2.6 s |
The top row is why the opening file failed. Stereo doubles every figure again, so 30 KB is a tenth of a second of 44.1 kHz stereo, which is a click rather than a cue.
The bottom rows look like the easy answer, and for music they often are. A 300 ms transient-heavy cue is a different customer: at 96 kbps the encoder decides where the ear is listening, and it may decide the quiet breath under your tone is not worth carrying. The Ogg container also holds a setup header of a few kilobytes before the first sample, a real share of 30 KB at this length.
Lossy buys duration and charges control over the attack shape and the decoded length.
Trim the Silence, Then Trim the Tail
A cue that runs 610 ms with 300 ms of content is not a long sound, it is 310 ms of padding. At 22.05 kHz mono every millisecond costs about 44 bytes, so a 40 ms lead-in and a 250 ms tail come to roughly 12.8 KB, a third of the budget spent on nothing anyone can hear.
Where the silence hides
It arrives from four places. The DAW renders the full bus tail rather than the point where the cue stops being audible. Plugin buffers flush after the last note. Some generators default to a 5 to 10 ms fade-in. And encoders often pad both ends of the file.
Cut the head at the first sample that is not digital black, on a zero crossing to avoid a click, and stop the tail once the level stays below roughly −60 dBFS.
Pricing the tail
A one-second tail at 22.05 kHz mono is 43 KB, more than the entire allowance for a sound that finished its message 700 ms earlier. At 44.1 kHz the same tail is 86 KB.
Two ways out: print the cue dry and let the engine add space at runtime, or print a short tail and fade it out inside the file, finished 250 to 350 ms after the last note. Fade over 80 to 120 ms with an exponential curve; a hard cut on reverb reads as a gate slamming and can click on a small speaker.
Mono, Unless Width Is Doing Actual Work
Mono halves every number above and is the right default for a heal cue. Most phones play a summed or near-mono version of the file, so out-of-phase content cancels on the way out and the cue loses exactly the parts that sounded wide in headphones.
Fold the file to mono and listen. If the cue holds its weight, the second channel was 30 KB of duplicate. If it collapses, ask whether that width survives on a phone, and usually it does not.
If the width is real, pay for it somewhere else: keep the stereo file and shorten the cue, or drop the bitrate. The total is fixed, and the tradeoffs in mobile file size and performance are the ones a whole library runs into.
Capping the Sample Rate Caps the Top End
The sample rate sets a ceiling at half its value. 22.05 kHz cannot represent anything above 11.025 kHz, 16 kHz stops at 8 kHz, and 11.025 kHz stops at 5.5 kHz and sounds like a telephone handset. Anti-alias filters do not stop cleanly at the number either, so the usable top end sits a little below it.
That makes the rate a brightness decision as much as a byte decision. For a heal cue, 22.05 kHz is often the sweet spot: a crisp 2 to 4 kHz attack at half the bytes of 44.1 kHz. Dropping to 16 kHz saves another third and costs the air above 8 kHz, which a phone speaker does not reproduce anyway.
Keep the identity under 8 kHz
Above roughly 8 kHz a cue has sparkle, not meaning. Low-bitrate encoders often lowpass near that region and small speakers roll off there too, so the information that answers what happened belongs below it: the interval between the notes, the timbre of the body, the shape of the attack.
A bright, airy heal sound can test well on studio monitors and arrive as a dull click: the top octave carried the impression of quality, and it is the first thing the encode removes. If the cue must still feel open, add 2 to 5 kHz detail rather than anything above 10 kHz.
Put the body where the speaker still works
A 90 Hz thump is satisfying on headphones and absent on a phone. Many phone speakers lose output quickly below a few hundred hertz, so a cue whose fundamental sits down there reads as a click with no pitch attached, and the player learns that a pickup happened without learning which kind.
Move the fundamental to roughly 300 to 800 Hz, E4 at 330 Hz up through G5 at 784 Hz, and the cue keeps a pitch on a small driver. A two-note rise inside that window, root up a fifth or an octave, lands where the speaker still has output and the ear is most sensitive, with nothing below 200 Hz carrying the message.
Keep a sub layer for consoles and TV setups, but check that the cue still says heal with the sub removed. High-pass at 300 Hz, listen in mono, and if it vanishes the identity was in the wrong octave. The wider checks in making effects translate on phone speakers apply to the rest of the palette as well.
Re-Audition After the Codec, Not Before
The WAV you approve is not the file that ships. Four things change through a lossy encoder, and all four matter more at 30 KB than at 300 MB.
Transients get smeared: a hard 8 ms attack can come back 15 ms wide with a small pre-echo in front of it, and that is the part doing the recognition work. Quiet layers get quantized away, so a soft breath under a loud tone may not exist in the decoded file. And encoder padding changes the decoded length, so a 300 ms cue can reach the engine at 340 ms and break the budget you just set.
None of that is visible in the exported waveform. Export at the shipping settings, import the result, check the decoded length, and listen on a laptop speaker and a phone speaker. A null test tells you how different the files are, not whether the cue still reads.
If the attack loses its edge after the encode, the fix is usually not more attack: shorten the file and spend the recovered bytes on bitrate. That is the same logic as reducing file size without losing quality, run in the other direction.
A Starting Budget for a Heal Cue
Starting points, not specifications. A game with a large download can ignore them; a web build cannot.
- Decoded length: 450 to 700 ms total, of which 250 to 350 ms is audible content.
- Lead-in: 0 to 5 ms, cut on a zero crossing.
- Tail: exponential fade finished 250 to 350 ms after the last note, silent by −60 dBFS.
- Format: 22.05 kHz mono 16-bit, or mono Ogg Vorbis at 96 to 112 kbps when the cue can afford to be longer.
- Body: fundamental between 300 and 650 Hz, second note a fifth or an octave up, attack 5 to 10 ms of filtered noise around 1.5 to 4 kHz.
- Reverb: engine-side if the budget is tight, otherwise a printed 200 to 300 ms tail faded inside the file.
Render the cue, run the export, check the number on disk, then play it on the worst speaker you own at the volume a phone gets used at on a bus.
One thing sits upstream: the file size work is wasted if the cue starts late. A heal that arrives 150 ms after the health bar updates still feels broken, however clean the file is. latency on mobile covers that side, and it is worth reading before another afternoon goes into the timbre of a cue the engine is delaying anyway.