@@ -12,13 +12,13 @@ open Midinette.Sysex
1212
1313type NonZeroIndexedArraySegment < 't >( baseLogicalAddress : int , segment : ArraySegment < 't >) =
1414 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
1616 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
1818 address
1919 let checkAddressAndLength address length =
2020 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
2222 address
2323 member x.LogicalOffset = baseLogicalAddress
2424 member x.Get address =
@@ -29,7 +29,7 @@ type NonZeroIndexedArraySegment<'t>(baseLogicalAddress: int, segment: ArraySegme
2929 let address = checkAddress address
3030 segment.Array.[ segment.Offset + address] <- value
3131
32- member x.Array = segment.Array.[ segment.Offset .. ( segment.Count - 1 )]
32+ member x.Array = segment.Array.[ segment.Offset .. ( segment.Offset + ( segment. Count - 1 ) )]
3333 member x.GetSlice address length =
3434 let address = checkAddressAndLength address length
3535 let slice = segment.Array.[ segment.Offset + address .. ( segment.Offset + address + length - 1 )]
@@ -89,7 +89,7 @@ module Sysex =
8989 let [<Literal>] kit = 0x4D1
9090 let [<Literal>] patternShort = 0xacd
9191 let [<Literal>] patternLong = 0x1522
92-
92+ let [<Literal>] globalsSettings = 0xc5
9393 module Offsets =
9494 let [<Literal>] messageId = 0x6
9595 module Kit =
@@ -100,6 +100,8 @@ module Sysex =
100100 let [<Literal>] delay = 0x48f
101101 let [<Literal>] equalizer = 0x497
102102 let [<Literal>] compressor = 0x49f
103+ let [<Literal>] checksum = 0x4cc
104+ let [<Literal>] messageLength = 0x4ce
103105 module Pattern =
104106 let [<Literal>] pattern = 0x9
105107 (* let [<Literal>] trigPattern = 0xa
@@ -109,8 +111,39 @@ module Sysex =
109111 let [<Literal>] patternLength = 0xb2
110112 let [<Literal>] multiplier = 0xb3
111113 *)
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
112131
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+
114147 let validateSysexShape ( sysex : sysex_data ) =
115148 if not ( areMachineDrumCheckSumAndLengthValid sysex) then
116149 failwithf " invalid check sum"
@@ -124,6 +157,9 @@ module Sysex =
124157 match sysex.Length with
125158 | Sizes.patternShort | Sizes.patternLong -> ()
126159 | _ -> 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
127163 | otherwise ->
128164 failwithf " non checked message id %A " otherwise
129165
@@ -205,6 +241,8 @@ type MasterEffect =
205241with
206242 static member asByte = function | Delay -> 0x5d uy | Reverb -> 0x5e uy | Equalizer -> 0x5f uy | Compressor -> 0x60 uy
207243
244+
245+
208246type MDMachine =
209247| GND_ EM = 00 uy | GND_ SN = 01 uy | GND_ NS = 02 uy | GND_ IM = 03 uy
210248| 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 =
245283| RAM_ P3 = 39 uy
246284| RAM_ P4 = 40 uy
247285
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+
248299type MDMachineType =
249300| MD of MDMachine
250301| 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+
251349 member x.HasPitch =
252350 match x with
253351 | MDUW ( MDUWMachine.RAM_ R1| MDUWMachine.RAM_ R2| MDUWMachine.RAM_ R3| MDUWMachine.RAM_ R4) -> false
@@ -292,8 +390,11 @@ with
292390 FilterBaseFrequency ; FilterWidth ; FilterQ ; SampleRateReduction
293391 Distortion ; Volume ; Pan ; DelaySend
294392 ReverbSend ; LFOSpeed ; LFOAmount ; LFOShapeMix
295-
296393 |]
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+
297398 static member fromCCOffset offset =
298399 match UMX.untag_ byte_ 7bits offset with
299400 | 00 uy -> MachineParameter1 | 01 uy -> MachineParameter2 | 02 uy -> MachineParameter3 | 03 uy -> MachineParameter4
@@ -700,7 +801,6 @@ type MDKit private (bytes: NonZeroIndexedArraySegment<byte_7bits>) =
700801 let dataSlice = bytes.GetSlice address length
701802 dataSlice
702803 |> dataToByte
703-
704804 member x.Position = bytes.Get Sysex.Offsets.Kit.kit
705805 member x.Name
706806 with get () = bytes.GetSlice 0x0a 16 |> unbox |> ASCIIEncoding.Default.GetString
@@ -779,9 +879,11 @@ type MDKit private (bytes: NonZeroIndexedArraySegment<byte_7bits>) =
779879 let segment = NonZeroIndexedArraySegment( Sysex.Offsets.Kit.kit, segment)
780880 MDKit segment
781881
882+ static member toSysex ( mdKit : MDKit ) =
883+ Sysex.makeMachineDrumSysexMessageWithChecksum MachineDrumSysexMessageId.Kit mdKit.ContentAsBytes
884+
782885 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
785887type MDTempoMultiplier =
786888| One
787889| Two
@@ -970,7 +1072,8 @@ type GlobalSettings = {
9701072with
9711073 static member ToSysex globals =
9721074 [||]
973- static member FromSysex ( bytes : sysex_data ) =
1075+ static member fromSysex ( bytes : sysex_data ) =
1076+ Sysex.validateSysexShape bytes
9741077 let originalPosition = bytes.[ 0x09 ]
9751078 let drumRoutingTable = bytes |> SysexBufferEdit.getDataSlice 0x0a 16 |> Array.map Output.FromByte
9761079 let keymapStructure =
@@ -1021,7 +1124,7 @@ with
10211124 | StatusResponse _ -> 0x72 uy
10221125 static member BuildResponse ( sysex : sysex_data ) =
10231126 match UMX.untag_ sysex sysex.[ 6 ] with
1024- | 0x50 uy -> Some ( GlobalSettingsResponse ( GlobalSettings.FromSysex sysex) )
1127+ | 0x50 uy -> Some ( GlobalSettingsResponse ( GlobalSettings.fromSysex sysex) )
10251128 | 0x52 uy -> Some ( KitResponse ( MDKit.fromSysex sysex) )
10261129 | 0x67 uy -> Some ( PatternResponse ( MDPattern.fromSysex sysex) )
10271130 | 0x69 uy -> Some ( SongResponse ( MDSong sysex) )
@@ -1198,7 +1301,6 @@ type MachineDrum<'timestamp>(inPort: IMidiInput<'timestamp>, outPort: IMidiOutpu
11981301
11991302 member x.EventToMidiMessages ( mdEvent : MachineDrumEvent ) globals =
12001303 let channel = globals.MidiBaseChannel
1201- //globals.KeymapStructure.GetTriggerNotesForBank
12021304 let track = mdEvent.Track
12031305 let note =
12041306 match track with
0 commit comments