No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Krzysztof Krystian Jankowski b93e8223d3 no debug
2026-08-17 01:53:27 +02:00
Win32/Release upx 2026-08-17 01:53:04 +02:00
.gitignore no debug 2026-08-17 01:53:27 +02:00
concept-art.png concepts 2026-08-17 01:38:52 +02:00
P1XelMusic.dpr mvp 2026-08-17 01:48:16 +02:00
P1XelMusic.dproj mvp 2026-08-17 01:48:16 +02:00
P1XelMusic.dproj.local mvp build 2026-08-17 01:52:24 +02:00
P1XelMusic.res mvp build 2026-08-17 01:52:24 +02:00
README.md mvp 2026-08-17 01:49:31 +02:00
UnitMain.dfm mvp 2026-08-17 01:48:16 +02:00
UnitMain.pas mvp 2026-08-17 01:48:16 +02:00

Your engine already points in exactly the right direction: audio is planned as a simple frame-ticked tracker, and the engine rules explicitly lock music to a custom four-channel sequencer that stays simple enough to author reliably.

I would not build a traditional tracker first. Traditional trackers still expect you to think like a musician: C-4, D#4, chords, intervals, etc.

Instead, make the editor work like your graphics editor: paint musical intent onto a grid.

Core idea: “music LEGO”

Internally the editor knows notes. You mostly shouldn't have to.

Think in three concepts:

Rhythm → when something happens Function → what role it has: home / tension / bass / chord / drum Shape → does the melody go up, down, repeat, jump, answer another phrase?

The tool translates those into legal Game Boy notes.

For example, instead of:

C4 E4 G4 E4
D4 F4 A4 F4

you could see:

1   3   5   3
2   4   6   4

or even:

ROOT   HIGH   HIGHER   HIGH
UP     HIGH   PEAK     HIGH

Then a small optional label underneath teaches you:

1 = C
3 = E
5 = G

So you gradually learn theory without theory being required.

I would combine these creation methods

Method What you do What the editor does
Scale-Locked Painter Click cells vertically to create melody shapes Only allows notes that fit the current scale
Phrase Builder Insert blocks like RISE, FALL, ANSWER, REPEAT Generates editable melodies
Chord Wizard Pick HOME → MOVE → TENSION → HOME Converts that into a valid chord progression
Rhythm Library Pick a visual rhythm Applies timing to melody/bass/drums
Bass Library Pick ROOT, ROOT+5, OCTAVE, WALK, etc. Follows the current harmony automatically
Variation Generator Select 4 bars → “Make Variation” Keeps rhythm/harmony but modifies notes
Classic Tracker Direct note/effect editing Expert escape hatch when you eventually want it

The important one is scale locking.

You select something like:

KEY: C
SCALE: Minor
MOOD: Dark / Adventure

and the editor highlights perhaps seven usable rows.

You literally cannot accidentally paint a wildly wrong note unless you disable Scale Lock.


Don't start with musical terminology

Your main project settings could initially expose:

MOOD
[ Adventure ▼ ]

ENERGY
[====------]

DARK <--------> HAPPY

SPEED
[ Medium ▼ ]

COMPLEXITY
[ Simple ▼ ]

The editor can resolve this to:

Scale: A minor
Tempo: ...
Chord family: ...
Suggested instruments: ...

A Show Theory button reveals that information.

This gives you two simultaneous interfaces:

Composer Mode

HOME
MOVE
TENSION
HOME

Learn Mode

Am
F
G
Am

i
VI
VII
i

That is probably the strongest feature you could build for yourself.

You make music first, and learn why it works afterward.


Melody Shape Painter

This could be especially programmer-friendly.

Imagine a 16-column pattern:

HIGH |             ■
     |       ■ ■     ■
MID  |   ■ ■     ■
     | ■
LOW  |■
     +----------------
      01 02 03 ... 16

You're drawing a curve, almost like pixel art.

Because Scale Lock is enabled, vertical positions aren't chromatic piano notes. They're:

7
6
5
4
3
2
1

Scale degrees.

Now operations become very visual:

Flip Vertical
Flip Horizontal
Shift Up
Shift Down
Reverse
Repeat x2
Simplify
Add Variation
Make Ending
Make Answer

Those are almost exactly the sort of operations you already have in your pixel editor.

That similarity is valuable.


Rhythm should work like a palette

On the right side, instead of your Quick Palette, have:

QUICK RHYTHM

■■■■ ■■■■ ■■■■ ■■■■  Straight 16
■-■- ■-■- ■-■- ■-■-  Eighths
■--- ■--- ■--- ■---  Quarters
■--■ --■- ■--■ --■-  Syncopated
■-■■ --■- ■-■■ --■-  Adventure

Click one and it applies it to the selected range.

Same for drums.

DRUM PATTERNS

BASIC
ROCK
MARCH
GALLOP
SHUFFLE
BOSS
CHASE
DUNGEON
VICTORY

Each has 4/8/16 bar variations.

Don't make these MIDI drum patterns. Make them specifically for Game Boy Channel 4 noise.

So a drum database entry isn't merely:

Kick at 0
Snare at 4

It includes the actual Game Boy sound recipe.


Bass should almost compose itself

Bass is one area where you really don't need to understand notes.

Give it modes such as:

FOLLOW ROOT
ROOT + FIFTH
ROOT + OCTAVE
PULSE
WALK UP
WALK DOWN
ARPEGGIO
PEDAL
OFF-BEAT

If your harmony is:

HOME | MOVE | TENSION | HOME

the bass generator knows the underlying notes.

You can then hit:

[Generate]
[Variation]
[Simplify]
[More Energy]

This will get you surprisingly far.


Chord creation without knowing chords

I'd build a Progression Designer, but don't initially call the buttons chords.

Something like:

+--------+ +--------+ +---------+ +--------+
| HOME   | | TRAVEL | | TENSION | | HOME   |
| Stable | | Open   | | Wants   | | Stable |
+--------+ +--------+ +---------+ +--------+

Under Show Theory:

I → IV → V → I

You could have preset emotional progressions:

Adventure
Mystery
Danger
Sad
Heroic
Peaceful
Victory
Boss
Dungeon
Ocean
Puzzle

And importantly:

the presets should be recipes, not finished songs.

For example:

MYSTERY

Scale      Minor
Progression HOME → DARK → TENSION → HOME
Bass       Sparse
Rhythm     Slow syncopation
Melody     Narrow range
Movement   Mostly steps
Resolution Weak

Then the generators create material within those constraints.

That means your songs don't all sound like the same template.


Game Boy channels should be visible as roles

I'd default to:

CH1  LEAD
CH2  HARMONY / BASS
CH3  WAVE / BASS / PAD
CH4  DRUMS

But allow reassignment.

The editor can know the hardware restrictions and prevent impossible combinations.

For example, instead of exposing every sound register immediately:

CH1 INSTRUMENT

Duty        [ 50% ▼ ]
Attack      [ Fast ▼ ]
Decay       [ Medium ▼ ]
Brightness  [====----]
Sweep       [ Up ▼ ]

Advanced mode exposes the actual hardware values.

Again:

creative meaning first → hardware registers second.


Instrument editor

Your graphics editor has palette editing.

The equivalent for audio should be an Instrument Editor.

I would use visual envelopes:

VOLUME

15 |■■
   |■■■■
   |■■■■■■
   |■■■■■■■■
 0 +----------------
     TIME →

and:

PITCH

HIGH        /
           /
          /
LOW  ----- 

Then controls like:

Duty       [12.5][25][50][75]
Attack     [Instant ▼]
Decay      [Medium ▼]
Pitch Env  [None ▼]
Vibrato    [Small ▼]

With a button:

[ PLAY C ]

or preferably:

[ PLAY LOW ]
[ PLAY MID ]
[ PLAY HIGH ]

because even there you don't necessarily need note names.


SFX editor should be even less musical

SFX are ideal for this philosophy.

Don't use tracker notation at all.

Make SFX from pitch + volume + noise curves.

For example:

LASER

PITCH   HIGH █████\
                 \
                  \ LOW

VOLUME  ████████\
                 \___

PICKUP

PITCH   LOW  / / / HIGH
VOLUME  ███████\__

EXPLOSION

NOISE   █████████████
VOLUME  ████████\____
PITCH   LOW

Give yourself a library:

UI CLICK
UI ACCEPT
UI CANCEL
COIN
PICKUP
DOOR
STEP
HIT
HURT
LASER
POWER LASER
EXPLOSION
MAGIC
HEAL
ALERT
DEATH
VICTORY

Then every preset has:

[Randomize]
[Shorter]
[Longer]
[Brighter]
[Darker]
[Harder]
[Softer]

This could make SFX creation extremely fast.


Very important: play SFX over music

Your editor should simulate actual game behaviour.

Have:

PLAY SONG

then click:

SFX: LASER

and hear what actually happens when that SFX needs a channel.

The editor should have an SFX channel policy:

LASER
Priority: 2

Preferred:
[x] CH1
[ ] CH2
[ ] CH3
[x] CH4

Steal:
[x] Allowed

Resume music afterward:
[x]

This will help design the runtime audio system too.


UI matching your P1XEL editor

I would make it visually almost identical.

Something roughly like:

File  Edit  Export  Project  Tools  View  Help
─────────────────────────────────────────────────────────
P1XEL AUDIO - PROJECT.P1X                  Open | Save

 SONG / PATTERN      AUDIO TRACKER                   SOUND
 SELECTOR
                   Tracker Instrument SFX Library
 SONG 01
  Intro
  Loop             ┌───────────────────────────────┐
  Ending            │ CH1   LEAD                   │
                    │      ■   ■■       ■          │
 PATTERNS            │    ■       ■  ■              │
  P00                │                               │
  P01                │ CH2   BASS                   │
  P02                │ ■---■---■---■---             │
                    │                               │
 INSTRUMENTS         │ CH3   WAVE                   │
  Lead 1             │                               │
  Bass 1             │ CH4   DRUMS                  │
  Drum 1             │ ■-■---■-■---■-■              │
                    └───────────────────────────────┘

                    ◀  ■  ▶  LOOP      BPM/SPEED

 THEORY HELPER                         QUICK PATTERN
 Key: C                               Straight
 Scale: Minor                         Gallop
 Mood: Adventure                      March
 [x] Scale Lock                       Syncopated
                                      Boss

And keep your current aesthetic:

  • Win2000 gray controls
  • classic menu bar
  • tabs
  • group boxes
  • tiny status bar
  • no giant modern buttons
  • almost everything visible simultaneously
  • right-click context menus
  • keyboard shortcuts
  • drag selection
  • copy/paste
  • very little modal UI

Your screenshots already have a nice tool/workbench feeling. Audio should feel like another module of exactly that application rather than a separate DAW.


The tracker itself

Eventually I'd still have a conventional tracker representation, but simplified.

Instead of:

ROW | CH1         | CH2         | CH3         | CH4
00  | C-4 01 A03  | C-2 02 ...  | --- -- ---  | N01
01  | --- -- ---  | === -- ---  | --- -- ---  | ---

default to:

    LEAD       BASS       WAVE       DRUM
00  1          ROOT                  KICK
01  .          .                     .
02  3          .                     HAT
03  .          .                     .
04  5          ROOT                  SNARE

and have:

View → Tracker Values

turn it into the hardware-oriented representation.


Store music as patterns, not a timeline

For your particular engine I would keep runtime architecture tiny.

Your engine has one logic tick per frame, so the editor can express timing directly as:

Frames Per Row = 6

rather than needing an independent high-resolution timer. That fits the engine's one-frame/one-tick rule very naturally.

A song becomes approximately:

Song
 ├─ order[]
 │   P00
 │   P01
 │   P01
 │   P02
 │
 ├─ patterns[]
 ├─ instruments[]
 └─ speed

Each channel row only really needs concepts such as:

NOTE
HOLD
REST
INSTRUMENT
VOLUME
EFFECT

That keeps the RGBDS player small.


I'd also copy the philosophy of your graphics pipeline

Your graphics side has the editor produce data the engine can consume directly, with the engine avoiding unnecessary transformation. That's one of the core ideas of the existing P1XEL contract.

I'd do exactly the same for audio.

Something like:

project.p1x
      ↓
P1XEL AUDIO
      ↓
song.p1a
sfx.p1a
      ↓
zig build
      ↓
audio_assets.inc
      ↓
RGBDS

Eventually you could give audio its own tiny versioned contract.

Not now, though. First get the editor/playback model right.


One feature I think would make this tool unusually good

Add a WHY? button.

Click a note:

WHY DOES THIS FIT?

and the status area says:

This is scale degree 5. It belongs to the current chord and creates mild tension toward HOME.

Click another:

This note is outside the current chord but inside the scale. It works well as a passing note.

Click a bass note:

ROOT is the safest bass note here.

That turns the editor into an interactive music-theory teacher without turning music theory into a prerequisite.

Over time you would naturally learn:

root, third, fifth, scale, chord, resolution, syncopation, octave, etc.

But you'd learn them by making game music, not by studying notation.

The first version I'd build

Don't implement everything above.

V0.1 should be only:

Song → Pattern → 4 Channels → 16/32 Rows

plus:

Scale Lock + Melody Painter + Rhythm Library + Bass Auto-Follow + Noise Drum Library + Instrument Editor + SFX Envelope Editor.

That is already enough to make complete Game Boy soundtracks without knowing conventional notation.

And I would make the three primary tabs:

TRACKER | INSTRUMENT EDITOR | SFX EDITOR

with PATTERN LIBRARY and SONG MANAGER beside them, exactly in the visual language of your current P1XEL editor.

The strongest design principle for the whole thing is:

The user paints musical relationships; the editor chooses notes.

That would make this much more useful to a programmer than simply cloning LSDj or a classic tracker.

MVP

Implemented in this prototype

  • Tracker with four Game Boy-oriented roles:
    • CH1 Lead / Square 1
    • CH2 Bass / Square 2
    • CH3 Wave
    • CH4 Drums / Noise
  • Scale-degree composition (1..7) instead of requiring note names.
  • Scale Lock and a contextual Why this fits? learning helper.
  • Mood, key, scale, frames-per-row, and tempo controls.
  • One-click Quick Rhythm generators.
  • One-click Bass Pattern generators (root, fifth, octave, arpeggio, pulse, walk-down).
  • Drum-kit buttons that write directly into the selected tracker row.
  • Pattern tree, pattern selector, reusable song-flow blocks, row insert/delete/copy/paste/clear, and degree transpose.
  • Instrument Editor with square-wave duty visualization and low/mid/high preview.
  • SFX Editor with pitch/noise shape visualization, preset list, randomize/shorter/brighter helpers, and preview.
  • Sound Manager prototype for SFX channel stealing / priority policy.
  • .p1m JSON project save/load.
  • Prototype RGBDS include exporter.
  • Lightweight Windows audio preview generated in memory using square/noise PCM. No third-party audio library is required.

Build

Open P1XelMusic.dproj in Delphi 13 and build Win32 or Win64.

The project uses only RTL/VCL units and winmm (PlaySound) through Winapi.MMSystem.

Project format

.p1m is deliberately simple JSON for now. It stores global composition settings plus tracker patterns and rows. This is an editor format, not the final ROM/runtime format.

RGBDS export

Export -> RGBDS Include... emits a compact prototype table:

row = CH1 note-id, CH2 note-id/command, CH3 note-id, CH4 drum-id

255 currently means HOLD for tonal channels. Drum IDs are emitted as constants. The runtime format should be finalized together with the engine audio module before it becomes a stable contract.

Current preview limitation

The desktop preview is intentionally lightweight rather than a complete Game Boy APU emulator. It previews one generated square/noise sound at a time. The editor data model and UI are ready for a later channel-accurate GBC APU preview backend.