|
| 1 | +{ |
| 2 | + "wordmark": "TIMP", |
| 3 | + "tagline": "A small, native, album-art-forward music player. The cover is the interface — and the interface takes its color from the cover.", |
| 4 | + "artist": "fezcode · Şamil Bülbül", |
| 5 | + "version": "0.9.0", |
| 6 | + "repo": "https://github.com/fezcode/timp", |
| 7 | + "download": "https://github.com/fezcode/timp/releases", |
| 8 | + "formats": ["MP3", "FLAC", "OGG", "WAV"], |
| 9 | + "trackSeconds": 24, |
| 10 | + "rackLabel": "Timp samples its accent color from the album art. So does this page — drop the needle on a record.", |
| 11 | + "queue": [ |
| 12 | + { |
| 13 | + "title": "Sampled accents", |
| 14 | + "desc": "Embedded covers (ID3v2 APIC, FLAC PICTURE), sibling cover.jpg, or a generated gradient — and the whole UI re-tints from the artwork.", |
| 15 | + "keys": ["CLICK"], |
| 16 | + "palette": { "name": "Midnight City", "a": "#F27BB4", "b": "#6C5BD4" } |
| 17 | + }, |
| 18 | + { |
| 19 | + "title": "Playlist drawer", |
| 20 | + "desc": "The queue slides out beside the player. Drag files in, reorder rows, save it as a real .m3u8 that other players can open.", |
| 21 | + "keys": ["Q"], |
| 22 | + "palette": { "name": "Lagoon", "a": "#38C8C0", "b": "#2274A8" } |
| 23 | + }, |
| 24 | + { |
| 25 | + "title": "10-band equalizer", |
| 26 | + "desc": "60 Hz to 16 kHz with ON and FLAT. Per-band gains persist in config.ini between sessions.", |
| 27 | + "keys": ["E"], |
| 28 | + "palette": { "name": "Golden Hour", "a": "#F5A524", "b": "#E4572E" } |
| 29 | + }, |
| 30 | + { |
| 31 | + "title": "Synced lyrics", |
| 32 | + "desc": "Karaoke-style .lrc, plain .txt, embedded USLT / Vorbis LYRICS — with an lrclib.net fallback fetched on a background thread.", |
| 33 | + "keys": ["Y"], |
| 34 | + "palette": { "name": "Ultraviolet", "a": "#B478F0", "b": "#4A3AB8" } |
| 35 | + }, |
| 36 | + { |
| 37 | + "title": "Spectrum & waveform", |
| 38 | + "desc": "Click the album art to cycle cover → spectrum bars → waveform. A mini spectrum always dances under the title.", |
| 39 | + "keys": ["CLICK"], |
| 40 | + "palette": { "name": "Tangerine Dream", "a": "#FF8A3C", "b": "#D6486B" } |
| 41 | + }, |
| 42 | + { |
| 43 | + "title": "Shuffle & repeat", |
| 44 | + "desc": "Fixed-order shuffle — the list is shuffled once and prev/next follow that order — plus 3-state repeat: off, one, all.", |
| 45 | + "keys": ["S", "L"], |
| 46 | + "palette": { "name": "Neon Meadow", "a": "#A5E63A", "b": "#2F9E63" } |
| 47 | + }, |
| 48 | + { |
| 49 | + "title": "System integration", |
| 50 | + "desc": "System-wide media keys, always-on-top, a procedurally drawn taskbar icon, and window position that survives restarts.", |
| 51 | + "keys": ["T"], |
| 52 | + "palette": { "name": "Glacier", "a": "#7FB5F5", "b": "#5C5CD6" } |
| 53 | + }, |
| 54 | + { |
| 55 | + "title": "Four formats, every glyph", |
| 56 | + "desc": "MP3, FLAC, OGG and WAV decoded by miniaudio. File open and decode go through the Win32 wide API, so Unicode paths work end to end.", |
| 57 | + "keys": ["O"], |
| 58 | + "palette": { "name": "Ember Days", "a": "#F4435E", "b": "#8B2E6B" } |
| 59 | + } |
| 60 | + ], |
| 61 | + "lyrics": { |
| 62 | + "caption": "timp.lrc — synced", |
| 63 | + "lines": [ |
| 64 | + "One window, borderless.", |
| 65 | + "The cover is the interface.", |
| 66 | + "Every record repaints the room.", |
| 67 | + "Decoded in C, drawn at refresh rate.", |
| 68 | + "No installer. No runtime. No telemetry.", |
| 69 | + "One exe, statically linked.", |
| 70 | + "Your folders, your glyphs, your music.", |
| 71 | + "Press space. That's it." |
| 72 | + ] |
| 73 | + }, |
| 74 | + "eq": { |
| 75 | + "heading": "The whole player fits on an equalizer", |
| 76 | + "note": "Ten modules of pure C11. Band height is each file's real share of the codebase — rl_main.c is the master fader.", |
| 77 | + "bands": [ |
| 78 | + { "file": "osdialog.c", "kb": "3.7", "level": 0.38, "role": "Native open dialog + DWM rounded corners" }, |
| 79 | + { "file": "audio.c", "kb": "7.2", "level": 0.53, "role": "miniaudio engine — thread-safe decode, Unicode paths" }, |
| 80 | + { "file": "tags.c", "kb": "10.1", "level": 0.6, "role": "ID3v2 / Vorbis metadata + embedded lyrics" }, |
| 81 | + { "file": "art.c", "kb": "6.1", "level": 0.49, "role": "Embedded + folder cover-art extraction" }, |
| 82 | + { "file": "lyrics.c", "kb": "11.3", "level": 0.62, "role": ".lrc / .txt parsing + lrclib.net fetch" }, |
| 83 | + { "file": "eq.c + fft.c", "kb": "6.3", "level": 0.5, "role": "10-band EQ + spectrum FFT" }, |
| 84 | + { "file": "playlist.c", "kb": "7.9", "level": 0.55, "role": "Queue, index + fixed-order shuffle" }, |
| 85 | + { "file": "playlistio.c", "kb": "5.0", "level": 0.45, "role": "Save / load / list .m3u8 playlists" }, |
| 86 | + { "file": "mediakeys.c", "kb": "1.8", "level": 0.25, "role": "System-wide media-key hotkeys" }, |
| 87 | + { "file": "rl_main.c", "kb": "82.8", "level": 1, "role": "Window, event loop, UI, every panel (raylib)" } |
| 88 | + ] |
| 89 | + }, |
| 90 | + "screens": [ |
| 91 | + { "src": "/images/projects/timp/main.png", "caption": "Now playing — accent sampled from the art" }, |
| 92 | + { "src": "/images/projects/timp/queue.png", "caption": "Queue drawer — reorder, remove, save as .m3u8" }, |
| 93 | + { "src": "/images/projects/timp/eq.png", "caption": "10-band EQ — 60 Hz to 16 kHz" }, |
| 94 | + { "src": "/images/projects/timp/lyrics.png", "caption": "Synced lyrics — karaoke highlight" }, |
| 95 | + { "src": "/images/projects/timp/settings.png", "caption": "Settings — drawer side, on-top, library" } |
| 96 | + ], |
| 97 | + "stats": [ |
| 98 | + { "value": "C11", "label": "pure, no runtime" }, |
| 99 | + { "value": "1", "label": "exe, zero DLLs" }, |
| 100 | + { "value": "4", "label": "audio formats" }, |
| 101 | + { "value": "10", "label": "EQ bands" }, |
| 102 | + { "value": "0", "label": "telemetry" }, |
| 103 | + { "value": "v0.9.0", "label": "anchored shuffle" } |
| 104 | + ], |
| 105 | + "build": { |
| 106 | + "caption": "MSYS2 / MinGW64", |
| 107 | + "lines": [ |
| 108 | + "pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-pkgconf mingw-w64-x86_64-raylib", |
| 109 | + ".\\build.ps1", |
| 110 | + ".\\build\\timp.exe" |
| 111 | + ] |
| 112 | + }, |
| 113 | + "liner": [ |
| 114 | + "Timp is what happens when a music player is built like a hi-fi component instead of a web app: one borderless window, large cover art, anti-aliased type, and an accent color sampled live from whatever record is playing.", |
| 115 | + "Under the hood it is pure C11. raylib draws the window at monitor refresh rate, miniaudio decodes MP3, FLAC, OGG and WAV on a worker thread, and everything links statically into a single timp.exe — no installer, no runtime, no telemetry.", |
| 116 | + "Playlists are honest .m3u8 files with absolute UTF-8 paths, settings live in a plain config.ini under %APPDATA%\\Timp, and lyrics arrive from .lrc files, embedded tags, or lrclib.net when the shelf is empty." |
| 117 | + ], |
| 118 | + "credits": [ |
| 119 | + { "name": "raylib", "role": "window, input, rendering — zlib", "href": "https://www.raylib.com/" }, |
| 120 | + { "name": "miniaudio", "role": "audio decode + output — MIT-0", "href": "https://miniaud.io/" }, |
| 121 | + { "name": "stb_image", "role": "cover-art decoding — public domain", "href": "https://github.com/nothings/stb" }, |
| 122 | + { "name": "lrclib.net", "role": "community lyrics database", "href": "https://lrclib.net/" } |
| 123 | + ], |
| 124 | + "license": "All code written for Timp is released into the public domain." |
| 125 | +} |
0 commit comments