midi-communications-windows 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/notify-plugin.yml +17 -0
- data/.yardoc/checksums +1 -1
- data/.yardoc/objects/root.dat +0 -0
- data/.yardopts +0 -2
- data/README.md +5 -8
- data/doc/MIDICommunicationsWindows/API/MIDIHdr.html +1 -1
- data/doc/MIDICommunicationsWindows/API/MIDIInCaps.html +1 -1
- data/doc/MIDICommunicationsWindows/API/MIDIOutCaps.html +1 -1
- data/doc/MIDICommunicationsWindows/API/MSG.html +1 -1
- data/doc/MIDICommunicationsWindows/API.html +1 -1
- data/doc/MIDICommunicationsWindows/Device/ClassMethods.html +1 -1
- data/doc/MIDICommunicationsWindows/Device/InstanceMethods.html +1 -1
- data/doc/MIDICommunicationsWindows/Device.html +1 -1
- data/doc/MIDICommunicationsWindows/Error.html +1 -1
- data/doc/MIDICommunicationsWindows/Input.html +1 -1
- data/doc/MIDICommunicationsWindows/Message.html +1 -1
- data/doc/MIDICommunicationsWindows/Output.html +1 -1
- data/doc/MIDICommunicationsWindows/TypeConversion.html +1 -1
- data/doc/MIDICommunicationsWindows.html +2 -2
- data/doc/_index.html +1 -4
- data/doc/file.README.html +5 -8
- data/doc/file_list.html +0 -5
- data/doc/index.html +5 -8
- data/doc/top-level-namespace.html +1 -1
- data/lib/midi-communications-windows/version.rb +1 -1
- data/midi-communications-windows.gemspec +5 -2
- metadata +3 -4
- data/doc/file.testing-on-windows.html +0 -253
- data/docs/testing-on-windows.md +0 -222
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8fc6b5ad53dfa328b84bf63dcdb0660a2c5d6e00b18faec4eb5549a8f4baa116
|
|
4
|
+
data.tar.gz: 664db0add4987b5f180481b26e6d85e3ea66b7b645b59bda5a930bb6fe59eb6d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2bfafc2e6f554e568b37a2e53d4261734d858da411d42a8a04a0d3cc3ccbb7bb5fe7d62b7e243c9ca62a0a3804cbf451f02372c86b4b9fb88899a1c872c0e52b
|
|
7
|
+
data.tar.gz: 1718a6d1111ab6ff8e4cdbb79d6bc2c3de18aed3478cd5d997283e8c437657d4b3c91670edebaddd661ff8d4b08b7d12ac4541cd3e38284c65811a219eab90ff
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Notify Plugin Rebuild
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
notify:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Trigger nota-plugin rebuild
|
|
12
|
+
uses: peter-evans/repository-dispatch@v3
|
|
13
|
+
with:
|
|
14
|
+
token: ${{ secrets.PLUGIN_REBUILD_PAT }}
|
|
15
|
+
repository: javier-sy/nota-plugin
|
|
16
|
+
event-type: source-updated
|
|
17
|
+
client-payload: '{"repo": "${{ github.repository }}", "sha": "${{ github.sha }}"}'
|
data/.yardoc/checksums
CHANGED
|
@@ -4,5 +4,5 @@ lib/midi-communications-windows/input.rb 36e58891d1c604dd4b2f333382a4010660d4786
|
|
|
4
4
|
lib/midi-communications-windows/device.rb 9f151193d144c298c064592ee21d44111f968d01
|
|
5
5
|
lib/midi-communications-windows/output.rb 3069d46892268c529d999363bd05fac891e5f4fc
|
|
6
6
|
lib/midi-communications-windows/message.rb 2390946620b244ec12a6b373e003304ef9c29e4d
|
|
7
|
-
lib/midi-communications-windows/version.rb
|
|
7
|
+
lib/midi-communications-windows/version.rb 4804d6731ca80a4f6f679dd5585ed1b2c7517513
|
|
8
8
|
lib/midi-communications-windows/type_conversion.rb dae7dc5109d955f4693920fa173f5c143dcb7bf1
|
data/.yardoc/objects/root.dat
CHANGED
|
Binary file
|
data/.yardopts
CHANGED
data/README.md
CHANGED
|
@@ -30,14 +30,11 @@ enough to make `Output`'s System Exclusive wait mean something, and a port
|
|
|
30
30
|
appearing or disappearing while the program runs.
|
|
31
31
|
|
|
32
32
|
The version stays in the 0.0.x series because that was a virtual machine with no
|
|
33
|
-
MIDI hardware in it, not because anything is known to be missing.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
That document is also how to rebuild the test environment: it is the procedure
|
|
39
|
-
these measurements were taken with, including how to make two ports collide in
|
|
40
|
-
WinMM's 31 characters of name.
|
|
33
|
+
MIDI hardware in it, not because anything is known to be missing.
|
|
34
|
+
|
|
35
|
+
How those measurements were taken, and what a session with real hardware still
|
|
36
|
+
has to close, is written down in
|
|
37
|
+
[`dev/testing-on-windows.md`](dev/testing-on-windows.md).
|
|
41
38
|
|
|
42
39
|
### One thing worth knowing before you use it
|
|
43
40
|
|
|
@@ -134,7 +134,7 @@ WinMM there expects.</p>
|
|
|
134
134
|
</div>
|
|
135
135
|
|
|
136
136
|
<div id="footer">
|
|
137
|
-
Generated on
|
|
137
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
138
138
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
139
139
|
0.9.45 (ruby-3.4.7).
|
|
140
140
|
</div>
|
|
@@ -132,7 +132,7 @@ declared as <code>:uint16</code> so that reading it cannot split a character in
|
|
|
132
132
|
</div>
|
|
133
133
|
|
|
134
134
|
<div id="footer">
|
|
135
|
-
Generated on
|
|
135
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
136
136
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
137
137
|
0.9.45 (ruby-3.4.7).
|
|
138
138
|
</div>
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
</div>
|
|
131
131
|
|
|
132
132
|
<div id="footer">
|
|
133
|
-
Generated on
|
|
133
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
134
134
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
135
135
|
0.9.45 (ruby-3.4.7).
|
|
136
136
|
</div>
|
|
@@ -133,7 +133,7 @@ is 48 bytes on 64-bit Windows, which is what the queue functions expect.</p>
|
|
|
133
133
|
</div>
|
|
134
134
|
|
|
135
135
|
<div id="footer">
|
|
136
|
-
Generated on
|
|
136
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
137
137
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
138
138
|
0.9.45 (ruby-3.4.7).
|
|
139
139
|
</div>
|
|
@@ -971,7 +971,7 @@ than showing a replacement character.</p>
|
|
|
971
971
|
</div>
|
|
972
972
|
|
|
973
973
|
<div id="footer">
|
|
974
|
-
Generated on
|
|
974
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
975
975
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
976
976
|
0.9.45 (ruby-3.4.7).
|
|
977
977
|
</div>
|
|
@@ -355,7 +355,7 @@ back as the same object as before; see <span class='object_link'><a href="../Dev
|
|
|
355
355
|
</div>
|
|
356
356
|
|
|
357
357
|
<div id="footer">
|
|
358
|
-
Generated on
|
|
358
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
359
359
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
360
360
|
0.9.45 (ruby-3.4.7).
|
|
361
361
|
</div>
|
|
@@ -1086,7 +1086,7 @@ may already hold.</p>
|
|
|
1086
1086
|
</div>
|
|
1087
1087
|
|
|
1088
1088
|
<div id="footer">
|
|
1089
|
-
Generated on
|
|
1089
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
1090
1090
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
1091
1091
|
0.9.45 (ruby-3.4.7).
|
|
1092
1092
|
</div>
|
|
@@ -978,7 +978,7 @@ the reserved id <code>-1</code> and does not count among its devices.</p>
|
|
|
978
978
|
</div>
|
|
979
979
|
|
|
980
980
|
<div id="footer">
|
|
981
|
-
Generated on
|
|
981
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
982
982
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
983
983
|
0.9.45 (ruby-3.4.7).
|
|
984
984
|
</div>
|
|
@@ -428,7 +428,7 @@ for instance</p></div>
|
|
|
428
428
|
</div>
|
|
429
429
|
|
|
430
430
|
<div id="footer">
|
|
431
|
-
Generated on
|
|
431
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
432
432
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
433
433
|
0.9.45 (ruby-3.4.7).
|
|
434
434
|
</div>
|
|
@@ -1544,7 +1544,7 @@ may already hold.</p>
|
|
|
1544
1544
|
</div>
|
|
1545
1545
|
|
|
1546
1546
|
<div id="footer">
|
|
1547
|
-
Generated on
|
|
1547
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
1548
1548
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
1549
1549
|
0.9.45 (ruby-3.4.7).
|
|
1550
1550
|
</div>
|
|
@@ -690,7 +690,7 @@ byte calls for</p></div>
|
|
|
690
690
|
</div>
|
|
691
691
|
|
|
692
692
|
<div id="footer">
|
|
693
|
-
Generated on
|
|
693
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
694
694
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
695
695
|
0.9.45 (ruby-3.4.7).
|
|
696
696
|
</div>
|
|
@@ -1687,7 +1687,7 @@ else, and this is where the two part company.</p>
|
|
|
1687
1687
|
</div>
|
|
1688
1688
|
|
|
1689
1689
|
<div id="footer">
|
|
1690
|
-
Generated on
|
|
1690
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
1691
1691
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
1692
1692
|
0.9.45 (ruby-3.4.7).
|
|
1693
1693
|
</div>
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
</div>
|
|
360
360
|
|
|
361
361
|
<div id="footer">
|
|
362
|
-
Generated on
|
|
362
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
363
363
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
364
364
|
0.9.45 (ruby-3.4.7).
|
|
365
365
|
</div>
|
|
@@ -184,7 +184,7 @@ RubyGems is where installations break; there is nothing here to break.</p>
|
|
|
184
184
|
|
|
185
185
|
</div>
|
|
186
186
|
</dt>
|
|
187
|
-
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>0.0.
|
|
187
|
+
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>0.0.4</span><span class='tstring_end'>'</span></span><span class='period'>.</span><span class='id identifier rubyid_freeze'>freeze</span></pre></dd>
|
|
188
188
|
|
|
189
189
|
</dl>
|
|
190
190
|
|
|
@@ -200,7 +200,7 @@ RubyGems is where installations break; there is nothing here to break.</p>
|
|
|
200
200
|
</div>
|
|
201
201
|
|
|
202
202
|
<div id="footer">
|
|
203
|
-
Generated on
|
|
203
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
204
204
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
205
205
|
0.9.45 (ruby-3.4.7).
|
|
206
206
|
</div>
|
data/doc/_index.html
CHANGED
|
@@ -65,9 +65,6 @@
|
|
|
65
65
|
<li class="r1"><a href="index.html" title="README">README</a></li>
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
<li class="r2"><a href="file.testing-on-windows.html" title="testing-on-windows">testing-on-windows</a></li>
|
|
69
|
-
|
|
70
|
-
|
|
71
68
|
</ul>
|
|
72
69
|
|
|
73
70
|
<div class="clear"></div>
|
|
@@ -252,7 +249,7 @@
|
|
|
252
249
|
</div>
|
|
253
250
|
|
|
254
251
|
<div id="footer">
|
|
255
|
-
Generated on
|
|
252
|
+
Generated on Mon Sep 7 00:14:17 2026 by
|
|
256
253
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
257
254
|
0.9.45 (ruby-3.4.7).
|
|
258
255
|
</div>
|
data/doc/file.README.html
CHANGED
|
@@ -112,13 +112,10 @@ not been exercised is anything needing real hardware — a physical interface sl
|
|
|
112
112
|
enough to make <code>Output</code>'s System Exclusive wait mean something, and a port
|
|
113
113
|
appearing or disappearing while the program runs.</p>
|
|
114
114
|
<p>The version stays in the 0.0.x series because that was a virtual machine with no
|
|
115
|
-
MIDI hardware in it, not because anything is known to be missing
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<p>That document is also how to rebuild the test environment: it is the procedure
|
|
120
|
-
these measurements were taken with, including how to make two ports collide in
|
|
121
|
-
WinMM's 31 characters of name.</p>
|
|
115
|
+
MIDI hardware in it, not because anything is known to be missing.</p>
|
|
116
|
+
<p>How those measurements were taken, and what a session with real hardware still
|
|
117
|
+
has to close, is written down in
|
|
118
|
+
<a href="dev/testing-on-windows.md"><code>dev/testing-on-windows.md</code></a>.</p>
|
|
122
119
|
<h3 id="One_thing_worth_knowing_before_you_use_it">One thing worth knowing before you use it</h3>
|
|
123
120
|
<p><code>Input#gets</code> <strong>waits</strong>. It does not return an empty array when nothing has
|
|
124
121
|
arrived; it blocks until something does, and then returns everything that
|
|
@@ -230,7 +227,7 @@ Both are addressed here by construction; see the notes in
|
|
|
230
227
|
<p><a href="https://github.com/javier-sy/midi-communications-windows">MIDI Communications Windows Layer</a> Copyright (c) 2026 <a href="https://yeste.studio">Javier Sánchez Yeste</a>, licensed under LGPL 3.0 License</p></div></div>
|
|
231
228
|
|
|
232
229
|
<div id="footer">
|
|
233
|
-
Generated on
|
|
230
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
234
231
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
235
232
|
0.9.45 (ruby-3.4.7).
|
|
236
233
|
</div>
|
data/doc/file_list.html
CHANGED
data/doc/index.html
CHANGED
|
@@ -112,13 +112,10 @@ not been exercised is anything needing real hardware — a physical interface sl
|
|
|
112
112
|
enough to make <code>Output</code>'s System Exclusive wait mean something, and a port
|
|
113
113
|
appearing or disappearing while the program runs.</p>
|
|
114
114
|
<p>The version stays in the 0.0.x series because that was a virtual machine with no
|
|
115
|
-
MIDI hardware in it, not because anything is known to be missing
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<p>That document is also how to rebuild the test environment: it is the procedure
|
|
120
|
-
these measurements were taken with, including how to make two ports collide in
|
|
121
|
-
WinMM's 31 characters of name.</p>
|
|
115
|
+
MIDI hardware in it, not because anything is known to be missing.</p>
|
|
116
|
+
<p>How those measurements were taken, and what a session with real hardware still
|
|
117
|
+
has to close, is written down in
|
|
118
|
+
<a href="dev/testing-on-windows.md"><code>dev/testing-on-windows.md</code></a>.</p>
|
|
122
119
|
<h3 id="One_thing_worth_knowing_before_you_use_it">One thing worth knowing before you use it</h3>
|
|
123
120
|
<p><code>Input#gets</code> <strong>waits</strong>. It does not return an empty array when nothing has
|
|
124
121
|
arrived; it blocks until something does, and then returns everything that
|
|
@@ -230,7 +227,7 @@ Both are addressed here by construction; see the notes in
|
|
|
230
227
|
<p><a href="https://github.com/javier-sy/midi-communications-windows">MIDI Communications Windows Layer</a> Copyright (c) 2026 <a href="https://yeste.studio">Javier Sánchez Yeste</a>, licensed under LGPL 3.0 License</p></div></div>
|
|
231
228
|
|
|
232
229
|
<div id="footer">
|
|
233
|
-
Generated on
|
|
230
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
234
231
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
235
232
|
0.9.45 (ruby-3.4.7).
|
|
236
233
|
</div>
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
</div>
|
|
103
103
|
|
|
104
104
|
<div id="footer">
|
|
105
|
-
Generated on
|
|
105
|
+
Generated on Mon Sep 7 00:14:18 2026 by
|
|
106
106
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
107
107
|
0.9.45 (ruby-3.4.7).
|
|
108
108
|
</div>
|
|
@@ -3,12 +3,15 @@ require_relative 'lib/midi-communications-windows/version'
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = 'midi-communications-windows'
|
|
5
5
|
s.version = MIDICommunicationsWindows::VERSION
|
|
6
|
-
s.date = '2026-09-
|
|
6
|
+
s.date = '2026-09-07'
|
|
7
7
|
s.summary = 'Realtime MIDI IO with Ruby for Windows'
|
|
8
8
|
s.description = 'Access the Windows Multimedia (WinMM) MIDI API with Ruby.'
|
|
9
9
|
s.authors = ['Javier Sánchez Yeste']
|
|
10
10
|
s.email = ['javier.sy@gmail.com']
|
|
11
|
-
|
|
11
|
+
# dev/ is how the library was measured, not how it is used: it describes
|
|
12
|
+
# installing preview software on a machine with no MIDI hardware, and has no
|
|
13
|
+
# business in every user's gem directory.
|
|
14
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|dev)/}) }
|
|
12
15
|
s.homepage = 'https://github.com/javier-sy/midi-communications-windows'
|
|
13
16
|
s.license = 'LGPL-3.0-or-later'
|
|
14
17
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: midi-communications-windows
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Javier Sánchez Yeste
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-09-
|
|
10
|
+
date: 2026-09-07 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ffi
|
|
@@ -138,6 +138,7 @@ executables: []
|
|
|
138
138
|
extensions: []
|
|
139
139
|
extra_rdoc_files: []
|
|
140
140
|
files:
|
|
141
|
+
- ".github/workflows/notify-plugin.yml"
|
|
141
142
|
- ".gitignore"
|
|
142
143
|
- ".version"
|
|
143
144
|
- ".yardoc/checksums"
|
|
@@ -170,7 +171,6 @@ files:
|
|
|
170
171
|
- doc/css/full_list.css
|
|
171
172
|
- doc/css/style.css
|
|
172
173
|
- doc/file.README.html
|
|
173
|
-
- doc/file.testing-on-windows.html
|
|
174
174
|
- doc/file_list.html
|
|
175
175
|
- doc/frames.html
|
|
176
176
|
- doc/index.html
|
|
@@ -179,7 +179,6 @@ files:
|
|
|
179
179
|
- doc/js/jquery.js
|
|
180
180
|
- doc/method_list.html
|
|
181
181
|
- doc/top-level-namespace.html
|
|
182
|
-
- docs/testing-on-windows.md
|
|
183
182
|
- examples/input.rb
|
|
184
183
|
- examples/list_ports.rb
|
|
185
184
|
- examples/output.rb
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>
|
|
7
|
-
File: testing-on-windows
|
|
8
|
-
|
|
9
|
-
— MIDI Communications Windows API
|
|
10
|
-
|
|
11
|
-
</title>
|
|
12
|
-
|
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css">
|
|
14
|
-
|
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css">
|
|
16
|
-
|
|
17
|
-
<script type="text/javascript">
|
|
18
|
-
pathId = "testing-on-windows";
|
|
19
|
-
relpath = '';
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
|
24
|
-
|
|
25
|
-
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</head>
|
|
29
|
-
<body>
|
|
30
|
-
<div id="main_progress" aria-hidden="true"></div>
|
|
31
|
-
|
|
32
|
-
<div class="nav_wrap">
|
|
33
|
-
<iframe id="nav" src="file_list.html?1"></iframe>
|
|
34
|
-
<div id="resizer"></div>
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
<div id="main" tabindex="-1">
|
|
38
|
-
<div id="header">
|
|
39
|
-
<div id="menu">
|
|
40
|
-
|
|
41
|
-
<a href="_index.html">Index</a> »
|
|
42
|
-
<span class="title">File: testing-on-windows</span>
|
|
43
|
-
|
|
44
|
-
</div>
|
|
45
|
-
|
|
46
|
-
<div id="search">
|
|
47
|
-
|
|
48
|
-
<a class="full_list_link" id="class_list_link"
|
|
49
|
-
href="class_list.html">
|
|
50
|
-
|
|
51
|
-
<svg width="24" height="24">
|
|
52
|
-
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
|
53
|
-
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
|
54
|
-
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
|
55
|
-
</svg>
|
|
56
|
-
</a>
|
|
57
|
-
|
|
58
|
-
</div>
|
|
59
|
-
<div class="clear"></div>
|
|
60
|
-
</div>
|
|
61
|
-
|
|
62
|
-
<div id="content"><div id='filecontents'><h1 id="Testing_this_gem_on_Windows_without_MIDI_hardware">Testing this gem on Windows without MIDI hardware</h1>
|
|
63
|
-
<p><em>Written 2026-09-06. Section 1 is the part with a shelf life: it describes
|
|
64
|
-
software that was in preview at the time, which Microsoft's release notes said
|
|
65
|
-
was headed for Windows 11 25H2 and later during the last week of November 2026.
|
|
66
|
-
If that has happened, most of section 1 collapses into "nothing to install" and
|
|
67
|
-
the rest still applies.</em></p>
|
|
68
|
-
<p>This is <strong>the procedure the library was measured with</strong>, not a promise that it
|
|
69
|
-
works on another machine. All of it ran once, on one particular installation.
|
|
70
|
-
Where something was checked, it says so; where it was not, it says that too.</p>
|
|
71
|
-
<p>The machine was:</p>
|
|
72
|
-
<p>| | |
|
|
73
|
-
|---|---|
|
|
74
|
-
| Windows | 11 25H2, build <strong>26200.9278</strong> |
|
|
75
|
-
| CPU | ARM64 — a VMware VM on Apple silicon |
|
|
76
|
-
| Ruby | 3.4.10 <code>x64-mingw-ucrt</code>, <strong>emulated</strong> under Prism (no ARM64 Ruby present) |
|
|
77
|
-
| ffi | 1.17.4 <code>x64-mingw-ucrt</code>, precompiled binary |
|
|
78
|
-
| MIDI hardware | <strong>none</strong> — no USB device passed through to the guest |</p>
|
|
79
|
-
<p>That last row is why this document exists: with no hardware, a loopback pair is
|
|
80
|
-
the only way to exercise input and output at the same time.</p>
|
|
81
|
-
<p>Nothing measured on this setup says anything about <strong>timing</strong>. Emulation inside
|
|
82
|
-
a virtual machine; latency and jitter need real hardware and a native Ruby.</p>
|
|
83
|
-
<hr />
|
|
84
|
-
<h2 id="1__What_has_to_be_installed">1. What has to be installed</h2>
|
|
85
|
-
<p>Windows 11 25H2 ships <strong>Windows MIDI Services</strong> in the box: the <code>midisrv</code>
|
|
86
|
-
service (<code>C:\Windows\System32\midisrv.exe</code>) and the <code>wdmaud2.drv</code> shim,
|
|
87
|
-
registered as <code>midi1</code> under
|
|
88
|
-
<code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32</code>. That shim is what
|
|
89
|
-
makes endpoints from the new stack <strong>visible to WinMM</strong> without this gem doing
|
|
90
|
-
anything special, and therefore what makes this setup able to test a gem that
|
|
91
|
-
speaks only WinMM.</p>
|
|
92
|
-
<p>What is <em>not</em> in the box are the MIDI 1.0 loopback transport and the tools. Those
|
|
93
|
-
come from the [<code>microsoft/MIDI</code>] repository, release <code>inbox-dev-preview-6</code>:</p>
|
|
94
|
-
<ul>
|
|
95
|
-
<li><code>Windows.MIDI.Services.Basic.MIDI.1.0.Loopback.Preview.1.0.18-preview.3-arm64.exe</code></li>
|
|
96
|
-
<li><code>Windows.MIDI.Services.Tools.0.99.64-devpreview.6-arm64.exe</code></li>
|
|
97
|
-
</ul>
|
|
98
|
-
<p>There are <code>-x64</code> variants of both. The measuring machine used the <strong>native ARM64</strong>
|
|
99
|
-
ones (PE header <code>0xAA64</code>) even though the Ruby was emulated x64: the gem talks to
|
|
100
|
-
<code>winmm.dll</code>, and Windows handles the crossing.</p>
|
|
101
|
-
<p>The Network and Bluetooth transports from the same release are not needed.</p>
|
|
102
|
-
<h3 id="Warnings_that_are_not_optional">Warnings that are not optional</h3>
|
|
103
|
-
<ul>
|
|
104
|
-
<li><strong>These are unsigned preview binaries.</strong> The release notes require Windows
|
|
105
|
-
<strong>Developer Mode</strong>, and are explicit: <em>"There are almost certainly bugs and
|
|
106
|
-
missing/incomplete features."</em> This is not production software.</li>
|
|
107
|
-
<li><strong>Do not redistribute them.</strong> The release's permitted-use table forbids it. A
|
|
108
|
-
repository should link to the release and never host the installers.</li>
|
|
109
|
-
<li>Minimum system version declared: <strong>Windows 11 25H2</strong>.</li>
|
|
110
|
-
<li>Downloaded through a browser they carry Mark of the Web and SmartScreen will
|
|
111
|
-
object; <code>Unblock-File</code> clears it. Fetched with <code>Invoke-WebRequest</code> they do not.</li>
|
|
112
|
-
</ul>
|
|
113
|
-
<h2 id="2__Installing">2. Installing</h2>
|
|
114
|
-
<p>Both installers are <strong>WiX bundles</strong>, so they accept <code>/quiet</code>, <code>/norestart</code> and
|
|
115
|
-
<code>/log</code>. Both need <strong>elevation</strong>, and Developer Mode writes to <code>HKLM</code>, so it is
|
|
116
|
-
worth doing the whole thing in one elevated script and getting one UAC prompt.</p>
|
|
117
|
-
<p>The release notes fix the order: <strong>loopback transport first, tools second.</strong></p>
|
|
118
|
-
<pre class="code powershell"><code class="powershell"># --- 1. Developer Mode (the key may not exist)
|
|
119
|
-
$k = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock'
|
|
120
|
-
if (-not (Test-Path $k)) { New-Item $k -Force | Out-Null }
|
|
121
|
-
Set-ItemProperty $k -Name AllowDevelopmentWithoutDevLicense -Value 1 -Type DWord
|
|
122
|
-
Set-ItemProperty $k -Name AllowAllTrustedApps -Value 1 -Type DWord
|
|
123
|
-
|
|
124
|
-
# --- 2. installers, in this order
|
|
125
|
-
Start-Process -Wait -FilePath '<...>Basic.MIDI.1.0.Loopback.Preview...-arm64.exe' `
|
|
126
|
-
-ArgumentList '/quiet','/norestart','/log','loopback.log'
|
|
127
|
-
Start-Process -Wait -FilePath '<...>Tools.0.99.64-devpreview.6-arm64.exe' `
|
|
128
|
-
-ArgumentList '/quiet','/norestart','/log','tools.log'
|
|
129
|
-
</code></pre>
|
|
130
|
-
<p><strong>Both return exit <code>3010</code></strong>, which is <code>ERROR_SUCCESS_REBOOT_REQUIRED</code>: installed
|
|
131
|
-
correctly, reboot pending. The measuring machine <strong>was not rebooted</strong>, and every
|
|
132
|
-
measurement was taken that way. If something behaves oddly, that reboot is the
|
|
133
|
-
first suspect.</p>
|
|
134
|
-
<p>To check the transport registered:</p>
|
|
135
|
-
<pre class="code powershell"><code class="powershell">Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows MIDI Services\Transport Plugins'
|
|
136
|
-
# Midi2BasicLoopbackMidiTransport should appear, with Enabled = 1
|
|
137
|
-
</code></pre>
|
|
138
|
-
<h3 id="_midi_exe__and_the_PATH"><code>midi.exe</code> and the PATH</h3>
|
|
139
|
-
<p>The console lands at:</p>
|
|
140
|
-
<pre class="code ruby"><code class="ruby">C:\Program Files\Windows MIDI Services\Tools\Console\midi.exe
|
|
141
|
-
</code></pre>
|
|
142
|
-
<p>The installer <strong>does</strong> add it to the machine PATH, but <strong>a shell opened before
|
|
143
|
-
installing still has the old environment</strong> and will say <code>midi</code> does not exist. In
|
|
144
|
-
a fresh shell, <code>midi</code> is enough; in the installing shell, use the full path. This
|
|
145
|
-
detail cost time and produced one wrong report before it was noticed.</p>
|
|
146
|
-
<h2 id="3__Creating_the_loopback_pair">3. Creating the loopback pair</h2>
|
|
147
|
-
<pre class="code powershell"><code class="powershell">$midi = 'C:\Program Files\Windows MIDI Services\Tools\Console\midi.exe'
|
|
148
|
-
|
|
149
|
-
& $midi basic-loopback create --name "Reloj Bitwig ñ prueba de longitud"
|
|
150
|
-
& $midi basic-loopback list
|
|
151
|
-
</code></pre>
|
|
152
|
-
<p>Options for <code>create</code>:</p>
|
|
153
|
-
<table>
|
|
154
|
-
<thead>
|
|
155
|
-
<tr>
|
|
156
|
-
<th>option</th>
|
|
157
|
-
<th>what it does</th>
|
|
158
|
-
</tr>
|
|
159
|
-
</thead>
|
|
160
|
-
<tbody>
|
|
161
|
-
<tr>
|
|
162
|
-
<td><code>-n</code>, <code>--name</code></td>
|
|
163
|
-
<td>the endpoint's name</td>
|
|
164
|
-
</tr>
|
|
165
|
-
<tr>
|
|
166
|
-
<td><code>-u</code>, <code>--unique-identifier</code></td>
|
|
167
|
-
<td>an identifier of your own</td>
|
|
168
|
-
</tr>
|
|
169
|
-
<tr>
|
|
170
|
-
<td><code>-s</code>, <code>--save-to-config</code></td>
|
|
171
|
-
<td><strong>persists it in the system configuration</strong></td>
|
|
172
|
-
</tr>
|
|
173
|
-
</tbody>
|
|
174
|
-
</table>
|
|
175
|
-
<p><strong>Without <code>--save-to-config</code> a loopback is temporary</strong>: it disappears when
|
|
176
|
-
<code>midisrv</code> or the machine restarts, and nothing is written to disk. Every
|
|
177
|
-
measurement was taken that way, deliberately. <code>--save-to-config</code> does modify the
|
|
178
|
-
user's system configuration — ask before using it.</p>
|
|
179
|
-
<p>A <code>create</code> returns an <strong>Association Id</strong>, a GUID. Keep it: it is the only thing
|
|
180
|
-
that will remove the loopback again.</p>
|
|
181
|
-
<h3 id="Checking_through_WinMM__which_is_what_the_gem_sees">Checking through WinMM, which is what the gem sees</h3>
|
|
182
|
-
<pre class="code ruby"><code class="ruby">ruby -Ilib examples/list_ports.rb
|
|
183
|
-
</code></pre>
|
|
184
|
-
<p>One loopback shows up as <strong>one input and one output with the same name, byte for
|
|
185
|
-
byte</strong>. With two loopbacks created, enumeration gives 2 inputs and 3 outputs —
|
|
186
|
-
the third being the <em>Microsoft GS Wavetable Synth</em>, which is always there.</p>
|
|
187
|
-
<h2 id="4__The_name_collision_recipe">4. The name-collision recipe</h2>
|
|
188
|
-
<p>WinMM stores <strong>31 characters</strong> of a name (<code>MAXPNAMELEN</code> is 32, less the NUL) and
|
|
189
|
-
drops the rest <strong>silently</strong>. To reproduce the case where two distinct ports are
|
|
190
|
-
indistinguishable, create two loopbacks whose <strong>first 31 characters match</strong>:</p>
|
|
191
|
-
<pre class="code powershell"><code class="powershell">& $midi basic-loopback create --name "Reloj Bitwig ñ prueba de longitud"
|
|
192
|
-
& $midi basic-loopback create --name "Reloj Bitwig ñ prueba de longitud DOS"
|
|
193
|
-
</code></pre>
|
|
194
|
-
<p>The first is 33 characters, the second 37; both truncate to
|
|
195
|
-
<code>Reloj Bitwig ñ prueba de longit</code>. In <code>MIDIINCAPSW</code>/<code>MIDIOUTCAPSW</code> they come back
|
|
196
|
-
<strong>identical field by field</strong>: same name, same <code>wMid</code> (1), same <code>wPid</code> (25 for
|
|
197
|
-
inputs, 26 for outputs), same <code>vDriverVersion</code>, same <code>wTechnology</code>. Only the
|
|
198
|
-
index separates them.</p>
|
|
199
|
-
<p>If you change the names, keep the character counts working — the recipe depends
|
|
200
|
-
on one being longer than 31 and both agreeing up to that point.</p>
|
|
201
|
-
<p>The truncation happens <strong>upstream of WinMM</strong>: <code>midi enumerate midi-services-endpoints</code> shows the service already holding the 31-character name.
|
|
202
|
-
Whether the console or the service truncates was not determined; for the gem it
|
|
203
|
-
makes no difference.</p>
|
|
204
|
-
<p>The <code>ñ</code> survives intact (<code>U+00F1</code> in the UTF-16LE dump), which is what validates
|
|
205
|
-
the <strong>W</strong> entry points against a genuinely non-ASCII character.</p>
|
|
206
|
-
<h2 id="5__Removing">5. Removing</h2>
|
|
207
|
-
<pre class="code powershell"><code class="powershell">& $midi basic-loopback remove --association-id "{bfba125e-3aca-446c-9b94-692a70153034}"
|
|
208
|
-
</code></pre>
|
|
209
|
-
<p><strong>The braces around the GUID are required.</strong> <code>list</code> prints the id without them;
|
|
210
|
-
they have to be added.</p>
|
|
211
|
-
<p>Afterwards, check the machine is back where it started — with <code>list</code>, and better
|
|
212
|
-
still by enumerating through WinMM: with no loopbacks there should be <strong>0 inputs
|
|
213
|
-
and 1 output</strong>.</p>
|
|
214
|
-
<h2 id="6__What_this_setup_can_test__and_what_it_cannot">6. What this setup can test, and what it cannot</h2>
|
|
215
|
-
<p>Exercised with it, and working: enumeration with colliding names, short messages
|
|
216
|
-
in all three lengths (3, 2 and 1 bytes), accumulation in <code>gets</code>, System Exclusive
|
|
217
|
-
both ways at 200, 3000 and 5000 bytes, buffer recycling, closing and reopening,
|
|
218
|
-
and the propagation of an error from opening a port.</p>
|
|
219
|
-
<p><strong>Not testable with this setup</strong>, and therefore still untested:</p>
|
|
220
|
-
<ul>
|
|
221
|
-
<li><strong><code>SYSEX_TIMEOUT</code> / <code>Output#wait_until_sent</code>.</strong> The only real output device is
|
|
222
|
-
the <em>GS Wavetable Synth</em>, a software synthesiser that marks <code>MHDR_DONE</code> in
|
|
223
|
-
under a millisecond because there is no wire. This needs a physical interface.</li>
|
|
224
|
-
<li><strong><code>RESET_TIMEOUT</code> / <code>Input#await_returned_buffers</code>.</strong> It never came close:
|
|
225
|
-
closes took between 4 and 21 ms against a one-second bound. The
|
|
226
|
-
device-went-away path needs something to unplug.</li>
|
|
227
|
-
<li><strong>Renumbering in <code>Device.enumerate</code>.</strong> Needs a port to actually appear or go.</li>
|
|
228
|
-
<li><strong><code>MM_MIM_LONGERROR</code>.</strong> None could be provoked, not even with a System
|
|
229
|
-
Exclusive message larger than the entire buffer queue. The code handling it is
|
|
230
|
-
unexercised — its presence has been shown harmless, which is not the same
|
|
231
|
-
thing.</li>
|
|
232
|
-
<li><strong>That an input and an output of the same device share a name.</strong> Established
|
|
233
|
-
for a loopback, where they are literally the same device. Not for a real USB
|
|
234
|
-
interface.</li>
|
|
235
|
-
<li><strong>Any measurement of time.</strong></li>
|
|
236
|
-
</ul>
|
|
237
|
-
<p>Those are the items a session with real hardware should close.</p>
|
|
238
|
-
<h2 id="7__One_finding_from_here_worth_not_forgetting">7. One finding from here worth not forgetting</h2>
|
|
239
|
-
<p>Multi-client access <strong>follows the endpoint, not the API</strong>. Two WinMM clients on
|
|
240
|
-
the same BLOOP input both work and <strong>both receive every message</strong>. The <em>GS
|
|
241
|
-
Wavetable Synth</em>, which belongs to the classic <code>wdmaud</code> stack, refuses the second
|
|
242
|
-
open with <em>"The specified device is already in use."</em> So on one machine, through
|
|
243
|
-
one API, shareable ports and exclusive ports coexist.</p></div></div>
|
|
244
|
-
|
|
245
|
-
<div id="footer">
|
|
246
|
-
Generated on Sun Sep 6 21:20:52 2026 by
|
|
247
|
-
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
248
|
-
0.9.45 (ruby-3.4.7).
|
|
249
|
-
</div>
|
|
250
|
-
|
|
251
|
-
</div>
|
|
252
|
-
</body>
|
|
253
|
-
</html>
|
data/docs/testing-on-windows.md
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
# Testing this gem on Windows without MIDI hardware
|
|
2
|
-
|
|
3
|
-
*Written 2026-09-06. Section 1 is the part with a shelf life: it describes
|
|
4
|
-
software that was in preview at the time, which Microsoft's release notes said
|
|
5
|
-
was headed for Windows 11 25H2 and later during the last week of November 2026.
|
|
6
|
-
If that has happened, most of section 1 collapses into "nothing to install" and
|
|
7
|
-
the rest still applies.*
|
|
8
|
-
|
|
9
|
-
This is **the procedure the library was measured with**, not a promise that it
|
|
10
|
-
works on another machine. All of it ran once, on one particular installation.
|
|
11
|
-
Where something was checked, it says so; where it was not, it says that too.
|
|
12
|
-
|
|
13
|
-
The machine was:
|
|
14
|
-
|
|
15
|
-
| | |
|
|
16
|
-
|---|---|
|
|
17
|
-
| Windows | 11 25H2, build **26200.9278** |
|
|
18
|
-
| CPU | ARM64 — a VMware VM on Apple silicon |
|
|
19
|
-
| Ruby | 3.4.10 `x64-mingw-ucrt`, **emulated** under Prism (no ARM64 Ruby present) |
|
|
20
|
-
| ffi | 1.17.4 `x64-mingw-ucrt`, precompiled binary |
|
|
21
|
-
| MIDI hardware | **none** — no USB device passed through to the guest |
|
|
22
|
-
|
|
23
|
-
That last row is why this document exists: with no hardware, a loopback pair is
|
|
24
|
-
the only way to exercise input and output at the same time.
|
|
25
|
-
|
|
26
|
-
Nothing measured on this setup says anything about **timing**. Emulation inside
|
|
27
|
-
a virtual machine; latency and jitter need real hardware and a native Ruby.
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## 1. What has to be installed
|
|
32
|
-
|
|
33
|
-
Windows 11 25H2 ships **Windows MIDI Services** in the box: the `midisrv`
|
|
34
|
-
service (`C:\Windows\System32\midisrv.exe`) and the `wdmaud2.drv` shim,
|
|
35
|
-
registered as `midi1` under
|
|
36
|
-
`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32`. That shim is what
|
|
37
|
-
makes endpoints from the new stack **visible to WinMM** without this gem doing
|
|
38
|
-
anything special, and therefore what makes this setup able to test a gem that
|
|
39
|
-
speaks only WinMM.
|
|
40
|
-
|
|
41
|
-
What is *not* in the box are the MIDI 1.0 loopback transport and the tools. Those
|
|
42
|
-
come from the [`microsoft/MIDI`] repository, release `inbox-dev-preview-6`:
|
|
43
|
-
|
|
44
|
-
- `Windows.MIDI.Services.Basic.MIDI.1.0.Loopback.Preview.1.0.18-preview.3-arm64.exe`
|
|
45
|
-
- `Windows.MIDI.Services.Tools.0.99.64-devpreview.6-arm64.exe`
|
|
46
|
-
|
|
47
|
-
There are `-x64` variants of both. The measuring machine used the **native ARM64**
|
|
48
|
-
ones (PE header `0xAA64`) even though the Ruby was emulated x64: the gem talks to
|
|
49
|
-
`winmm.dll`, and Windows handles the crossing.
|
|
50
|
-
|
|
51
|
-
The Network and Bluetooth transports from the same release are not needed.
|
|
52
|
-
|
|
53
|
-
[`microsoft/MIDI`]: https://github.com/microsoft/MIDI/releases
|
|
54
|
-
|
|
55
|
-
### Warnings that are not optional
|
|
56
|
-
|
|
57
|
-
- **These are unsigned preview binaries.** The release notes require Windows
|
|
58
|
-
**Developer Mode**, and are explicit: *"There are almost certainly bugs and
|
|
59
|
-
missing/incomplete features."* This is not production software.
|
|
60
|
-
- **Do not redistribute them.** The release's permitted-use table forbids it. A
|
|
61
|
-
repository should link to the release and never host the installers.
|
|
62
|
-
- Minimum system version declared: **Windows 11 25H2**.
|
|
63
|
-
- Downloaded through a browser they carry Mark of the Web and SmartScreen will
|
|
64
|
-
object; `Unblock-File` clears it. Fetched with `Invoke-WebRequest` they do not.
|
|
65
|
-
|
|
66
|
-
## 2. Installing
|
|
67
|
-
|
|
68
|
-
Both installers are **WiX bundles**, so they accept `/quiet`, `/norestart` and
|
|
69
|
-
`/log`. Both need **elevation**, and Developer Mode writes to `HKLM`, so it is
|
|
70
|
-
worth doing the whole thing in one elevated script and getting one UAC prompt.
|
|
71
|
-
|
|
72
|
-
The release notes fix the order: **loopback transport first, tools second.**
|
|
73
|
-
|
|
74
|
-
```powershell
|
|
75
|
-
# --- 1. Developer Mode (the key may not exist)
|
|
76
|
-
$k = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock'
|
|
77
|
-
if (-not (Test-Path $k)) { New-Item $k -Force | Out-Null }
|
|
78
|
-
Set-ItemProperty $k -Name AllowDevelopmentWithoutDevLicense -Value 1 -Type DWord
|
|
79
|
-
Set-ItemProperty $k -Name AllowAllTrustedApps -Value 1 -Type DWord
|
|
80
|
-
|
|
81
|
-
# --- 2. installers, in this order
|
|
82
|
-
Start-Process -Wait -FilePath '<...>Basic.MIDI.1.0.Loopback.Preview...-arm64.exe' `
|
|
83
|
-
-ArgumentList '/quiet','/norestart','/log','loopback.log'
|
|
84
|
-
Start-Process -Wait -FilePath '<...>Tools.0.99.64-devpreview.6-arm64.exe' `
|
|
85
|
-
-ArgumentList '/quiet','/norestart','/log','tools.log'
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**Both return exit `3010`**, which is `ERROR_SUCCESS_REBOOT_REQUIRED`: installed
|
|
89
|
-
correctly, reboot pending. The measuring machine **was not rebooted**, and every
|
|
90
|
-
measurement was taken that way. If something behaves oddly, that reboot is the
|
|
91
|
-
first suspect.
|
|
92
|
-
|
|
93
|
-
To check the transport registered:
|
|
94
|
-
|
|
95
|
-
```powershell
|
|
96
|
-
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows MIDI Services\Transport Plugins'
|
|
97
|
-
# Midi2BasicLoopbackMidiTransport should appear, with Enabled = 1
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### `midi.exe` and the PATH
|
|
101
|
-
|
|
102
|
-
The console lands at:
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
C:\Program Files\Windows MIDI Services\Tools\Console\midi.exe
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
The installer **does** add it to the machine PATH, but **a shell opened before
|
|
109
|
-
installing still has the old environment** and will say `midi` does not exist. In
|
|
110
|
-
a fresh shell, `midi` is enough; in the installing shell, use the full path. This
|
|
111
|
-
detail cost time and produced one wrong report before it was noticed.
|
|
112
|
-
|
|
113
|
-
## 3. Creating the loopback pair
|
|
114
|
-
|
|
115
|
-
```powershell
|
|
116
|
-
$midi = 'C:\Program Files\Windows MIDI Services\Tools\Console\midi.exe'
|
|
117
|
-
|
|
118
|
-
& $midi basic-loopback create --name "Reloj Bitwig ñ prueba de longitud"
|
|
119
|
-
& $midi basic-loopback list
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Options for `create`:
|
|
123
|
-
|
|
124
|
-
| option | what it does |
|
|
125
|
-
|---|---|
|
|
126
|
-
| `-n`, `--name` | the endpoint's name |
|
|
127
|
-
| `-u`, `--unique-identifier` | an identifier of your own |
|
|
128
|
-
| `-s`, `--save-to-config` | **persists it in the system configuration** |
|
|
129
|
-
|
|
130
|
-
**Without `--save-to-config` a loopback is temporary**: it disappears when
|
|
131
|
-
`midisrv` or the machine restarts, and nothing is written to disk. Every
|
|
132
|
-
measurement was taken that way, deliberately. `--save-to-config` does modify the
|
|
133
|
-
user's system configuration — ask before using it.
|
|
134
|
-
|
|
135
|
-
A `create` returns an **Association Id**, a GUID. Keep it: it is the only thing
|
|
136
|
-
that will remove the loopback again.
|
|
137
|
-
|
|
138
|
-
### Checking through WinMM, which is what the gem sees
|
|
139
|
-
|
|
140
|
-
```
|
|
141
|
-
ruby -Ilib examples/list_ports.rb
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
One loopback shows up as **one input and one output with the same name, byte for
|
|
145
|
-
byte**. With two loopbacks created, enumeration gives 2 inputs and 3 outputs —
|
|
146
|
-
the third being the *Microsoft GS Wavetable Synth*, which is always there.
|
|
147
|
-
|
|
148
|
-
## 4. The name-collision recipe
|
|
149
|
-
|
|
150
|
-
WinMM stores **31 characters** of a name (`MAXPNAMELEN` is 32, less the NUL) and
|
|
151
|
-
drops the rest **silently**. To reproduce the case where two distinct ports are
|
|
152
|
-
indistinguishable, create two loopbacks whose **first 31 characters match**:
|
|
153
|
-
|
|
154
|
-
```powershell
|
|
155
|
-
& $midi basic-loopback create --name "Reloj Bitwig ñ prueba de longitud"
|
|
156
|
-
& $midi basic-loopback create --name "Reloj Bitwig ñ prueba de longitud DOS"
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
The first is 33 characters, the second 37; both truncate to
|
|
160
|
-
`Reloj Bitwig ñ prueba de longit`. In `MIDIINCAPSW`/`MIDIOUTCAPSW` they come back
|
|
161
|
-
**identical field by field**: same name, same `wMid` (1), same `wPid` (25 for
|
|
162
|
-
inputs, 26 for outputs), same `vDriverVersion`, same `wTechnology`. Only the
|
|
163
|
-
index separates them.
|
|
164
|
-
|
|
165
|
-
If you change the names, keep the character counts working — the recipe depends
|
|
166
|
-
on one being longer than 31 and both agreeing up to that point.
|
|
167
|
-
|
|
168
|
-
The truncation happens **upstream of WinMM**: `midi enumerate
|
|
169
|
-
midi-services-endpoints` shows the service already holding the 31-character name.
|
|
170
|
-
Whether the console or the service truncates was not determined; for the gem it
|
|
171
|
-
makes no difference.
|
|
172
|
-
|
|
173
|
-
The `ñ` survives intact (`U+00F1` in the UTF-16LE dump), which is what validates
|
|
174
|
-
the **W** entry points against a genuinely non-ASCII character.
|
|
175
|
-
|
|
176
|
-
## 5. Removing
|
|
177
|
-
|
|
178
|
-
```powershell
|
|
179
|
-
& $midi basic-loopback remove --association-id "{bfba125e-3aca-446c-9b94-692a70153034}"
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**The braces around the GUID are required.** `list` prints the id without them;
|
|
183
|
-
they have to be added.
|
|
184
|
-
|
|
185
|
-
Afterwards, check the machine is back where it started — with `list`, and better
|
|
186
|
-
still by enumerating through WinMM: with no loopbacks there should be **0 inputs
|
|
187
|
-
and 1 output**.
|
|
188
|
-
|
|
189
|
-
## 6. What this setup can test, and what it cannot
|
|
190
|
-
|
|
191
|
-
Exercised with it, and working: enumeration with colliding names, short messages
|
|
192
|
-
in all three lengths (3, 2 and 1 bytes), accumulation in `gets`, System Exclusive
|
|
193
|
-
both ways at 200, 3000 and 5000 bytes, buffer recycling, closing and reopening,
|
|
194
|
-
and the propagation of an error from opening a port.
|
|
195
|
-
|
|
196
|
-
**Not testable with this setup**, and therefore still untested:
|
|
197
|
-
|
|
198
|
-
- **`SYSEX_TIMEOUT` / `Output#wait_until_sent`.** The only real output device is
|
|
199
|
-
the *GS Wavetable Synth*, a software synthesiser that marks `MHDR_DONE` in
|
|
200
|
-
under a millisecond because there is no wire. This needs a physical interface.
|
|
201
|
-
- **`RESET_TIMEOUT` / `Input#await_returned_buffers`.** It never came close:
|
|
202
|
-
closes took between 4 and 21 ms against a one-second bound. The
|
|
203
|
-
device-went-away path needs something to unplug.
|
|
204
|
-
- **Renumbering in `Device.enumerate`.** Needs a port to actually appear or go.
|
|
205
|
-
- **`MM_MIM_LONGERROR`.** None could be provoked, not even with a System
|
|
206
|
-
Exclusive message larger than the entire buffer queue. The code handling it is
|
|
207
|
-
unexercised — its presence has been shown harmless, which is not the same
|
|
208
|
-
thing.
|
|
209
|
-
- **That an input and an output of the same device share a name.** Established
|
|
210
|
-
for a loopback, where they are literally the same device. Not for a real USB
|
|
211
|
-
interface.
|
|
212
|
-
- **Any measurement of time.**
|
|
213
|
-
|
|
214
|
-
Those are the items a session with real hardware should close.
|
|
215
|
-
|
|
216
|
-
## 7. One finding from here worth not forgetting
|
|
217
|
-
|
|
218
|
-
Multi-client access **follows the endpoint, not the API**. Two WinMM clients on
|
|
219
|
-
the same BLOOP input both work and **both receive every message**. The *GS
|
|
220
|
-
Wavetable Synth*, which belongs to the classic `wdmaud` stack, refuses the second
|
|
221
|
-
open with *"The specified device is already in use."* So on one machine, through
|
|
222
|
-
one API, shareable ports and exclusive ports coexist.
|