The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Win32::MIDI - Perl extension for writing to MIDI devices under Win32

SYNOPSIS

  use Win32::MIDI;

        # create new instance of the class, you need to create
        # a new object for every midi device you want to write to
        # at any given time.  You can only open a device once, so no
        # two objects can write to the same device at the same time.
        
  my $midi_obj = Win32::MIDI->new();

        # print number of available (writing) devices
        
  print $midi_obj->numDevices() . "\n";

        # open a device

  $midi_obj->openDevice(0);

        # set default channel

  $midi_obj->cur_channel(1);

        # play a note by absolute value (numeric)
        # middle C - 60
        # note,dur,velocity
        
  $midi_obj->play_note(60,2.5,127) || print $midi_obj->error() . "\n" and $midi_obj->reset_error();

        # set default octave (middle)
        
  $midi_obj->cur_octave(4);
  
        # play a note by relative name (note name)
        # middle C - 60
        # note,dur,velocity

  $midi_obj->play_note(C,2.5,127) || print $midi_obj->error() . "\n" and $midi_obj->reset_error();

        # close the device
        
  $midi_obj->closeDevice();

  
        ## Low-Level Method -- Writing Directly To The Device,
        ## Creating Your Own MIDI Messages


        # 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(3);

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

        # NOTE: Mixed-case methods warn() on error
        # Others use $obj->error();
        

DESCRIPTION

Win32::MIDI Version 0.2

Win32::MIDI serves as a driver for PERL to gain write access to a MIDI device. This module is, in no way, complete or expansive. It does not currently provide access to reading data from a MIDI device. It is intended to compliment such packages as Win32::Sound and MIDI-Perl (indeed, it would be quite nice if it were more compatible with MIDI-Perl). Win32::MIDI provides the ability to send Channel Control messages, Pitch Wheel Changes, (some) SYSEX messages, Aftertouch, Notes, and a whole lot more to any available MIDI output device on your system. This module uses the Time::HiRes module to provide timing intervals of less than a second. This package is by no means complete, and can be expanded upon a great deal.

You will need Win32::Sound if you wish to know anything about a device other than its number. (See the info on openDevice() below)

This module can be retrieved from http://www.digitalKOMA.com/church/projects/

METHODS

 new()

        Creates a new instance of the class.  Returns a blessed object upon success.

        Usage:

                my $object = Win32::MIDI::new();



 error()

        Returns the last set error message.  Returns undef() if no errors have occured.

        Usage:

                my $error = $object->error();



 reset_error()

        Resets the error message mechanism.  error() will now return undef.

        Always returns true (1).

        Usage:

                $object->reset_error();



 numDevices()

        Returns the number of available MIDIOUT devices on the system.
        For more information about these devices, you should use the Devices() method of Win32::Sound.

        This method, as all methods with mixed-case names do, utilizes croak() on errors.
        
        Usage:

                my $num_devices = $object->numDevices();



 openDevice NUM

        Opens a MIDI device, specified by NUM.
        NUM corresponds to the (x) portion of MIDIOUTx as returned by Win32::Sound::Devices().  This number
        should never be more than the number of devices returned by numDevices() minus 1.  You must open a
        device BEFORE you attempt to write any data to a MIDI device or close a device.  If you wish to open
        more than one device at a time, you must create another instance of this class to do so.

        This method, as all methods with mixed-case names do, utilizes croak() on errors.
        
        Usage:

                $object->openDevice(1);



 closeDevice()

        Closes the currently open device.

        This method, as all methods with mixed-case names do, utilizes croak() on errors.

        Usage:

                $object->closeDevice();



 play_note NOTE DURATION VELOCITY CHANNEL ON/OFF OCTAVE

        Sends a note_on event to an opened MIDIOUT device.  The following arguments may be supplied:

        NOTE            The note to play, can be an absolute note value (e.g.: 100) or relative name (e.g.: 'C')
        DURATION        A decimal representing how many seconds to play the note for.  May be less than 1.
        VELOCITY        (optional) The velocity value of the note being played, defaults to 127.
        CHANNEL (optional) The channel to play the note on (1..16) checks cur_channel() if not supplied.
                        Defaults to 1.
        ON/OFF  (optional) Specifies whether a note_off event should be sent at the end of DURATION.
                        Boolean: 1 = send note_off event, 0 = do not send
        OCTAVE  (optional) Used in conjunction with a relative note name (e.g.: 'C'), specifies the octave the
                        note falls in.  If not supplied, and a relative note name is used, will check cur_octave().  If
                        no 'current octave' is set, then the method will fail.


        All arguments are positional.  That is to say, if you wish to supply OCTAVE, you must supply all
        other arguments.
        
        Returns true (1) on success, sets the value of error() and returns undef() on failure.

        Usage:

                        # play note by absolute vlaue, and minimum arguments.
                        
                if($object->play_note(60,.35)) {
                        print("Note played.\n");
                        } else {
                                print $object->error() . "\n" and $object->reset_error();
                                }

                        # play note by relative name, specifying octave
                        # middle C (c4), half a second duration full velocity, channel 1
                        # with note_off event
                        
                if($object->play_note('C',.5,127,1,1,4)) {
                        print("Note played.\n");
                        } else {
                                print $object->error() . "\n" and $object->reset_error();
                                }

                        # use cur_octave and relative names for minimum arguments

                        # cycle through octaves, playing C from each.

                my $nmRef = $object->note_map();
                
                foreach my $octave (sort { $a <=> $b } keys(%{ $nmRef })) {
                        $object->cur_octave($octave);
                        print("Octave is $octave\n");
                        if($object->play_note('C',.5)) {
                                print("\tPlayed C\n");
                                } else {
                                        print $object->error() . "\n" and $object->reset_error();
                                        }
                        }



 cur_octave OCTAVE

        Returns the current 'default' octave.  Sets the current 'default' octave if OCTAVE
        is supplied.     Valid range for OCTAVE is -1..9. (unless you have redefined the Note
        Name Map, see note_map() below.)

        The 'default' octave is utilized when no OCTAVE argument is provided to the play_note()
        method and a relative note name (e.g.: 'C#') is utilized.

        This function always returns the currently set 'default' octave, and undef() if no
        'default' octave has been set.

        Usage:

                $object->cur_octave('3');
                my $octave = $object->cur_octave();



 cur_channel CHANNEL

        Returns the current 'default' channel.  Sets the current 'default' channel if CHANNEL
        is supplied.  Valid range for CHANNEL is 1..16.

        The 'default' channel is utilized when no CHANNEL argument is provided to the play_note()
        method.

        This function always returns the currently set 'default' channel, and undef() if no
        'default' channel has been set.

        Usage:

                $object->cur_channel('1');
                my $channel = $object->cur_channel();

                
 note_map()

        Returns a reference to the hash which represents the current mapping of note names to
        absolute note values, grouped by octave.  By changing the data within the reference, you can
        create new octaves, new note names, and more.  Note names can be anything you desire, octaves
        must be numeric.  You may define any number of octaves as well.

        The Note Map is accessed on every call to play_note() that utilizes a relative note name.

        For a read-only version of the note map, see value_of() method below.
        
        The structure of the note map is as follows:

        Top
                Octave
                        Note
                                Value
                        Note
                                Value
                Octave
                        Note
                                Value

        That is,

        %map = ();
        $map{4} = ();
        $map{4}{'c'} = 60;
        $map{4}{'c#'} = 61;
        $map{4}{'d'} = 62;

        It is useful to note, that all note names must be lower-cased, even though you can use any
        word to name a note, if you use any upper-cased characters, the note will not be retrievable.
        (This is to allow the use of any case when calling play_note(), see it's entry below)

        By default, the range of octaves is -1..9, where C4 is 60.
         

        Usage:

        my $hRef = $object->note_map();

                # Print the     contents of the map

        foreach my $key (sort { $a <=> $b } keys(%{ $hRef })) {
                print("Octave $key:\n");
                foreach my $note (sort { $a cmp $b } keys(%{ $hRef->{"$key"} })) {
                        my $abs_value = $hRef->{"$key"}{"$note"};
                        print("\tNote: $note, Absolute Value: $abs_value\n");
                        next;
                        }
                next;
                }

                # create a new map

        %{ $hRef } = ();

                # group by 4 notes, using a, b, c, and d.  There are 0-127      (128 total) possible
                # values.
         
         my $total_octaves = 128 / 4;
         my $base_note_val = 0;
         
         for my $oct (1..$total_octaves) {
                 $hRef->{"$oct"} = ();
                 for my $note (a..d) {
                         last if($base_note_val > 127);
                         $hRef->{"$oct"}{"$note"} = $base_note_val;
                         $base_note_val++;
                        }
                }


                # all calls to play_note() utilizing named notes will now use this note map.



 value_of NAME OPT1 OPT2

        Returns the stored value of a given data element in use by the module.  NAME is the name of the
        element you wish to receive, and OPT1 and OPT2 can be utilized to become more specific.  Not
        all names require, or can have OPT arguments.  NAME can be one of the following:

                note
                velocity
                cc
                channel
                channel_aftertouch
                polyphonic
                pitch_wheel
                special
                note_name_map
                null

        The data returned is read-only, and is of the type specified, all elements consist of a single byte
        except for generally described elements (lacking a specific target, i.e. OPT which specifies which
        value of the list of elements of that type to return, in which case a hash is returned).


        The following data elements can accept OPT2 arguments, and the possible values:

        
        channel         OPT1 = on|off   OPT2 = channel number [1..16]

                Returns the byte to use as a channel note on/off MIDI status.  Can
                also return the entire hash of a particular state (on/off) or both.
                
                e.g.:
                        my $channel_1_on_byte = $object->value_of('channel','on',1);
                        my $channel_4_off_byte = $object->value_of('channel','off',4);

        note_name_map   OPT1 = octave   OPT2 = note name

                Returns the mapping of relative note names to octaves and absolute note
                values.  Can return a single note's value, an entire octave, or the entire range
                of octaves.
                
                e.g.:
                        my $c4_note_value = $object->value_of('note_name_map',4,'c');
                        my $d_sharp_neg1 = $object->value_of('note_name_map',-1,'d#');

                                See the note_map() method above for a writeable version of the
                                note name map.


        Either of the above elements will return hashes if not given OPT2 or OPT1.
        OPT2 can only be supplied if OPT1 is.  Example:

                my %note_hash = ($object->value_of('note_name_map'));
                print $note_hash{4}{'d#'} . "\n";


                my $channel_off_hash = ($object->value_of('channel','off'));
                print $channel_off_hash{};


        The other elements are described here:

        note OPT1 = number [0..127]

                Returns the MIDI byte which represents a note event (to be combined with a channel
                on/off MIDI status byte and velocity value byte).  Returns a hash with 128 keys (0..127)
                if OPT1 is omitted.

        velocity OPT1 = value [0..127]

                Return the MIDI byte which represents a velocity level.  See note, above.  Returns a hash
                with 128 keys (0..127) if OPT1 is omitted.

        cc OPT1 = channel [1..16]

                Returns the MIDI byte which represents a MIDI Channel Control event.  To be used in
                creating MIDI CC commands.  Returns a hash with 16 keys (1..16) if OPT1 is omitted.

        channel_aftertouch OPT1 = channel (1..16)                       

                Returns the MIDI byte which represents a MIDI Channel Aftertouch command.  Returns
                a hash with 16 keys (1..16) if OPT1 is omitted.

        polyphonic OPT1 = channel (1..16)

                Returns the MIDI byte which represents a MIDI Polyphonic Aftertouch command.  Returns
                a hash with 16 keys (1..16) if OPT1 is omitted.

        pitch_wheel OPT1 = channel (1..16)

                Returns the MIDI byte which represents a MIDI Pitch Wheel change.  Returns      a hash with 16
                keys (1..16) if OPT1 is omitted.

        special OPT1 = number   (1..16)

                Returns the MIDI byte which represents a MIDI special command, such as SYSEX or PLAY.
                Returns a hash with 16 keys (1..16) if OPT1 is omitted.

        null

                Returns the current value of a NULL byte.  This is used to construct and pad MIDI messages.
                If OPT1 is supplied, undef() will be returned.
                
                
        This method is used both internally and externally to access the raw data used to construct a
        MESSAGE for the low-level writeMIDI() method below.  You can utilize this method to avoid having
        to create your own data maps when sending out messages.

        

 send_cc CCVALUE CCDATA CHANNEL

        Sends a MIDI Channel Control message.  The following arguments are accepted:

        CCVALUE Which Channel Control message to send.  Values range 0..127.  Each value
                        typically maps to a function as defined by the MMA.  For example, Modulation
                        Wheel position is value 33.  This determines what the contents of CCDATA may be.

        CCDATA  The data to send related to the Control Message specified by CCVALUE.  CCDATA
                        is always numeric, and the maximum value is always 127.  CCVALUE determines what
                        an appropriate value for CCDATA is.  For example, to move the Mod Wheel to position
                        slightly below 'default', you'd use a CCVALUE of 33 and CCDATA of 62 (64 is roughly
                        center, or 'default').

        CHANNEL (optional) The channel to send a Control Message to.  If no CHANNEL is supplied, then
                        cur_channel() is consulted.  Will default to 1 if no 'current channel' is set.

        Returns true (1) on success, sets the value of error() and return undef() on failure.

        Usage:

                        # send an expression controller change, move it up, and then back down

                if($object->send_cc(11,68,1)) {
                        print("Expression Controller Go Up\n");
                        if($object->send_cc(11,50,1)) {
                                print("Expression Controller Go Down\n");
                                } else {
                                        print $object->error() . "\n" and $object->reset_error();
                                        }
                        } else {
                                print $object->error() . "\n" and $object->reset_error();
                                }
                                



 pitch_wheel VALUE1 VALUE2 CHANNEL

        Sends a pitch wheel change to specified CHANNEL.  Two values are used for changes
        of fine granularity.  The following arguments are accepted:

        VALUE1  The major value.  0-127.
        VALUE2  The minor value. 0-127.
        CHANNEL (optional) The channel to send the Pitch Wheel change to.  If not supplied,
                        cur_channel() is consulted.  Defaults to 1 if no 'current channel' has been set.

        The two (major + minor) VALUEs are used to allow for very fluid, human-like changes.  You
        can consider the MAJOR value (VALUE1) to be the 'large step' position, and the MINOR value
        (VALUE2) to be the 'small step' position.  That is, if we first chopped the total length the pitch
        wheel can move into 128 sections, we get the MAJOR value, if we then split each of those sections
        in 128 small sections, we'd have the minor value.  VALUE1, then, determines our 'big' steps, and
        VALUE2 determines our 'precise' movement within that 'step'.

        Returns true (1) on success, sets the value of error() and returns undef() on failure.

        Usage:

                        # move pitchwheel up slightly (64/64 can be considered 'center', or unchanged)

                if($object->pitch_wheel(64,70,1)) {
                        print("I moved it up slightly\n");
                        } else {
                                print $object->error() . "\n" and $object->reset_error();
                                }

                        # move pitchwheel down VERY far and then reset it.

                if($object->pitch_wheel(0,1,1)) {
                        print("Dropped it down\n");
                        if($object->pitch_wheel(64,64,1)) {
                                print("Back to normal\n");
                                } else {
                                        print $object->error() . "\n" and $object->reset_error();
                                        }
                        } else {
                                print $object->error() . "\n" and $object->reset_error();
                                }



 writeMIDI MESSAGE

        Writes MESSAGE to the currently open MIDI device.
        Structure of MESSAGE comes from the midiOutShortMsg() function of Winmm.dll:

        A doubleword (long) message with the first byte of the message in the low-order byte.
        The message is packed as follows:

                Word            Byte                    Usage
                High            High-order              Not used.
                                Low-order               The second byte of MIDI data (when needed)
                Low             High-order              The first byte of MIDI data (when needed)
                                Low-order               The MIDI Status

        This means that the format of MESSAGE must be an unsigned long in "network" order.

        To achieve this, you can create a string with the necessary values like this:

                my $string = "\x00\127\127\x90";

        Which mean:

                Not used data           : NULL (\x00)
                Second MIDI Byte        : Velocity 127 (\127)
                First MIDI Byte         : Note 127 (\127)
                Status                  : note_on channel 1 (\x90)

        Then, you must convert the string into an unsigned long, in network order:

                my $message = unpack("N",$string);

        For more information on the byte data for MIDI messages, see http://www.harmony-central.com/MIDI/Doc/

        This method, as all methods with mixed-case names do, utilizes croak() on errors.

        Usage:

                $object->writeMIDI($message);   


                

EXPORT

None.

AUTHOR

C. Church, <dolljunkie@digitalKOMA.com>

SEE ALSO

perl, MIDI-Perl, Win32::Sound, MIDI, http://www.harmony-central.com/MIDI/Doc/