A single Go binary that upsamples audio to hi-res formats β up to 32-bit / 768 kHz β with a measurement-driven enhancement engine that decides, explains, and reports every modification it makes. Decisions come from the built-in local engine or from your locally-running Ollama model (e.g. qwen3-coder:30b on a TITAN RTX / RTX 4090).
Any WAV (8/16/24/32-int, 32/64-float, any rate) plus FLAC, MP3, AAC, OGG, AIFF and more via ffmpeg. Output 16/24/32-bit PCM or 32-bit float, 8 kHz β 768 kHz.
Local heuristic decision engine, or hand the measurements to your Ollama LLM which returns strict-JSON DSP decisions β clamped by safety rules either way.
Every file gets a report: measured analysis, the recommendations (local or Ollama), and the exact list of modifications applied β console, web UI and .report.json.
Single files, whole directories, or fully recursive library conversion β from the CLI or the built-in web interface with live progress.
What hiresgo does is get you as close as honestly possible to how a native hi-res master of the same material would behave:
Animated: teal = real measured spectrum stopping at the lossy ceiling; violet = the gentle harmonic extension hiresgo blends in above it.
# the default: 44.1/16 β 192 kHz / 24-bit, local smart mode, enhance 50% $ ./hiresgo song.wav # a whole folder to 96 kHz / 32-bit float $ ./hiresgo -rate 96000 -bits 32 -float album/ # an entire library, recursively, decisions by your local qwen3-coder:30b $ ./hiresgo -r -mode ollama -enhance 70 -report -out /music/hires /music/cd # just tell me what you WOULD do (no conversion) $ ./hiresgo -analyze song.wav # start the web interface with progress bars and per-file reports $ ./hiresgo -serve 127.0.0.1:8093
Watch the stages light up β this is exactly the order applied to every file, and exactly the stage names shown by the progress bars:
Runs of β₯2 consecutive samples at β₯0.997 full-scale (up to ~4 ms) are treated as flattened peaks. The plateau is replaced by a Catmull-Rom curve through the surrounding intact samples, which naturally arcs above the old ceiling β possible because the 24/32-bit output has headroom the 16-bit source never had. Reported as: Reconstructed N clipped peak runsβ¦
Per-channel mean subtraction when |offset| > 0.0002. Recovers symmetric headroom before requantization. Reported with the exact per-channel values removed.
Dual envelope followers (1.5 ms/60 ms fast, 40 ms/400 ms slow), channel-linked. A transient enhancer boosts attacks up to 5 dB Γ amount when the fast envelope outruns the slow one, and a gentle upward/downward expander (effective ratio β€ 1:1.19, macro movement capped at Β±3.5 dB) restores the loud/quiet contrast mastering limiters removed. Gain is slew-limited so it never pumps. The report shows crest factor before β after.
Only when a lossy ceiling is measured (ceiling < 88% of source Nyquist with a β₯22 dB cliff). The top octave of real content is driven through a mild even+odd-order nonlinearity (xΒ·|x| and xΒ³), band-limited to [ceiling β¦ extension], tapered β β6 dB/oct, and blended 11β21 dB below the reference band just under the ceiling, hard-capped at β30 dBFS RMS. Runs at the output rate so the new content genuinely exists above the old Nyquist. Because the synthesis is harmonically derived from the real signal, it tracks the music β cymbals get shimmer back, silence stays silent.
When the measured floor is elevated (> β55 dBFS), a conservative STFT spectral gate profiles the noise from the file's own quietest frames and attenuates it up to the chosen depth (β€ 8 dB, scaled by the enhance dial). Fast-attack/slow-release gain smoothing and 3-bin spectral smoothing prevent musical noise; the report shows the floor before β after. Skipped automatically if there is no reliable quiet passage to profile.
When significant sub-25 Hz energy is measured, a 4th-order Butterworth high-pass (default 20 Hz) removes rumble/DC-adjacent content that wastes headroom and is inaudible on the program itself.
When a left/right level lean exceeds 1.5 dB, the quieter channel is nudged up by the measured delta (β€ 3 dB) to re-center the image. Objective fix β NOT scaled by the enhance dial. Preserved when the lean is small or possibly-intentional stage positioning.
Digital-silence padding of β₯ 3 s at either edge is trimmed to a tidy 0.3 s lead / 0.5 s trail. Never touches musical content β only sub β70 dBFS blocks at the very start/end.
If the spectrum tilts duller than β26 dB (HF vs midband) and no bandwidth extension is active: a +0.3β¦+1.5 dB high shelf at 12 kHz. Mastering-grade subtlety only.
Polyphase Kaiser windowed sinc: 224 taps (widened automatically when downsampling), Ξ² = 14, per-phase DC-normalized rows, exact integer rational phase accumulator β zero drift even on hour-long files at 768 kHz. Passband flat to ~0.92 Γ source Nyquist; images at/above the old Nyquist suppressed β β135 dB.
16/24-bit outputs get TPDF dither at 1 LSB; 32-bit int/float are written directly. A final true-peak guard trims the whole file (reported in dB) only if enhancement pushed the peak past β0.05 dBFS. Files whose data would exceed 4 GB are automatically written as RF64.
-mode convert β pure conversion. No analysis, no enhancement: resample + dither only. Fastest; bit-transparent apart from the sample-rate/bit-depth change itself. Use when you want a pristine format change and nothing else.
-mode local β the built-in engine reads every measurement and, like a careful mastering engineer, either corrects each imperfection with a justified amount or explicitly preserves it with a stated reason β clipping, DC, dynamics, lossy bandwidth, dark tilt, elevated noise floor, subsonic rumble, channel lean and edge silence are all considered, not just the obvious three. Fully offline, deterministic, instant.
-mode ollama β the measurement JSON is sent to your local Ollama model, which returns strict-JSON DSP decisions plus its reasoning. hiresgo clamps everything to safe ranges. If Ollama is unreachable it automatically falls back to local and says so in the report.
local engine, ollama (qwen3-coder:30b), or ollama β local fallback), why (the recommendations, quoting the measurements), and what was actually applied β so an Ollama run is never a black box.| Flag | Default | What it does / what to expect |
|---|---|---|
-rate N | 192000 | Target sample rate, 8000β768000 Hz. Common: 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000. Non-integer ratios (44.1kβ192k) are handled exactly. |
-bits N | 24 | Target depth: 16, 24 or 32 (integer PCM). 16/24 get TPDF dither automatically. |
-float | off | Write 32-bit IEEE float instead of integer PCM (forces -bits 32). Ideal for further editing. |
-mode M | local | convert | local | ollama β see Modes above. |
-enhance N|auto | 50 | Global strength 0β100 scaling every enhancement magnitude; 0 = corrective conversion only. auto derives the strength per file from its measured severity: 20% floor + up to 65% weighted from lossy confidence (Γ0.45), crest deficit below 12 dB (Γ0.30), clipping density (Γ0.15) and dull tilt (Γ0.10). A clean file stays at the 20% floor (effectively corrective-only); a clipped low-bitrate rip lands near 80%. The derived value and its drivers are printed in every report. |
-format wav|flac | wav | Output container. flac (requires ffmpeg) writes lossless FLAC at roughly half the size of WAV and copies metadata tags from the source file β ideal for a music library at high rates. 32-bit/float requests are stored as 24-bit FLAC. |
-summary | off | After a batch, write summary.csv and a sortable summary.html across all converted files: per-file status, format, crest, ceiling, noise floor, effective bits, star rating and applied count, plus a "needs attention" table highlighting the lowest-rated files, lossy sources and detected fake hi-res. |
-out DIR | β | Write outputs into DIR. When the input was a single directory, its tree structure is mirrored. Without -out, files land next to the source with the suffix. |
-suffix S | _hires | Filename suffix used when writing next to the source (song.wav β song_hires.wav). |
-workers N (serve) | 1 | In -serve mode: global count of files converted simultaneously across all users; per-file fair queueing. Size it by RAM (each slot holds one file fully in memory at the output rate). |
-recursive / -r | off | Descend into all subdirectories of any directory argument. |
-workers N | 1 | Files converted in parallel. Each file already parallelizes across channels; raise this on many-core boxes converting big libraries. Watch RAM (see Formats & limits). |
-report | off | Write <output>.report.json beside every converted file: full analysis, recommendations, applied list, timings β machine-readable. |
-analyze | off | Analysis + recommendation preview only; nothing is converted or written. |
-overwrite | off | Replace existing outputs; otherwise they are skipped with a warning. |
-ollama-url U | http://127.0.0.1:11434 | Base URL of your Ollama instance. |
-ollama-model M | qwen3-coder:30b | Model used in -mode ollama. Any instruct model that can follow a JSON schema works. |
-ollama-timeout D | 5m0s | Budget per Ollama phase: model load and the decision request each get this long (Go duration, e.g. 90s, 10m). A cold 30B model can take minutes to load from disk. |
-ollama-test | β | Diagnose the Ollama connection step by step: reachability, model presence, load time, and one sample decision with timings. Run this first if -mode ollama misbehaves. |
-serve ADDR | β | Start the web interface (e.g. 127.0.0.1:8093). CLI flag values become the form defaults. Bind 0.0.0.0:PORT only on trusted LANs β the path mode can read server files. |
-quiet | off | One line per file instead of the full report box. |
-v | off | Verbose: include the raw Ollama JSON output inside reports. |
-no-color | off | Plain-text console reports (logs, CI). |
-help-html F | β | Export this manual to an HTML file and exit. |
-version | β | Print version and exit. |
# 1 Β· The audiophile default β one CD rip to 192/24 with explanations $ ./hiresgo song.wav β song_hires.wav; report shows analysis, local recommendations, applied list # 2 Β· Pure conversion, zero opinion β maximum-rate archival master $ ./hiresgo -mode convert -rate 768000 -bits 32 song.wav β mathematically transparent 768 kHz/32-bit; ~26 GB RAM per hour of stereo, RF64 if >4 GB # 3 Β· Whole album folder β mirrored hi-res tree with JSON evidence $ ./hiresgo -report -out /music/hires /music/cd/Pink_Floyd β /music/hires/*.wav + *.report.json per track # 4 Β· Entire library, recursive, conservative touch $ ./hiresgo -r -enhance auto -out /music/hires /music/library β tree mirrored; each file gets its own strength: clean discs ~20%, damaged rips up to ~85% # 5 Β· Let the LLM drive, strong enhancement, show its raw JSON $ ./hiresgo -r -mode ollama -enhance 70 -v -report /music/mp3_era β per-file: "decisions: ollama (qwen3-coder:30b)" + model reasoning; falls back to local if Ollama is down # 6 Β· Preview first, convert second $ ./hiresgo -analyze /music/questionable_rips $ ./hiresgo -r -enhance 60 /music/questionable_rips # 7 Β· Mixed-format folder (48 kHz WAVs, FLACs, old MP3s) β uniform 96/24 $ ./hiresgo -rate 96000 -r -out /music/uniform /music/mixed β every input rate/format normalized; MP3 ceilings detected per file and extended per file # 8 Β· Studio handoff β float masters, 8 files at a time on a big box $ ./hiresgo -float -rate 192000 -workers 8 -out /masters stems/
One number scales every creative magnitude the decision engine enabled. Drag it:
Corrective repairs (declip, DC removal) run whenever the mode is local/ollama and enhance > 0 β they fix objective faults and are not scaled down.
ollama serve then ollama pull qwen3-coder:30b (fits a TITAN RTX / RTX 4090)../hiresgo -ollama-test β it checks reachability, confirms the model is installed, times the load, and runs one sample decision.recommendations array explaining each decision./api/tags, 6 s) fails immediately with the real reason instead of hanging; the model is then explicitly loaded with keep_alive: 30m β batch jobs pay the load cost once, on the first file; the decision itself streams with an idle watchdog (75 s of silence aborts a stalled generation) and a hard num_predict cap so nothing can hang the pipeline. Load/generation timings appear as a [diag] line with -v.ollama β local fallback with the exact reason as a warning.$ ./hiresgo -serve 127.0.0.1:8093 hiresgo v6.0.0 web interface UI: http://127.0.0.1:8093/ Manual: http://127.0.0.1:8093/help
-workers N when starting -serve) is acquired per file, so a 500-track library job from one user interleaves fairly with everyone else's single tracks instead of starving them; jobs briefly show queued while waiting for a slot. Each job's results and downloads are reachable only through its own unguessable job id.Since v6.3 every analyzed file first gets a detailed source evaluation: each measured parameter with a verdict β β good, β notable, β issue β and a sentence explaining what is right or wrong. Parameters covered: format consistency and effective bit depth (exposes 16-bit data padded into 24/32-bit containers), peak level and headroom, RMS loudness, crest factor, loudness range (macro-dynamics), clipping, DC offset, bandwidth ceiling with codec awareness, tonal balance, noise-floor estimate, stereo correlation, channel balance, subsonic energy and edge silence. Since v6.5 every row also carries a meaning (what the metric measures β shown as a hover tooltip in the web UI) and, for notable/issue rows, a detail paragraph with possible causes, reference scales and analyzer caveats β e.g. evaluation rows describe the measured condition and recommend a fix rather than asserting one (the Applied list is the record of what actually ran), objective corrective repairs (clear DC offset, real clipping) are re-enabled automatically if a decision engine tries to skip them, the noise floor distinguishes genuine hiss from reverb/mix-bed showing through gaps (a floor within ~40 dB of a loud program is treated as ambience, not a defect); crest factor is cross-referenced with loudness range (a modest crest alongside a wide LRA is read as dense micro-dynamics, not brickwalling, and does not trigger expansion); the noise-floor row is measured only in genuine silent gaps between notes and reports indeterminate (not a false hiss warning) when the program never goes quiet β a solo instrument or sustained pad is no longer mislabeled as noisy; the bandwidth row classifies a lossy ceiling into its approximate bitrate class (16 kHz β 128 kbps, 19.5 kHz β V0, 20.5 kHz β 320 kbps); the balance and tilt rows list the recording-side explanations (mic placement, stage position, venue, artistic choice) before suggesting any correction. The evaluation closes with an Overall assessment: per-category star ratings (recording format, dynamic range, cleanliness, bandwidth, stereo image, tonal balance, noise) and a composed verdict paragraph that separates what needs work (targeted by the recommendations) from what merely stands out and may be a characteristic of the original session rather than a defect. In the web UI the evaluation streams into its own section the moment analysis completes β before the conversion finishes β and is repeated inside the result card; in the CLI it opens the report; in the JSON sidecar it is the evaluation array. Below the evaluation, the same three-part story as before:
ββββββββββββββββββββββββββββββββββββββββββββββββββ β βͺ oldrip.wav β Input: WAV PCM 16-bit / 44100 Hz / stereo / 3:42.0 β Output: WAV 24-bit / 192000 Hz / stereo β oldrip_hires.wav β Mode: local enhance 60% decisions: local engine β Analysis β β’ Peak -0.1 dBFS, RMS -9.3 dBFS, crest factor 9.2 dB β β’ Spectral ceiling 16.02 kHz (41 dB cliff) β lossy-source suspected (81%) β β’ 14 clipped peak runs (0.021% of samples) β Recommendations (local engine) β 1. Detected 14 clipped peak runs β reconstruct flattened peaksβ¦ β 2. Crest factor 9.2 dB indicates heavy mastering limiting β gentle expansionβ¦ β 3. Spectral ceiling β 16.02 kHz (lossy signature, 81%) β synthesize 16.0β30.5 kHzβ¦ β Applied to this file β β Reconstructed 14 clipped peak runs via cubic interpolation β β Dynamics decompression β crest factor 9.2 β 11.4 dB β β Upsampled 44100 β 192000 Hz (224-tap Kaiser windowed-sinc) β β Harmonic bandwidth extension 16.0 kHz β 30.5 kHz, blended -13 dB β β Requantized to 24-bit PCM (TPDF dither) ββββββββββββββββββββββββββββββββββββββββββββββββββ
The JSON sidecar (*.report.json) contains the identical data β analysis, decision_source, recommendations[], applied[], warnings[], timings β ready for scripting or archiving proof of what was done to every file.
| Direction | Supported |
|---|---|
| Input (native) | WAV / RF64: PCM 8/16/24/32-bit, IEEE float 32/64-bit, any rate 1β1000 kHz, mono to 32 channels, WAVE_FORMAT_EXTENSIBLE, streaming headers. |
| Input (via ffmpeg) | FLAC, MP3, M4A/AAC, OGG, Opus, AIFF, WMA, WavPack, APE, CAF, DSF, MKA, MP4-audio β auto-detected by extension when ffmpeg is on PATH. |
| Output | WAV (auto-RF64 above 4 GB): 16/24/32-bit PCM (TPDF-dithered at 16/24) or 32-bit IEEE float, 8 kHzβ768 kHz. |
Processing is in-RAM (float64): expect β duration Γ rate Γ channels Γ 8 Γ 2.3 bytes at the output rate. A 5-min stereo track β 2.1 GB at 192 kHz, β 8.5 GB at 768 kHz. Use -workers 1 (default) for extreme rates.
The conversion itself is transparent. The audible wins come from the corrective side: real clipped rips get their transients back, brick-walled masters breathe again, MP3-era ceilings get plausible air (detection is container-aware since v6.2: a file that says mp3/aac is trusted to be one). On a clean, well-mastered CD rip the honest answer is: it will sound the same, in a bigger container β and the report will tell you exactly that ("source measures cleanβ¦ transparent conversion only").
Because it measured clean. The recommendations section says so explicitly. That is the system working, not failing β enhancement is evidence-driven.
High-bitrate MP3/AAC ceilings sit at 19.5β20.5 kHz β above the pure-spectral threshold. Since v6.2 detection is container-aware: when the source file is a known lossy codec (mp3, aac/m4a, ogg, opus, wma) and a genuine encoder cliff (β₯14 dB step) is measured anywhere below 97% of Nyquist, it is flagged with confidence scaled by the cliff depth, and the report shows [mp3 container]. Lossless containers (WAV, FLAC, AIFFβ¦) still require the strict spectral evidence, so steep production filters on real masters are not misclassified.
Some legit masters were made from lossy sources or use steep 16β19 kHz production filtering; the detector reports a confidence, and the extension blend scales with it. Lower -enhance or use -mode convert if you disagree with a call β or check -analyze first.
Classic first-request symptom: the old client waited silently through the whole model cold-load and could be stalled by JSON-constrained generation. Since v6.1 the client preflights in 6 s, loads the model explicitly (default budget 5 min, -ollama-timeout to raise), keeps it warm 30 min, streams the decision and aborts stalls. Run ./hiresgo -ollama-test to see exactly which phase fails. Windows note: if hiresgo runs inside WSL while Ollama runs on the Windows host, 127.0.0.1 does not cross the boundary β use the Windows host IP from WSL, enable WSL mirrored networking, or set OLLAMA_HOST=0.0.0.0 (and allow it in the firewall).
Unreachable URL, model not pulled, timeout, or non-JSON output. The exact reason is in the report warnings. The report warning names the failing phase precisely (unreachable, model not installed, load timeout, stalled generation, bad JSON). Fix: ./hiresgo -ollama-test, then ollama serve / ollama pull qwen3-coder:30b / raise -ollama-timeout as indicated.
Install ffmpeg (apt install ffmpeg). Without it hiresgo decodes WAV/RF64 only and skips the rest with a warning.
192/24 stereo β 1.15 MB/s, 768/32 β 6.1 MB/s. That is the physics of PCM. Files beyond 4 GB switch to RF64 automatically (players supporting BWF/RF64 read them; classic WAV-only tools may not).
Yes β the filter widens automatically and band-limits correctly, so -rate 44100 from a 96 k source is equally transparent.