Skip to content

Commit ebaed31

Browse files
committed
feat(projects): add Timp music player with new hi-fi project theme
1 parent 881b778 commit ebaed31

15 files changed

Lines changed: 1229 additions & 100 deletions

File tree

PROJECTS.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,53 @@ Dush is a minimalist shell...
123123
- Feature 2
124124
```
125125

126-
## 4. Assets
126+
## 4. Hi-Fi Layout
127+
128+
The **Hi-Fi** style (`(style) hifi`) turns the project page into a working music
129+
player. It was built for **Timp** but is fully data-driven and reusable for any
130+
audio/media project. Warm near-black ink, cream type (Unbounded display, Hanken
131+
Grotesk body, Spline Sans Mono labels), and — the signature — a transport that
132+
"plays" a queue of color palettes: every record re-samples the whole page's
133+
accent colors, exactly like Timp samples its accent from album art.
134+
135+
Sections mirror the app's own panels: **Now Playing** (hero player + record
136+
rack), **The Queue** (features as tracks, keyed with real hotkeys), **Lyrics**
137+
(manifesto with scroll-synced karaoke highlight), **Equalizer** (source modules
138+
as faders, heights = real file sizes), **Screens**, and **Liner Notes** (stats,
139+
build snippet, credits). A mini-player bar docks to the bottom once the hero
140+
scrolls away.
141+
142+
### Directory Structure
143+
144+
All content lives in a single JSON config:
145+
146+
```text
147+
public/projects/my-player/
148+
└── hifi.txt # One JSON config for the whole page
149+
```
150+
151+
### `hifi.txt` keys
152+
153+
* `wordmark`, `tagline`, `artist`, `version`, `repo`, `download`, `formats`
154+
* `trackSeconds`: how long each palette "track" plays (default 24)
155+
* `queue[]`: `{ title, desc, keys[], palette: { name, a, b } }` — one entry
156+
per feature; `a`/`b` are the two gradient stops sampled into `--acc`/`--acc2`
157+
* `lyrics`: `{ caption, lines[] }`
158+
* `eq`: `{ heading, note, bands[]: { file, kb, level (0..1), role } }`
159+
* `screens[]`: `{ src, caption }`
160+
* `stats[]`: `{ value, label }`
161+
* `build`: `{ caption, lines[] }` (rendered with a copy button)
162+
* `liner[]`: paragraphs, `credits[]`: `{ name, role, href }`, `license`
163+
164+
## 5. Assets
127165

128166
* **Images**: Place images in `public/images/projects/` or `public/images/bg/`.
129167
* **Icons**: Use Phosphor icons where applicable in code, or SVG assets.
130168

131-
## 5. Adding a New Project Checklist
169+
## 6. Adding a New Project Checklist
132170

133171
1. Create the folder `public/projects/[your-slug]`.
134-
2. Choose your style: `stylish` or `editorial`.
172+
2. Choose your style: `stylish`, `editorial`, `hifi`, etc.
135173
3. Create the corresponding `.txt` files based on the chosen style's structure.
136174
4. Add the project to `public/projects/projects.piml` with the correct `(style)` field.
137175
5. Run `npm run lint` to ensure code quality.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fezcodex",
3-
"version": "0.27.3",
3+
"version": "0.28.0",
44
"private": true,
55
"homepage": "https://fezcode.com",
66
"dependencies": {

public/images/projects/timp/eq.png

28.2 KB
Loading
32.3 KB
Loading
89.9 KB
Loading
31.6 KB
Loading
34.9 KB
Loading

public/projects/projects.piml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,27 @@
4949
(date) 2026-04-27
5050
(image) /images/projects/gobake/gobake-banner.png
5151

52+
> (project)
53+
(slug) timp
54+
(title) Timp
55+
(style) hifi
56+
(version) 0.9.0
57+
(size) 2
58+
(repo_link) https://github.com/fezcode/timp
59+
(demo_link) https://github.com/fezcode/timp/releases
60+
(pinned) true
61+
(isActive) true
62+
(technologies)
63+
> C11
64+
> raylib
65+
> miniaudio
66+
> Audio
67+
> Native
68+
> Windows
69+
(shortDescription) Timp is a small, native, album-art-forward music player written in C with raylib. Borderless Hi-Fi window, accent color sampled from the artwork, live spectrum, 10-band EQ, synced lyrics, and a slide-out playlist drawer — all statically linked into a single timp.exe.
70+
(date) 2026-07-04
71+
(image) /images/projects/timp/main.png
72+
5273
> (project)
5374
(slug) urban-tasks
5475
(title) Urban Tasks

public/projects/timp/hifi.txt

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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

Comments
 (0)