如何在 Perl 中发送 MIDI 消息?

How to send MIDI messages in Perl?

我正在尝试使用 Perl 发送 MIDI 消息。基本上我想改变补丁乐器。由于我没有生成文件,而只是播放,所以我使用 Win32::MIDI 因为它是唯一可以满足我需要的模块,但是没有模块补丁工具方法,因此我只剩下 writeMIDI 这需要向它发送 MIDI 消息。

例如

...
# note_on event, channel 1 (0x90), velocity (127), note (127), null (0x00);
my $data_on = "\x0077\x90";     
# note_off event, channel 1 (0x80), velocity (127), note (127), null (0x00);
my $data_off  = "\x0077\x80";

$midi_obj->writeMIDI(unpack("N",$data_on));
sleep(2);
$midi_obj->writeMIDI(unpack("N",$data_off));

$midi_obj->writeMIDI(unpack("N","\x00\C18")); <-- NOT WORKING change instrument on channel # 1 to patch # 8

我正尝试在通道 1 上做一个 'Program Change',patch no#(例如 8),因为这会更改 patch 乐器。

正如我在参考资料中所说:

A.1。频道语音消息:

指示接收仪器为其语音分配特定的声音 打开和关闭注释 改变当前活跃音符的声音


Voice Message         Status Byte     Data Byte1         Data Byte2
Note off                      8x      Key number          Note Off velocity
Note on                       9x      Key number          Note on velocity
Polyphonic Key Pressure       Ax      Key number          Amount of pressure
Control Change                Bx      Controller number   Controller value
<br>Program Change                Cx      Program number      None     
<br>Channel Pressure              Dx      Pressure value      None            
Pitch Bend                    Ex      MSB                 LSB
Notes: `x' in status byte hex value stands for a channel number.

我正在使用的参考资料 https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node158.html

unpack("N","\x00\C18F")

这看起来不正确,没有字符串转义 \C。此外,如果您尝试编写八进制转义符,C187F 仍然不是八进制数。请用十六进制说明您要写的内容。

可以在 perlop:

中找到更多关于八进制转义的信息

3

The result is the character specified by the three-digit octal number in the range 000 to 777 (but best to not use above 077, see next paragraph)

Some contexts allow 2 or even 1 digit, but any usage without exactly three digits, the first being a zero, may give unintended results. (For example, in a regular expression it may be confused with a backreference; see "Octal escapes" in perlrebackslash.) Starting in Perl 5.14, you may use \o{} instead, which avoids all these problems. Otherwise, it is best to use this construct only for ordinals 7 and below, remembering to pad to the left with zeros to make three digits. For larger ordinals, either use \o{}, or convert to something else, such as to hex and use \N{U+} (which is portable between platforms with different character sets) or \x{} instead.

更新:

I am trying to do a 'Program Change', as this changes the patch instrument.

根据 this and this 你可以尝试这样的事情:

my $channel_number = 1;
my $program_number = 15;
my $unused = 0;
my $str = pack("CCCC", $unused, $unused, $program_number, $channel_number+0xC0);
$midi_obj->writeMIDI(unpack("N",$str));