# Resample Desk > Every sample-rate conversion is a fraction in lowest terms, and the denominator is > the cycle a resampler has to work in. 48 kHz to 96 reduces to 2/1 — a > one-sample cycle, 64 coefficients. 44,100 to 48,000 reduces to 160/147 — > a 147-sample cycle and 5,120 coefficients. The two commonest rates in > audio are one of the least convenient pairs there is, and nobody chose it. ## The one thing to know **A conversion is a FRACTION, and what matters is that fraction in lowest terms.** ```text up / down = out / in, divided by their greatest common divisor cycle = down (input samples before anything repeats) phases = up (one filter phase per output sample in the cycle) table = taps * phases ``` **Read the cycle and the table separately.** Going up they roughly track each other. Going down they diverge hard: 192 kHz to 11.025 kHz is a 2,560-sample cycle and only 147 phases. **The pair everybody runs is one of the least convenient there is.** 44.1 kHz to 48 kHz reduces to 160/147 — 5,120 coefficients against the 64 that 48 kHz to 96 kHz costs at the same filter length. 80 times the table, and neither pair looks unusual written down. 44,100 came from fitting digital audio onto video tape, 48,000 came from professional video, and the two worlds met. **So the useful advice is never *use a higher rate*. It is STAY IN ONE FAMILY.** Everything in the 48k family converts to everything else in it almost freely, and so does the 44.1k family, and the crossing between them is the expensive part wherever it happens. **And if you do not convert at all** — if the samples are handed to a device running another rate and nothing is interpolated — the material plays at the ratio of the rates. 44.1 kHz handed to 48 kHz is +146.7 cents, 1.47 semitones sharp, and three minutes finishes in 2 min 45 s. Nothing in the file is wrong. The label is. **Pitch and duration are the same fact.** A hand-over cannot change one without the other, which is how to tell it from a pitch effect: if the programme still runs to length, nobody handed anything over. **Bandwidth only ever goes down.** 48 kHz to 44.1 kHz throws away 1,950 Hz above the new Nyquist, and going back up recovers none of it: the file gets 8.8% bigger and carries exactly what it carried. ## The conversions people actually run | Conversion | What it is | Ratio | Cycle | Phases | Table at 32 taps | If handed over instead | | --- | --- | --- | --- | --- | --- | --- | | 48 kHz → 96 kHz | doubling for a high-rate master | `2/1` | 1 sample | 2 phases | 64 coefficients | +1200.0 cents | | 96 kHz → 48 kHz | coming back down from it | `1/2` | 2 samples | 1 phase | 32 coefficients | -1200.0 cents | | 48 kHz → 32 kHz | down to a broadcast contribution rate | `2/3` | 3 samples | 2 phases | 64 coefficients | -702.0 cents | | 44.1 kHz → 48 kHz | a CD master onto a video timeline | `160/147` | 147 samples | 160 phases | 5,120 coefficients | +146.7 cents | | 48 kHz → 44.1 kHz | a session master onto a CD | `147/160` | 160 samples | 147 phases | 4,704 coefficients | -146.7 cents | | 48 kHz → 88.2 kHz | a 48k session into the 44.1 family | `147/80` | 80 samples | 147 phases | 4,704 coefficients | +1053.3 cents | | 192 kHz → 11.025 kHz | an archive transfer down for speech | `147/2560` | 2,560 samples | 147 phases | 4,704 coefficients | -4946.7 cents | **What decides the cost is not how big the rates are or how far apart they are: it is what they have in common.** Two upward conversions, the same filter length: 48 kHz → 96 kHz needs 64 coefficients and 44.1 kHz → 48 kHz needs 5,120 coefficients — 80 times as many. Neither pair looks unusual written down. **Read the cycle and the table separately.** The cycle is the denominator — how many input samples pass before anything repeats. The table is the numerator — one filter phase per output sample. Going DOWN they diverge: 192 kHz → 11.025 kHz is 2,560 samples of cycle and only 147 phases. ## What a filter length costs | Filter length | Table for 44.1k → 48k | Multiplies a second | What it buys | | --- | --- | --- | --- | | 8 taps | 1,280 coefficients | 384,000 | a soft transition band — content survives above the new Nyquist, or is taken from below it | | 16 taps | 2,560 coefficients | 768,000 | a clean cut, and this is the range real converters work in | | 32 taps | 5,120 coefficients | 1,536,000 | a clean cut, and this is the range real converters work in | | 64 taps | 10,240 coefficients | 3,072,000 | a clean cut, and this is the range real converters work in | | 128 taps | 20,480 coefficients | 6,144,000 | a clean cut, and this is the range real converters work in | | 256 taps | 40,960 coefficients | 12,288,000 | sharper than anything anybody will hear, and it costs linearly | **The filter length is the only number on this page a different implementation could change.** The ratio is what the two rates are. Below 16 taps the cut gets soft; above 128 taps it is sharper than anybody can hear and still costs linearly. ## What a hand-over does | Handed to | Speed | Pitch | 3 minutes becomes | Audible? | | --- | --- | --- | --- | --- | | 44.1 kHz → 44.101 kHz | 1.000023× | 0.0 cents | 3 min | no — under 5 cents | | 44.1 kHz → 44.144 kHz | 1.000998× | +1.7 cents | 3 min | no — under 5 cents | | 32 kHz → 32.768 kHz | 1.024× | +41.1 cents | 2 min 56 s | everybody, and it reads as a different performance | | 44.1 kHz → 48 kHz | 1.088435× | +146.7 cents | 2 min 45 s | everybody, and it reads as a different performance | | 48 kHz → 44.1 kHz | 0.91875× | -146.7 cents | 3 min 16 s | everybody, and it reads as a different performance | | 44.1 kHz → 96 kHz | 2.176871× | +1346.7 cents | 82.7 s | everybody, and it reads as a different performance | **Pitch and duration are the same fact.** A hand-over cannot change one without the other, which is how to tell it apart from a pitch effect: if the programme still runs to length, nobody handed anything over. ## What two clocks do | Clock tolerance | Drift in an hour at 48 kHz | Reaches 4,800 samples after | What it is | | --- | --- | --- | --- | | 1 ppm | 173 samples | 27 hours 46 min | an oven-controlled reference | | 5 ppm | 864 samples | 5 hours 33 min | a locked studio clock | | 50 ppm | 8,640 samples | 33 min 20 s | an ordinary consumer crystal | | 100 ppm | 17,280 samples | 16 min 40 s | a cheap one, or a warm one | **Two devices nominally at the same rate are not at the same rate.** No ratio fixes this and no filter length changes it: either something resamples continuously to correct for it, or eventually a buffer underruns. ## What it is A single-page app at https://resample-desk.skillsafe.ai/. The engine is free and runs entirely in the browser with no account; writing the report costs credits. 5 lanes over one sheet, each handing its result to the next. ## The free engine `resample.js` makes no network calls at all. Given a sheet it reduces every hop to a ratio in lowest terms, names the cycle and the filter phases, sizes the coefficient table at the stated filter length and counts the multiplies a second, carries the bandwidth through the chain and names the hop that set the floor, computes the pitch shift and duration scale of any rate handed over rather than converted, and works out how far two clocks drift over the running time against the slack available. It emits 31 findings. All of that is sent with every paid run as `prescan`, so the model is never asked to do arithmetic it can be given. A resample hop clips the band to the new Nyquist. A REINTERPRETED hop does not: the whole spectrum stretches with everything else, so content at 20 kHz moves to 20 kHz times the ratio. That distinction is why the two are separate columns and not one. ## Sheet grammar ```text CHAIN name | the album delivery chain source | 48000 quality | 32 ppm | 50 runtime | 45 min STAGES s1 | the session | 48000 | | tracked at the interface rate s2 | the master | 44100 | resample | delivered for CD s3 | the streaming mix | 48000 | resample | the platform normalises to 48k ``` A STAGES row is `id | what it is | rate | how | why`. **`how` says how the material got TO this stage**, and it is `resample` (the default — it is really converted) or `reinterpret` (the samples are handed over and nothing is interpolated). The first row's `how` is unused, because nothing arrived at it. A rate may be written `44100`, `44.1k` or `48 kHz`. `runtime` accepts `3600`, `45 min` or `2 h`. In CHAIN, **`source` is the rate the material was CAPTURED at**, which is not always the first stage's rate — a 44.1k bed dropped onto a 48k timeline is a 48k file carrying 44.1k material, and its ceiling was set before the chain began. If `source` is left out, the first stage's rate is assumed and that assumption is reported. ## Lanes | task | Lane | Fields | Sections | | --- | --- | --- | --- | | `plan` | Decide the rates before the chain exists | `brief, known` | Summary, The Sheet, The Rates, Reasoning, Next Step | | `check` | What this chain actually does | `sheet, worry` | Summary, Verdict, Findings, Corrected Sheet, Next Step | | `ratios` | The ratio behind every hop | `sheet` | Summary, Every Hop, The Awkward One, What It Costs, Next Step | | `band` | What survives the chain | `sheet` | Summary, What Each Hop Keeps, The Floor, What Cannot Come Back, Next Step | | `deliver` | Decide what changes: a rate, an order, or nothing | `sheet, fixed` | Summary, A Different Rate Fixes, Only A Decision Fixes, Nothing Fixes, Next Step | Every run body must carry `task`. The body IS the input object — do not wrap it in an `{"input": ...}` envelope, which returns 200 while hiding `task` from the model. ## Thresholds | Number | Value | What it decides | | --- | --- | --- | | an awkward cycle | past 8 samples | where a ratio stops being incidental and starts costing filter work | | a long cycle | 100 samples or more | where the coefficient table is the story | | audible pitch | 5 cents | below this almost nobody detects a shift | | obvious pitch | 25 cents | above this every listener hears it | | a short filter | under 16 taps | where the transition band goes soft | | clock slack | 4,800 samples | about 100 ms at 48 kHz, before drift has to be corrected | | the standard rates | 8 kHz, 11.025 kHz, 16 kHz, 22.05 kHz, 32 kHz, 44.1 kHz, 48 kHz, 88.2 kHz, 96 kHz, 176.4 kHz, 192 kHz | anything else is usually a digit out of place | ## Severity Severity is fixed by the code. **Errors are reserved for what an audience actually hears** — a hand-over past the point every listener detects the pitch, or a chain of hand-overs that compound to it. A long cycle, an expensive table and a lost band are warnings: real costs somebody has to decide about, not things that stop working. | Code | Severity | Scope | What it means | | --- | --- | --- | --- | | `SOURCE-ASSUMED` | warn | chain | The source rate was assumed | | `QUALITY-ASSUMED` | note | chain | The filter length was assumed | | `PPM-ASSUMED` | note | chain | The clock tolerance was assumed | | `RUNTIME-ASSUMED` | note | chain | The running time was assumed | | `SOURCE-DIFFERS` | warn | chain | The material was already converted before the first stage | | `RATE-UNUSUAL` | note | stage | That rate is not one in common use | | `HOP-NONE` | note | hop | No conversion here | | `HOP-TRIVIAL` | note | hop | A trivial ratio | | `HOP-AWKWARD` | warn | hop | An awkward ratio | | `HOP-HUGE` | warn | hop | A very long cycle | | `HOP-44-48` | warn | hop | The commonest conversion in audio is an awkward one | | `HOP-DECIMATES` | warn | hop | Bandwidth is lost here | | `HOP-UPSAMPLE` | note | hop | Going up invents nothing | | `REINTERPRETED` | warn | hop | The samples are handed over without conversion | | `PITCH-INAUDIBLE` | note | hop | The pitch shift is too small to hear | | `PITCH-OBVIOUS` | error | hop | Everybody will hear the pitch | | `DURATION-CHANGED` | warn | hop | The running time changes | | `ROUND-TRIP` | warn | chain | The chain returns to a rate it already had | | `REDUNDANT-HOPS` | warn | chain | More conversions than the chain needs | | `NO-CONVERSION` | note | chain | One rate the whole way | | `ONE-STAGE` | note | chain | Only one stage was given | | `NO-STAGES` | warn | chain | No stages given | | `BANDWIDTH-FLOOR` | note | chain | The narrowest point sets the whole chain | | `UPSAMPLE-AFTER-DECIMATE` | warn | chain | Going back up does not recover what went down | | `DRIFT-STATED` | note | chain | What the clocks do over the running time | | `DRIFT-NEEDS-ASYNC` | warn | chain | The drift outruns the buffer | | `FILTER-EXPENSIVE` | note | hop | The coefficient table is large | | `NET-PITCH-CANCELS` | note | chain | The reinterpretations cancel out | | `NET-PITCH-COMPOUNDS` | error | chain | The reinterpretations add up | | `WORK-TOTAL` | note | chain | What the conversions cost | | `QUALITY-LOW` | warn | chain | The filter is short | ## API Full documentation at https://resample-desk.skillsafe.ai/api.html. The engine is client-side only and has no endpoint, but everything it computes is above, so you can reproduce every figure in your own pipeline without this app. ## What this page cannot do - **It has not heard anything.** Every figure is arithmetic on rates somebody typed in. - **The cost figures are for a polyphase FIR.** Other designs exist and their arithmetic differs; the ratio does not. - **A long cycle is not bad sound.** A well-built converter at `160/147` is transparent. It is expensive, not audible, and conflating the two is how people end up avoiding a conversion by handing the file over instead — which IS audible. - **The thresholds are conventions.** 5 and 25 cents are where listening studies broadly land, not a measurement of anybody's ears. - **Bandwidth is not quality.** It is the ceiling on what can be present. What is below it can still be badly converted. - **It says nothing about bit depth, dither, or level.** Only about rate. ## Source Lanes derived from the `spotify-player` skill in https://github.com/steipete/clawdis, which plays audio through somebody else's stack. Every file it plays has been resampled at least once on the way to the speaker, by a ratio nobody listening ever sees. Not affiliated with or endorsed by the authors of that repository.