1
1
module Elektron.MonoMachine
2
-
2
+ open FSharp. UMX
3
3
open System
4
4
open Midi
5
+
5
6
open Midinette.Platform
6
7
open Elektron.Platform
7
8
open Elektron.Platform .SilverMachines
@@ -19,21 +20,22 @@ type LFOShape =
19
20
match value with
20
21
| _ -> failwithf " %i not defined" value
21
22
22
-
23
23
type LFOMultiplier = Times1 | Times2 | Times4 | Times8 | Times16 | Times32 | Times64
24
24
25
25
module internal Helpers =
26
- let monoMachineHeader = [|
26
+ let monoMachineHeader =
27
+ [|
27
28
0xf0 uy
28
29
0x00 uy
29
30
0x20 uy
30
31
0x3c uy
31
32
0x03 uy
32
33
0x00 uy
33
34
|]
35
+ |> UMX.tag_ sysex_ data
34
36
35
37
let makeSysexMessage message =
36
- let sysexEnd = [| 0xf7 uy|]
38
+ let sysexEnd = [| UMX.tag _ sysex _ data 0xf7 uy|]
37
39
Array.concat [| monoMachineHeader; message; sysexEnd|]
38
40
39
41
open Helpers
58
60
| SequencerMode -> 0x10 uy
59
61
| AudioMode -> 0x20 uy
60
62
| SequencerModeMode -> 0x21 uy
61
- static member FromByte v =
62
- match v with
63
+ static member FromByte ( v : byte < _ >) =
64
+ match UMX.untag v with
63
65
| 0x01 uy -> GlobalSlot
64
66
| 0x02 uy -> KitNumber
65
67
| 0x04 uy -> PatternNumber
73
75
type Track = Track1 | Track2 | Track3 | Track4 | Track5 | Track6
74
76
with
75
77
static member FromByte b =
76
- match b with
78
+ match UMX.untag _ byte _ 7bits b with
77
79
| 0x0 uy -> Track1
78
80
| 0x1 uy -> Track2
79
81
| 0x2 uy -> Track3
@@ -173,7 +175,7 @@ type MachineParameters(bytes: byte array) =
173
175
member x.MIDI = getBytes midiBase
174
176
member x.ADSR = getBytes adsrBase
175
177
176
- type MonoMachineKit ( data : byte array ) =
178
+ type MonoMachineKit ( data : sysex_data ) =
177
179
member x.Version = data.[ 0x07 ]
178
180
member x.Revision = data.[ 0x08 ]
179
181
member x.OriginalPosition = data.[ 0x09 ]
@@ -186,17 +188,17 @@ type MonoMachineKit (data: byte array) =
186
188
|> dataToByte
187
189
//else [||]
188
190
member x.Name =
189
- x.unpacked |> getSlice 0 11 |> ASCIIEncoding.ASCII.GetString
191
+ x.unpacked |> SysexBufferEdit. getSlice 0 11 |> unbox |> ASCIIEncoding.ASCII.GetString
190
192
member x.Levels =
191
- x.unpacked |> getSlice 0xb 6
193
+ x.unpacked |> SysexBufferEdit. getSlice 0xb 6
192
194
member x.Parameters =
193
195
x.unpacked
194
- |> getSlice 0x11 ( 72 * 6 )
196
+ |> SysexBufferEdit. getSlice 0x11 ( 72 * 6 )
195
197
|> Array.chunkBySize 72
196
198
|> Array.map MachineParameters
197
199
member x.Machines =
198
200
x.unpacked
199
- |> getSlice 0x1c1 6
201
+ |> SysexBufferEdit. getSlice 0x1c1 6
200
202
|> Array.map ((&&&) 0b01111111 uy)
201
203
|> Array.map MonoMachineType.FromValue
202
204
@@ -214,57 +216,58 @@ with
214
216
| Fixed v -> v
215
217
216
218
type GlobalSettings = {
217
- midiChannelAutoTrack : byte
218
- midiChannel : byte
219
- midiChannelMultiTrig : byte
220
- midiChannelMultiMap : byte
221
- midiMachineChannels : byte array
222
- ccDestinationsPerChannel: byte array array
219
+ midiChannelAutoTrack : byte_7bits
220
+ midiChannel : byte_7bits
221
+ midiChannelMultiTrig : byte_7bits
222
+ midiChannelMultiMap : byte_7bits
223
+ midiMachineChannels : byte_7bits array
224
+ ccDestinationsPerChannel: byte_7bits array array
223
225
programChangeIn : bool
224
226
velocityCurve : VelocityCurve
225
- fixedVelocity : byte
226
- knobSpeed : byte
227
+ fixedVelocity : byte_7bits
228
+ knobSpeed : byte_7bits
227
229
baseFrequency : int
228
230
}
229
231
with
230
232
static member Default =
231
233
{
232
- midiChannelAutoTrack= 8 uy
233
- midiChannel = 0 uy
234
- midiChannelMultiTrig = 7 uy
235
- midiChannelMultiMap = 08 uy
236
- midiMachineChannels = [| 0 uy .. 05 uy|]
234
+ midiChannelAutoTrack = UMX.tag _ byte _ 7bits 8 uy
235
+ midiChannel = UMX.tag _ byte _ 7bits 0 uy
236
+ midiChannelMultiTrig = UMX.tag _ byte _ 7bits 7 uy
237
+ midiChannelMultiMap = UMX.tag _ byte _ 7bits 08 uy
238
+ midiMachineChannels = UMX.tag _ byte _ 7bits [| 0 uy .. 05 uy|]
237
239
ccDestinationsPerChannel= [||]
238
240
programChangeIn = true
239
241
velocityCurve = VelocityCurve.Linear
240
- fixedVelocity = 0 uy
241
- knobSpeed = 0 uy
242
+ fixedVelocity = UMX.tag _ byte _ 7bits 0 uy
243
+ knobSpeed = UMX.tag _ byte _ 7bits 0 uy
242
244
baseFrequency = 440
243
245
244
246
}
245
- static member FromSysex ( sysexData : byte array ) =
247
+ static member FromSysex ( sysexData : sysex_data ) =
246
248
// note: this is just plain broken on hardware side
247
249
if areMonoMachineCheckSumAndLengthValid sysexData then
248
250
let globalData =
249
251
( getMonoMachineDataSliceFromSysexMessage sysexData)
250
252
|> Seq.toArray
251
- |> Elektron.Platform.dataToByte
253
+ |> dataToByte
254
+
252
255
//if globalData.Length < 0x101 then None
253
256
//else
254
257
Some
255
258
{
256
- midiChannelAutoTrack = globalData.[ 0x00 ]
257
- midiChannel = globalData.[ 0x01 ]
258
- midiChannelMultiTrig = globalData.[ 0x02 ]
259
- midiChannelMultiMap = globalData.[ 0x03 ]
259
+ midiChannelAutoTrack = UMX.tag _ byte _ 7bits globalData.[ 0x00 ]
260
+ midiChannel = UMX.tag _ byte _ 7bits globalData.[ 0x01 ]
261
+ midiChannelMultiTrig = UMX.tag _ byte _ 7bits globalData.[ 0x02 ]
262
+ midiChannelMultiMap = UMX.tag _ byte _ 7bits globalData.[ 0x03 ]
260
263
midiMachineChannels = [||] //globalData.[0x12..0x1]
261
264
262
265
// external sync
263
266
ccDestinationsPerChannel = [||] //[|globalData.[0x18..0x1]|]
264
267
programChangeIn = true //globalData.[0xfd] = 1uy
265
268
velocityCurve = VelocityCurve.Fixed 1 uy //globalData.[0xff] |> VelocityCurve.FromByte
266
- fixedVelocity = 0 uy //globalData.[0x100]
267
- knobSpeed = 0 uy//globalData.[0x101]
269
+ fixedVelocity = UMX.tag _ byte _ 7bits 0 uy //globalData.[0x100]
270
+ knobSpeed = UMX.tag _ byte _ 7bits 0 uy//globalData.[0x101]
268
271
baseFrequency = 0 //globalData.[0x104..] |> Elektron.fourBytesToBigEndianInt
269
272
}
270
273
else
@@ -274,26 +277,26 @@ with
274
277
type MonoMachineSysexResponse =
275
278
| GlobalSettings of GlobalSettings
276
279
| Kit of MonoMachineKit
277
- | Pattern of byte array
278
- | Song of byte array
279
- | StatusResponse of statusType : MonoMachineStatusType * value : byte
280
+ | Pattern of sysex_data
281
+ | Song of sysex_data
282
+ | StatusResponse of statusType : MonoMachineStatusType * value : byte_7bits
280
283
with
281
- static member BuildResponse ( bytes : byte array ) =
282
- match bytes.[ 6 ] with
283
- | 72 uy -> StatusResponse( MonoMachineStatusType.FromByte bytes.[ 7 ], bytes.[ 8 ])
284
+ static member BuildResponse ( bytes : sysex_data ) =
285
+ match UMX.untag _ sysex bytes.[ 6 ] with
286
+ | 72 uy -> StatusResponse( MonoMachineStatusType.FromByte bytes.[ 7 ], UMX.to _ byte _ 7bits bytes.[ 8 ])
284
287
| 0x50 uy -> GlobalSettings ( GlobalSettings.FromSysex( bytes) .Value)
285
288
| 0x52 uy -> Kit ( MonoMachineKit( bytes))
286
289
| 0x67 uy -> Pattern bytes
287
290
| _ -> failwithf " h:%x response not understood" bytes.[ 6 ]
288
291
289
292
290
293
type MonoMachineSysexRequests =
291
- | DumpGlobalSettings of globalSettingsIndex : byte
292
- | DumpKit of kit : byte
293
- | DumpPattern of pattern : byte
294
- | DumpSong of song : byte
294
+ | DumpGlobalSettings of globalSettingsIndex : byte_7bits
295
+ | DumpKit of kit : byte_7bits
296
+ | DumpPattern of pattern : byte_7bits
297
+ | DumpSong of song : byte_7bits
295
298
| QueryStatus of statusType : MonoMachineStatusType
296
- | AssignMachine of track : byte * machine : MonoMachineType * parametersMode : AssignMachineParameterMode
299
+ | AssignMachine of track : byte_7bits * machine : MonoMachineType * parametersMode : AssignMachineParameterMode
297
300
with
298
301
member x.MessageId =
299
302
match x with
@@ -306,13 +309,14 @@ with
306
309
member x.Sysex =
307
310
let data =
308
311
match x with
309
- | DumpGlobalSettings id -> id |> Array.singleton
310
- | DumpKit kit -> kit |> Array.singleton
311
- | DumpPattern pattern -> pattern |> Array.singleton
312
- | DumpSong song -> song |> Array.singleton
312
+ | DumpGlobalSettings id -> id |> UMX.untag |> Array.singleton
313
+ | DumpKit kit -> kit |> UMX.untag |> Array.singleton
314
+ | DumpPattern pattern -> pattern |> UMX.untag |> Array.singleton
315
+ | DumpSong song -> song |> UMX.untag |> Array.singleton
313
316
| QueryStatus status -> status.Id |> Array.singleton
314
- | AssignMachine ( t, m, p) -> [| t; m.Value; p.Value|]
315
- makeSysexMessage ( Array.concat ([| x.MessageId |> Array.singleton; data|]))
317
+ | AssignMachine ( t, m, p) -> [| UMX.untag t; UMX.untag m.Value; UMX.untag p.Value|]
318
+ let data = UMX.tag_ sysex_ data data
319
+ makeSysexMessage ( Array.concat ([| x.MessageId |> UMX.tag_ sysex_ data |> Array.singleton; data|]))
316
320
member x.ResponseMessageId =
317
321
match x with
318
322
| DumpGlobalSettings _
327
331
| DumpKit _ -> Some <| Kit( MonoMachineKit data)
328
332
| DumpPattern _ -> Some <| Pattern data
329
333
| DumpSong _ -> Some <| Song data
330
- | QueryStatus _ -> Some <| StatusResponse(( MonoMachineStatusType.FromByte data.[ monoMachineHeader.Length + 1 ]), data.[ monoMachineHeader.Length + 2 ])
334
+ | QueryStatus _ -> Some <| StatusResponse(( MonoMachineStatusType.FromByte data.[ monoMachineHeader.Length + 1 ]), UMX.to _ byte _ 7bits data.[ monoMachineHeader.Length + 2 ])
331
335
| AssignMachine(_) -> failwithf " not implemented"
332
336
//| _ -> None
333
337
@@ -347,8 +351,8 @@ type MonoMachine<'timestamp>(inPort: IMidiInput<'timestamp>, outPort: IMidiOutpu
347
351
maxMessage
348
352
timeout
349
353
( fun sysex ->
350
- sysex.[ 0 .. 5 ] = Helpers. monoMachineHeader
351
- && Some sysex.[ 6 ] = request.ResponseMessageId
354
+ sysex.[ 0 .. 5 ] = monoMachineHeader
355
+ && Some ( UMX.untag _ sysex sysex.[ 6 ]) = request.ResponseMessageId
352
356
)
353
357
request.BuildResponse
354
358
inPort
@@ -647,7 +651,7 @@ type MonoMachineEvent =
647
651
| Unknown of MidiMessage
648
652
| UnknownNRPN of Midi.Nrpn.NRPNEvent
649
653
| MonoMachineSysex of MonoMachineSysexResponse
650
- | Sysex of byte array
654
+ | Sysex of sysex_data
651
655
| KitChanged of byte
652
656
| SequencerStarted
653
657
| SequencerStopped
@@ -706,12 +710,12 @@ type MonoMachineEventListener<'timestamp>
706
710
let settings = GlobalSettings.Default //settings |> Option.defaultValue
707
711
let message = midiEvent.Message
708
712
let messageChannel = message.Channel.Value
709
- let midiChannelIsTrack = messageChannel >= settings.midiChannel && messageChannel < ( settings.midiChannel + 6 uy)
713
+ let midiChannelIsTrack = messageChannel >= settings.midiChannel && messageChannel < ( settings.midiChannel + ( UMX.tag _ byte _ 7bits 6 uy) )
710
714
if midiChannelIsTrack then
711
- let track = Track.FromByte ( byte ( messageChannel - settings.midiChannel) )
715
+ let track = Track.FromByte ( messageChannel - settings.midiChannel)
712
716
match message with
713
- | NoteOn (_, note, velocity) -> TrackTrigger( track, note, velocity)
714
- | NoteOff (_, note, velocity) -> TrackRelease( track, note, velocity)
717
+ | NoteOn (_, note, velocity) -> TrackTrigger( track, UMX.tag note, velocity)
718
+ | NoteOff (_, note, velocity) -> TrackRelease( track, UMX.tag note, velocity)
715
719
| ProgramChange { program = program} ->
716
720
let locator = PatternLocator.FromByte program
717
721
PatternSelected( locator)
0 commit comments