Skip to content

Commit 5df5bdf

Browse files
authored
Merge pull request #1 from functionally/types-1
Types
2 parents ec88ed4 + 319647f commit 5df5bdf

7 files changed

Lines changed: 673 additions & 3 deletions

File tree

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
shellHook = ''
2727
echo "Entering Nix shell with Lean and VS Code..."
2828
export PS1="\[\e[1;32m\][nix-shell:\w]$\[\e[m\] "
29+
export PATH="$PWD/.lake/build/bin:$PATH"
2930
'';
3031
};
3132
in

src/Ep133.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
import Ep133.Parsing
3+
import Ep133.Types
4+
import Ep133.Util

src/Ep133/Parsing.lean

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
2+
import Ep133.Types
3+
import Ep133.Util
4+
5+
6+
open Ep133.Types
7+
open Ep133.Util (getFloat32BE getUInt32 require)
8+
9+
open ParseResult (throw)
10+
11+
12+
-- See <https://github.com/phones24/ep133-export-to-daw/blob/99454368f8da44b8b5bf495df0f89c72603b8dc4/docs/EP133_FORMATS.md> for reference.
13+
14+
namespace Ep133.Parsing
15+
16+
17+
def parseEffects (raw : ByteArray) : ParseResult Effects :=
18+
do
19+
require (raw.size >= 100)
20+
$ throw ("Effects only contains " ++ toString raw.size ++ " bytes.")
21+
let effectType := raw[4]!
22+
let active ← EffectLabel.ofUInt8 effectType
23+
let effects ←
24+
(List.range 7).mapM
25+
(fun i ↦
26+
do
27+
let label ← EffectLabel.ofUInt8 i.toUInt8
28+
let param1 := getFloat32BE raw $ 8 + 4 * i
29+
let param2 := getFloat32BE raw $ 72 + 4 * i
30+
pure ⟨ label , {param1, param2} ⟩
31+
)
32+
pure
33+
{
34+
raw
35+
, active
36+
, effects := Std.HashMap.ofList effects
37+
}
38+
39+
40+
def makePatternLabel (l : Fin 4) (n : UInt8) : ParseResult PatternLabel :=
41+
do
42+
require (n > 0 && n < 100)
43+
$ throw ("Pattern " ++ toString n ++ " is out of range.")
44+
pure {letter := l, number := Fin.ofNat 99 $ n.toNat - 1}
45+
46+
47+
def parseScene (raw : ByteArray) (offset : Nat) : ParseResult Scene :=
48+
do
49+
let patternA ← makePatternLabel 0 $ raw[offset + 0]!
50+
let patternB ← makePatternLabel 1 $ raw[offset + 1]!
51+
let patternC ← makePatternLabel 2 $ raw[offset + 2]!
52+
let patternD ← makePatternLabel 3 $ raw[offset + 3]!
53+
pure
54+
{
55+
patternA, patternB, patternC, patternD
56+
, timeSignature := {numerator := raw[offset + 4]!.toNat, denominator := raw[offset + 5]!.toNat}
57+
}
58+
59+
60+
def parseScenes (raw : ByteArray) : ParseResult Scenes :=
61+
do
62+
require (raw.size >= 605)
63+
$ throw ("Scenes only contains " ++ toString raw.size ++ " bytes.")
64+
let sceneCount := raw[604]! |> UInt8.toNat
65+
let scenes : List Scene ← (List.range sceneCount).mapM (fun n ↦ parseScene raw (1 + 6 * n))
66+
pure
67+
{
68+
raw
69+
, scenes := scenes.toArray
70+
}
71+
72+
73+
def parsePad (raw : ByteArray) : ParseResult Pad :=
74+
do
75+
require (raw.size = 26)
76+
$ throw ("Pad contains " ++ toString raw.size ++ " bytes instead of 27.")
77+
let playMode ← PlayMode.ofUInt8 raw[23]!
78+
let volume ← Volume.ofUInt8 raw[16]!
79+
let timeStretchMode ← TimeStretchMode.ofUInt8 raw[21]!
80+
let timeStretchBars ← TimeStretchBars.ofUInt8 raw[25]!
81+
let chokeGroup ← ChokeGroup.ofUInt8 raw[22]!
82+
let soundId ← SoundId.ofUInt8s raw[2]! raw[1]!
83+
let pan ← Pan.ofUInt8 raw[18]!
84+
let trim :=
85+
{
86+
left := getUInt32 0 raw[6]! raw[5]! raw[4]! |> UInt32.toNat
87+
right := getUInt32 0 raw[10]! raw[9]! raw[8]! |> UInt32.toNat
88+
}
89+
let pitch ← Pitch.ofUInt8s raw[17]! 0 -- raw[26]!
90+
pure
91+
{
92+
raw
93+
, soundId
94+
, volume
95+
, attack := raw[19]!
96+
, release := raw[20]!
97+
, playMode
98+
, timeStretch :=
99+
{
100+
mode := timeStretchMode
101+
, bars:= timeStretchBars
102+
, bpm := getFloat32BE raw 12
103+
}
104+
, pitch
105+
, trim
106+
, pan
107+
, chokeGroup
108+
, midiChannel := raw[3]!
109+
}
110+
111+
112+
end Ep133.Parsing

0 commit comments

Comments
 (0)