Skip to content

Instantly share code, notes, and snippets.

@Vap0r1ze
Last active December 30, 2023 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vap0r1ze/f1c1eca6c04ae5817c1ab9ecbdcf56d7 to your computer and use it in GitHub Desktop.
Save Vap0r1ze/f1c1eca6c04ae5817c1ab9ecbdcf56d7 to your computer and use it in GitHub Desktop.
uiua minimal trackerish thing
LoadSong ← &i "song.ua" "LoadSong"
SampleSong ← &i "song.ua" "SampleSong"
Bpm ← 150
GetFreq ← (
++⊓(⊗:"A BC D EF G"|-1⊗:"b-#"|×12-@0) °[⊙⊙∘]
×55 ⁿ:2 ÷12
)
# Waves
Waves ← {"Sine" "Tri" "Square" "Saw" "Noise"}
Sine ← ○×τ
Tri ← -:1×4⌵-0.25-⊃(⌊+0.25)∘
Square ← ±Sine
Saw ← ×2-⊃(⌊+0.5)∘
Noise ← (-1×2⚂|0)=0
SawGood ← × -:1 ⁿ20 .Saw
# [Wave Amp Freq][instr] timestamp -- sample
Render ← /+≡(
⊃(∘|×⋅⋅⊙∘|⋅∘) °[⊙⊙∘]
×(Sine|Tri|Square|Saw|Noise)
)
TitleTheme ← LoadSong "songs/title.txt" Waves
AudioStream ← (
SampleSong:TitleTheme ×Bpm÷60 .
≡Render
)
StartAudio ← (; spawn&ast AudioStream)
# &sl 10 StartAudio
# ÷&asr ⇡×&asr ×NumProcs4
# ≡spawn AudioStream ↯[NumProcs ¯1]
# &fwa "tetris.wav" &ae "wav" ♭≡wait
GetLines ← ▽≠@#≡⊢. ⊜□≠@\n. &fras
GetFreq ← (
++⊓(⊗:"C D EF G A B"|-1⊗:"b-#"|×12-@0) °[⊙⊙∘]
×32.7 ⁿ:2 ÷12
)
ParseTrack ← (
°¤ regex"\\w+"
⍜°[⊙⊙∘]⊓(∘|∘|⋕)
)
# - `0` New note
# - `1` Continued note
# - `2` Stop note
GetNoteType ← ×+1 ⊃(⊗1|/↥) [⊃(≍"-->"|≍"===")]
ParseSeq ← ⍜°□(
≡([⊃∘(×=0) ⊃(GetNoteType|GetFreq)])
\((⊙;|⍜(⊡1|⋅(⊡1))|⊙;) ⊢.:)
)
ParseInstr ← (
⊜□≠@ . °□
⍜°[⊙⊙⊙∘]⊓(∘|∘|⋕|□ ⊜⋕≠@/. °□)
)
GetTracks ← ≡ParseTrack ▽=@-≡⊢.
GetSeqs ← (
⊜(□ ⊜∘≠@ . ⊐/(⊂⊂:" ")) <\↥. =@-≡⊢.
≡ParseSeq
)
GetInstrs ← ≡ParseInstr ↘1↙⊗1=@-≡⊢.
GetArrangement ← ⊜(⍜°⊟⊙⋕ ⊜□≠@ .)≠@,. °□⊢
SongData ← ∵°□ ≡⍜⊢⊗ ⊙¤ ⊃(GetArrangement|⊝≡⊢GetTracks)
InstrData ← (
≡⍜⊢⊗ ≡↘1 ⊙¤ GetInstrs
≡(⊂⊟ ⊓(°□|°□|°□) °[⊙⊙∘])
)
TrackData ← (
⊃(GetTracks|⊝≡⊢GetTracks|≡⊢GetInstrs)
∵°□ ≡⍜(°⊟↙2)⊃(⊗⊙⋅∘|⊗⋅⊙⋅∘) ⊙∩¤
)
# `File WaveTypes` -> `{Song Instrs Tracks Seqs}`
# - `Song` = `[PatId Length][]`
# - `Instr` = `[WaveId Vol A D S R]`
# - `Track` = `[PatId InstrId SubSize]`
LoadSong ← {⊃(SongData|TrackData|GetSeqs|InstrData)} GetLines
SamplePats ← ⊏ /+⊞≥: ⊃(◿:⊙/↥)⋅∘⊙(\+ °⊟ ⇌⍉)
SampleTracks ← ≡≡⊗ ⊙(¤¤≡↙2.) ⊠⊟ ⊙(⇡⧻.) SamplePats
TrackEnvStart ← ⊢⇌⊚≠1 ≡⊢ ↙⌊+1◿⧻,×÷4
# TODO TrackEnvEnd, encode "release" T as negative value
TrackEnvT ← ×-⊃(TrackEnvStart|⊙; ◿⧻,×÷4|÷:4)
TrackFreq ← ⊡1⊡⌊◿⧻,×÷4
SampleOsc ← ⊟⊃(TrackEnvT|TrackFreq) ⊃(⊢⇌⊡|⋅⋅∘|°□⊡⊙⋅;)
A ← (÷⊢:|⋅⋅1) =0⊢,
D ← (-:1 ×⊃(-:1 ⋅(⊡2)|÷:-: ⊙(°⊟↙2))|⋅⊡2) =0⊡1,
S ← ⋅(⊡2)
R ← (×⊃(⊡2|↥0 +1 ÷ ⊡3):|⋅⋅0) =0⊡3,
ADSR ← (R|A|D|S)⊃(/+≥: ⊙(⊂0 \+ ↙2))⊙∘
# timestamps[] Song -- [Wave Amp Freq][instr][]
SampleSong ← (
⊙°{⊙⊙⊙∘}
⊃∘SampleTracks
≡≡SampleOsc ⊃⋅⊙∘∘ ⊙⊙∩(¤¤)
≡≡(
⍜⊢(×⊃(ADSR ⊙(⊏2_3_4_5)|⊡1;))
⊂↙1:
) ⊙⊃¤¤
)
Main 64
# Inst Wave Vol A/D/S/R
Bass Tri 0.35 0/0/1/0
Lead Tri 0.25 0/0.75/0.22/0
Dot Tri 0.2 0/0.5/0/0
Hat Noise 0.125 0/0.125/0/0
--- Main: Bass [8] ---
E-1 E-2 E-1 E-2 E-1 E-2 E-1 E-2
A-1 A-2 A-1 A-2 A-1 A-2 A-1 A-2
G#1 G#2 G#1 G#2 E-1 E-2 E-1 E-2
A-1 A-2 A-1 A-2 A-1 A-2 B-1 C-2
D-2 D-1 === D-1 === D-1 A-1 F-1
C-1 C-2 === C-2 C-1 G-1 G-1 ===
B-1 B-2 === B-2 === E-2 === G#2
A-1 E-2 A-1 E-2 A-1 A-1 === ===
--- Main: Lead [8] ---
E-4 --> B-3 C-4 D-4 --> C-4 B-3
A-3 --> A-3 C-4 E-4 --> D-4 C-4
B-3 --> === C-4 D-4 --> E-4 -->
C-4 --> A-3 --> A-3 --> === ===
=== D-4 --> F-4 A-4 --> G-4 F-4
E-4 --> === C-4 E-4 --> D-4 C-4
B-3 --> B-3 C-4 D-4 --> E-4 -->
C-4 --> A-3 --> A-3 --> === ===
--- Main: Dot [16] ---
=== === === === G#3 --> A-3 --> B-3 --> === === A-3 --> G#3 -->
E-3 --> === === === === === === === === === === B-3 --> A-3 -->
G#3 G#3 E-3 --> G#3 --> A-3 --> B-3 --> === === C-4 --> === ===
A-3 --> === === E-3 --> === === E-3 --> === === === === === ===
=== === F-3 --> === === A-3 --> C-4 --> C-4 C-4 B-3 --> A-3 -->
G-3 --> === === === === E-3 --> G-3 --> A-3 G-3 F-3 --> E-3 -->
G#3 --> E-3 --> G#3 --> A-3 --> B-3 --> G#3 --> === === G#3 -->
A-3 --> E-3 --> E-3 --> === === E-3 --> === === === === === ===
--- Main: Hat [16] ---
=== === C-1 === === === C-1 ===
=== === C-1 C-1 === === C-1 ===
=== === C-1 === === === C-1 ===
=== === C-1 === C-1 === C-1 ===
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment