Skip to content

Commit 674c0eb

Browse files
a bit of Midi Tuning System implementation
1 parent d0e9fd2 commit 674c0eb

File tree

2 files changed

+97
-2
lines changed

2 files changed

+97
-2
lines changed

src/Midinette/Midi.Tuning.fs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
module Midi.Tuning
2+
open Midi
3+
4+
type MessageId =
5+
| DumpRequestId = 0uy
6+
| DumpResponseId = 1uy
7+
| SingleNoteTuningChangeId = 2uy
8+
9+
let makeSysex deviceId (messageId: MessageId) data =
10+
[|
11+
[|
12+
0xf0uy
13+
0x7euy
14+
deviceId
15+
0x08uy
16+
byte messageId
17+
|]
18+
data
19+
[|
20+
0xf7uy
21+
|]
22+
|]
23+
|> Array.concat
24+
25+
type NoteTuning =
26+
{
27+
semiTone: byte
28+
cents : decimal
29+
}
30+
31+
type BulkTuningDumpResponse =
32+
{
33+
name : string
34+
programNumber: byte
35+
tunings : NoteTuning array
36+
}
37+
38+
type TuningMessage =
39+
| BulkTuningDumpRequest of tuningProgramNumber: byte
40+
| BulkTuningDump of BulkTuningDumpResponse
41+
| SingleNoteTuningChange of noteIndexAndTunings: (byte * NoteTuning) array
42+
| TuningProgramSelect of program: byte * channel: byte // + do RPNs inc/dec
43+
with
44+
member x.IsRealTime =
45+
match x with
46+
| TuningProgramSelect _ | SingleNoteTuningChange _ -> true
47+
| BulkTuningDumpRequest _
48+
| BulkTuningDump _
49+
-> false
50+
51+
member x.MessageId =
52+
match x with
53+
| BulkTuningDumpRequest _ -> Some MessageId.DumpRequestId
54+
| BulkTuningDump _ -> Some MessageId.DumpResponseId
55+
| SingleNoteTuningChange _ -> Some MessageId.SingleNoteTuningChangeId
56+
| TuningProgramSelect _ -> None
57+
58+
member x.SysexData =
59+
match x with
60+
| BulkTuningDumpRequest programNumber -> Some [|programNumber|]
61+
| BulkTuningDump _ -> Some [||]
62+
| SingleNoteTuningChange tunings ->
63+
Some(
64+
[|
65+
for (noteIndex, tuning) in tunings do
66+
let centIncrement = 0.0061m
67+
let centsAsShort = int16 (tuning.cents / centIncrement)
68+
let centFirstByte = byte ((centsAsShort >>> 7) &&& 0b01111111s)
69+
let centSecondByte = byte (centsAsShort &&& 0b01111111s)
70+
yield! [|noteIndex; tuning.semiTone; centFirstByte; centSecondByte|]
71+
|]
72+
)
73+
| TuningProgramSelect _ -> None
74+
75+
76+
77+
member x.Send (deviceId: byte, midiOutput: IMidiOutput<_>, nowTimestamp) =
78+
let sysex, messageId = x.SysexData, x.MessageId
79+
match sysex, messageId with
80+
| Some (data), Some (messageId) ->
81+
midiOutput.WriteSysex (nowTimestamp()) (makeSysex deviceId messageId data)
82+
| _ -> ()
83+
84+
match x with
85+
| BulkTuningDumpRequest _ | BulkTuningDump _ | SingleNoteTuningChange _ -> ()
86+
| TuningProgramSelect _ ->
87+
//let rpn = 3
88+
//let messages = Midi.Nrpn.makeNRPN2 1uy 1uy 1uy
89+
//midiOutput.WriteMessages (nowTimestamp()) messages
90+
()
91+
(*
92+
type NoteTuningChange =
93+
| NoFrequency
94+
| Hertz of hertz: decimal
95+
| NoteAndCents of NoteTuning
96+
*)

src/Midinette/Midinette.fsproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
<?xml version="1.0" encoding="utf-8"?>
21
<Project Sdk="Microsoft.NET.Sdk">
32
<PropertyGroup>
43
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
5-
<OutputPath>..\..\build\$(Configuration)\$(Platform)</OutputPath>
64
</PropertyGroup>
75
<ItemGroup>
86
<Compile Include="Midi.fs" />
97
<Compile Include="Midi.MessageMatching.fs" />
108
<Compile Include="Midi.Nrpn.fs" />
119
<Compile Include="Midi.Registers.fs" />
10+
<Compile Include="Midi.Tuning.fs" />
1211
<Compile Include="Midi.Sysex.fs" />
1312
</ItemGroup>
1413
<Import Project="..\..\.paket\Paket.Restore.targets" />

0 commit comments

Comments
 (0)