@@ -12,13 +12,13 @@ open Midinette.Sysex
12
12
13
13
type NonZeroIndexedArraySegment < 't >( baseLogicalAddress : int , segment : ArraySegment < 't >) =
14
14
let checkAddress address =
15
- if address < baseLogicalAddress then failwithf " can't query bellow base logical address"
15
+ if address < baseLogicalAddress then failwithf " can't query at %i which is bellow base logical address %i " address baseLogicalAddress
16
16
let address = address - baseLogicalAddress
17
- if address >= segment.Count then failwithf " can't query after the segment"
17
+ if address >= segment.Count then failwithf " can't query at %i which is past the segment (length: %i ) " address segment.Count
18
18
address
19
19
let checkAddressAndLength address length =
20
20
let address = checkAddress address
21
- if length > segment.Count then failwithf " can't query length past segment"
21
+ if length > segment.Count then failwithf " can't query at %i elements from %i which is past the segment (length: %i ) " length address segment.Count
22
22
address
23
23
member x.LogicalOffset = baseLogicalAddress
24
24
member x.Get address =
@@ -29,7 +29,7 @@ type NonZeroIndexedArraySegment<'t>(baseLogicalAddress: int, segment: ArraySegme
29
29
let address = checkAddress address
30
30
segment.Array.[ segment.Offset + address] <- value
31
31
32
- member x.Array = segment.Array.[ segment.Offset .. ( segment.Count - 1 )]
32
+ member x.Array = segment.Array.[ segment.Offset .. ( segment.Offset + ( segment. Count - 1 ) )]
33
33
member x.GetSlice address length =
34
34
let address = checkAddressAndLength address length
35
35
let slice = segment.Array.[ segment.Offset + address .. ( segment.Offset + address + length - 1 )]
@@ -89,7 +89,7 @@ module Sysex =
89
89
let [<Literal>] kit = 0x4D1
90
90
let [<Literal>] patternShort = 0xacd
91
91
let [<Literal>] patternLong = 0x1522
92
-
92
+ let [<Literal>] globalsSettings = 0xc5
93
93
module Offsets =
94
94
let [<Literal>] messageId = 0x6
95
95
module Kit =
@@ -100,6 +100,8 @@ module Sysex =
100
100
let [<Literal>] delay = 0x48f
101
101
let [<Literal>] equalizer = 0x497
102
102
let [<Literal>] compressor = 0x49f
103
+ let [<Literal>] checksum = 0x4cc
104
+ let [<Literal>] messageLength = 0x4ce
103
105
module Pattern =
104
106
let [<Literal>] pattern = 0x9
105
107
(* let [<Literal>] trigPattern = 0xa
@@ -109,8 +111,39 @@ module Sysex =
109
111
let [<Literal>] patternLength = 0xb2
110
112
let [<Literal>] multiplier = 0xb3
111
113
*)
114
+ module Empty =
115
+ let newKitBuffer () =
116
+ NonZeroIndexedArraySegment<_>( Offsets.Kit.kit, new ArraySegment<_>( Array.zeroCreate Sizes.kit))
117
+ module Versions =
118
+ module Kit =
119
+ let [<Literal>] version = 0x4 uy
120
+ let [<Literal>] revision = 0x1 uy
121
+
122
+ let makeMachineDrumSysexMessageWithChecksum messageType ( messageBluePart : data ) : sysex_data =
123
+ let version , revision =
124
+ match messageType with
125
+ | MachineDrumSysexMessageId.Kit -> Versions.Kit.version, Versions.Kit.revision
126
+
127
+ let sysexEnd = 0xf7 uy
128
+ let checksumBytes =
129
+ checkSum messageBluePart
130
+ |> word14To2bytes
112
131
113
-
132
+ let messageLength =
133
+ ( messageBluePart.Length + 4 )
134
+ |> word14To2bytes
135
+
136
+ [|
137
+ yield ! mdHeader
138
+ yield UMX.tag_ sysex_ data ( byte messageType)
139
+ yield ! UMX.tag_ sysex_ data [| version; revision|]
140
+ yield ! UMX.to_ sysex_ data messageBluePart;
141
+ yield ! UMX.tag_ sysex_ data checksumBytes
142
+ yield ! UMX.tag_ sysex_ data messageLength
143
+ yield UMX.tag_ sysex_ data sysexEnd
144
+ |]
145
+
146
+
114
147
let validateSysexShape ( sysex : sysex_data ) =
115
148
if not ( areMachineDrumCheckSumAndLengthValid sysex) then
116
149
failwithf " invalid check sum"
@@ -124,6 +157,9 @@ module Sysex =
124
157
match sysex.Length with
125
158
| Sizes.patternShort | Sizes.patternLong -> ()
126
159
| _ -> failwithf " pattern supposed to be %i or %i but got %i " Sizes.patternShort Sizes.patternLong sysex.Length
160
+ | MachineDrumSysexMessageId.Global ->
161
+ if sysex.Length <> Sizes.globalsSettings then
162
+ failwithf " globalsettings supposed to be %i but got %i " Sizes.globalsSettings sysex.Length
127
163
| otherwise ->
128
164
failwithf " non checked message id %A " otherwise
129
165
@@ -205,6 +241,8 @@ type MasterEffect =
205
241
with
206
242
static member asByte = function | Delay -> 0x5d uy | Reverb -> 0x5e uy | Equalizer -> 0x5f uy | Compressor -> 0x60 uy
207
243
244
+
245
+
208
246
type MDMachine =
209
247
| GND_ EM = 00 uy | GND_ SN = 01 uy | GND_ NS = 02 uy | GND_ IM = 03 uy
210
248
| TRX_ BD = 16 uy | TRX_ SD = 17 uy | TRX_ XT = 18 uy | TRX_ CP = 19 uy | TRX_ RS = 20 uy | TRX_ CB = 21 uy | TRX_ CH = 22 uy | TRX_ OH = 23 uy
@@ -245,9 +283,69 @@ type MDUWMachine =
245
283
| RAM_ P3 = 39 uy
246
284
| RAM_ P4 = 40 uy
247
285
286
+
287
+ type MDMachineKind =
288
+ | GND
289
+ | TRX
290
+ | EFM
291
+ | E12
292
+ | PI
293
+ | INP
294
+ | MID
295
+ | CTR
296
+ | ROM
297
+ | RAM
298
+
248
299
type MDMachineType =
249
300
| MD of MDMachine
250
301
| MDUW of MDUWMachine
302
+ member x.Kind =
303
+ match x with
304
+ | MD m ->
305
+ match m with
306
+ | MDMachine.GND_ EM| MDMachine.GND_ IM| MDMachine.GND_ NS| MDMachine.GND_ SN -> GND
307
+ | MDMachine.TRX_ BD| MDMachine.TRX_ SD| MDMachine.TRX_ XT| MDMachine.TRX_ CP
308
+ | MDMachine.TRX_ RS| MDMachine.TRX_ CB| MDMachine.TRX_ CH| MDMachine.TRX_ OH
309
+ | MDMachine.TRX_ CY| MDMachine.TRX_ MA| MDMachine.TRX_ CL| MDMachine.TRX_ XC| MDMachine.TRX_ B2 -> TRX
310
+ | MDMachine.EFM_ BD| MDMachine.EFM_ SD| MDMachine.EFM_ XT| MDMachine.EFM_ CP
311
+ | MDMachine.EFM_ RS| MDMachine.EFM_ CB| MDMachine.EFM_ HH| MDMachine.EFM_ CY -> EFM
312
+ | MDMachine.E12_ BD| MDMachine.E12_ SD| MDMachine.E12_ HT | MDMachine.E12_ LT| MDMachine.E12_ CP| MDMachine.E12_ RS| MDMachine.E12_ CB| MDMachine.E12_ CH
313
+ | MDMachine.E12_ OH| MDMachine.E12_ RC| MDMachine.E12_ CC | MDMachine.E12_ BR| MDMachine.E12_ TA| MDMachine.E12_ TR| MDMachine.E12_ SH| MDMachine.E12_ BC -> E12
314
+ | MDMachine.P_ I_ BD| MDMachine.P_ I_ SD| MDMachine.P_ I_ MT| MDMachine.P_ I_ ML| MDMachine.P_ I_ MA| MDMachine.P_ I_ RS| MDMachine.P_ I_ RC| MDMachine.P_ I_ CC
315
+ | MDMachine.P_ I_ HH -> PI
316
+ | MDMachine.INP_ GA| MDMachine.INP_ GB| MDMachine.INP_ FA| MDMachine.INP_ FB| MDMachine.INP_ EA| MDMachine.INP_ EB -> INP
317
+ | MDMachine.MID_ 01| MDMachine.MID_ 02| MDMachine.MID_ 03| MDMachine.MID_ 04| MDMachine.MID_ 05| MDMachine.MID_ 06| MDMachine.MID_ 07| MDMachine.MID_ 08
318
+ | MDMachine.MID_ 09| MDMachine.MID_ 10| MDMachine.MID_ 11| MDMachine.MID_ 12| MDMachine.MID_ 13| MDMachine.MID_ 14| MDMachine.MID_ 15| MDMachine.MID_ 16 -> MID
319
+ | MDMachine.CTR_ AL| MDMachine.CTR_ 8P| MDMachine.CTR_ RE| MDMachine.CTR_ GB| MDMachine.CTR_ EQ| MDMachine.CTR_ DX -> CTR
320
+ | _ -> failwithf " kind %A " m
321
+ | MDUW m ->
322
+ match m with
323
+ | MDUWMachine.ROM_ 01| MDUWMachine.ROM_ 17| MDUWMachine.ROM_ 33
324
+ | MDUWMachine.ROM_ 02| MDUWMachine.ROM_ 18| MDUWMachine.ROM_ 34
325
+ | MDUWMachine.ROM_ 03| MDUWMachine.ROM_ 19| MDUWMachine.ROM_ 35
326
+ | MDUWMachine.ROM_ 04| MDUWMachine.ROM_ 20| MDUWMachine.ROM_ 36
327
+ | MDUWMachine.ROM_ 05| MDUWMachine.ROM_ 21| MDUWMachine.ROM_ 37
328
+ | MDUWMachine.ROM_ 06| MDUWMachine.ROM_ 22| MDUWMachine.ROM_ 38
329
+ | MDUWMachine.ROM_ 07| MDUWMachine.ROM_ 23| MDUWMachine.ROM_ 39
330
+ | MDUWMachine.ROM_ 08| MDUWMachine.ROM_ 24| MDUWMachine.ROM_ 40
331
+ | MDUWMachine.ROM_ 09| MDUWMachine.ROM_ 25| MDUWMachine.ROM_ 41
332
+ | MDUWMachine.ROM_ 10| MDUWMachine.ROM_ 26| MDUWMachine.ROM_ 42
333
+ | MDUWMachine.ROM_ 11| MDUWMachine.ROM_ 27| MDUWMachine.ROM_ 43
334
+ | MDUWMachine.ROM_ 12| MDUWMachine.ROM_ 28| MDUWMachine.ROM_ 44
335
+ | MDUWMachine.ROM_ 13| MDUWMachine.ROM_ 29| MDUWMachine.ROM_ 45
336
+ | MDUWMachine.ROM_ 14| MDUWMachine.ROM_ 30| MDUWMachine.ROM_ 46
337
+ | MDUWMachine.ROM_ 15| MDUWMachine.ROM_ 31| MDUWMachine.ROM_ 47
338
+ | MDUWMachine.ROM_ 16| MDUWMachine.ROM_ 32| MDUWMachine.ROM_ 48 -> ROM
339
+ | MDUWMachine.RAM_ R1
340
+ | MDUWMachine.RAM_ R2
341
+ | MDUWMachine.RAM_ P1
342
+ | MDUWMachine.RAM_ P2
343
+ | MDUWMachine.RAM_ R3
344
+ | MDUWMachine.RAM_ R4
345
+ | MDUWMachine.RAM_ P3
346
+ | MDUWMachine.RAM_ P4 -> RAM
347
+ | _ -> failwithf " kind uw %A " m
348
+
251
349
member x.HasPitch =
252
350
match x with
253
351
| MDUW ( MDUWMachine.RAM_ R1| MDUWMachine.RAM_ R2| MDUWMachine.RAM_ R3| MDUWMachine.RAM_ R4) -> false
@@ -292,8 +390,11 @@ with
292
390
FilterBaseFrequency ; FilterWidth ; FilterQ ; SampleRateReduction
293
391
Distortion ; Volume ; Pan ; DelaySend
294
392
ReverbSend ; LFOSpeed ; LFOAmount ; LFOShapeMix
295
-
296
393
|]
394
+ static member synthesisParameters = MDTrackParameter.all.[ 0 .. 7 ]
395
+ static member effectsParameters = MDTrackParameter.all.[ 8 .. 15 ]
396
+ static member routingParameters = MDTrackParameter.all.[ 16 .. 23 ]
397
+
297
398
static member fromCCOffset offset =
298
399
match UMX.untag_ byte_ 7bits offset with
299
400
| 00 uy -> MachineParameter1 | 01 uy -> MachineParameter2 | 02 uy -> MachineParameter3 | 03 uy -> MachineParameter4
@@ -700,7 +801,6 @@ type MDKit private (bytes: NonZeroIndexedArraySegment<byte_7bits>) =
700
801
let dataSlice = bytes.GetSlice address length
701
802
dataSlice
702
803
|> dataToByte
703
-
704
804
member x.Position = bytes.Get Sysex.Offsets.Kit.kit
705
805
member x.Name
706
806
with get () = bytes.GetSlice 0x0a 16 |> unbox |> ASCIIEncoding.Default.GetString
@@ -779,9 +879,11 @@ type MDKit private (bytes: NonZeroIndexedArraySegment<byte_7bits>) =
779
879
let segment = NonZeroIndexedArraySegment( Sysex.Offsets.Kit.kit, segment)
780
880
MDKit segment
781
881
882
+ static member toSysex ( mdKit : MDKit ) =
883
+ Sysex.makeMachineDrumSysexMessageWithChecksum MachineDrumSysexMessageId.Kit mdKit.ContentAsBytes
884
+
782
885
static member drumModelsAreAllEmpty ( kit : MDKit ) = kit.SelectedDrumModel = Array.create 16 ( MDMachineType.MD MDMachine.GND_ EM)
783
-
784
-
886
+ static member empty = Sysex.Empty.newKitBuffer () |> MDKit
785
887
type MDTempoMultiplier =
786
888
| One
787
889
| Two
@@ -970,7 +1072,8 @@ type GlobalSettings = {
970
1072
with
971
1073
static member ToSysex globals =
972
1074
[||]
973
- static member FromSysex ( bytes : sysex_data ) =
1075
+ static member fromSysex ( bytes : sysex_data ) =
1076
+ Sysex.validateSysexShape bytes
974
1077
let originalPosition = bytes.[ 0x09 ]
975
1078
let drumRoutingTable = bytes |> SysexBufferEdit.getDataSlice 0x0a 16 |> Array.map Output.FromByte
976
1079
let keymapStructure =
@@ -1021,7 +1124,7 @@ with
1021
1124
| StatusResponse _ -> 0x72 uy
1022
1125
static member BuildResponse ( sysex : sysex_data ) =
1023
1126
match UMX.untag_ sysex sysex.[ 6 ] with
1024
- | 0x50 uy -> Some ( GlobalSettingsResponse ( GlobalSettings.FromSysex sysex) )
1127
+ | 0x50 uy -> Some ( GlobalSettingsResponse ( GlobalSettings.fromSysex sysex) )
1025
1128
| 0x52 uy -> Some ( KitResponse ( MDKit.fromSysex sysex) )
1026
1129
| 0x67 uy -> Some ( PatternResponse ( MDPattern.fromSysex sysex) )
1027
1130
| 0x69 uy -> Some ( SongResponse ( MDSong sysex) )
@@ -1198,7 +1301,6 @@ type MachineDrum<'timestamp>(inPort: IMidiInput<'timestamp>, outPort: IMidiOutpu
1198
1301
1199
1302
member x.EventToMidiMessages ( mdEvent : MachineDrumEvent ) globals =
1200
1303
let channel = globals.MidiBaseChannel
1201
- //globals.KeymapStructure.GetTriggerNotesForBank
1202
1304
let track = mdEvent.Track
1203
1305
let note =
1204
1306
match track with
0 commit comments