I am trying to send MIDI messages using Perl. Basically I want to change the patch instrument. Since I am not generating a file, but playing only, I am using Win32::MIDI
as it is the only module that works for what I require, but there is no module patch instrument method, therefore I am left with writeMIDI
which requires sending it a MIDI message.
eg.
...
# note_on event, channel 1 (0x90), velocity (127), note (127), null (0x00);
my $data_on = "\x00\127\127\x90";
# note_off event, channel 1 (0x80), velocity (127), note (127), null (0x00);
my $data_off = "\x00\127\127\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
I am trying to do a 'Program Change' on Channel 1, patch no# (eg. 8) as this changes the patch instrument.
as it says in my reference:
A.1. Channel voice messages:
Instruct the receiving instrument to assign particular sounds to its voice Turn notes on and off Alter the sound of the currently active note or notes
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
Program Change Cx Program number None
Channel Pressure Dx Pressure value None
Pitch Bend Ex MSB LSB
Notes: `x' in status byte hex value stands for a channel number.
Reference I am using https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node158.html
CodePudding user response:
unpack("N","\x00\C18\7F")
This does not look correct, there is no string escape \C
. Also if you were trying to write an octal escape, still C18
and 7F
would not be octal numbers. Please clarify what you are trying to write in hex.
Some more information on octal escapes can be found in perlop:
\033
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\077
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.
Update:
I am trying to do a 'Program Change', as this changes the patch instrument.
According to this and this you could try something like 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));