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

NAME

MIDI::RtMidi::FFI::Device - OO interface for MIDI::RtMidi::FFI

VERSION

version 0.05

SYNOPSIS

    use MIDI::RtMidi::FFI::Device;
    
    my $device = RtMidiOut->new;
    $device->open_virtual_port( 'perl-rtmidi' );
    $device->send_event( note_on => 0x00, 0x40, 0x5a );
    sleep 1;
    $device->send_event( note_off => 0x00, 0x40, 0x5a );

DESCRIPTION

MIDI::RtMidi::FFI::Device is an OO interface for MIDI::RtMidi::FFI to help you manage devices, ports and MIDI events.

METHODS

new

    my $device = MIDI::RtMidi::FFI::Device->new( %options );
    my $midiin = RtMidiIn->new( %options );
    my $midiout = RtMidiOut->new( %options );

Returns a new MIDI::RtMidi::FFI::Device object. RtMidiIn and RtMidiOut are provided as shorthand to instantiate devices of type 'in' and 'out' respectively. Valid attributes:

  • type - Device type : 'in' or 'out' (defaults to 'out')

    Ignored if instantiating RtMidiIn or RtMidiOut.

  • api - MIDI API to use. This should be a RtMidiApi constant. By default the device should use the first compiled API available. See search order notes in Using Simultaneous Multiple APIs on the RtMidi website.

  • api_name - MIDI API to use by name. One of 'alsa', 'jack', 'core', 'winmm' or 'dummy'.

  • name - Device name

  • queue_size_limit - (Type 'in' only) The buffer size to allocate for queueing incoming messages (defaults to 1024)

  • bufsize - (Type 'in' only) An alias for queue_size_limit.

  • ignore_sysex - (Type 'in' only) Ignore incoming SysEx messages (defaults to true)

  • ignore_timing - (Type 'in' only) Ignore incoming timing messages (defaults to true)

  • ignore_sensing - (Type 'in' only) Ignore incoming active sensing messages (defaults to true)

ok, msg, data, ptr

    warn $device->msg unless $device->ok;

Getters for RtMidiWrapper device struct members

open_virtual_port

    $device->open_virtual_port( $name );

Open a virtual device port. A virtual device may be connected to other MIDI software, just as with a hardware device.

This method will not work on Windows.

open_port

    $device->open_port( $port, $name );

Open a port.

get_ports_by_name

    $device->get_ports_by_name( $name );
    $device->get_ports_by_name( qr/name/ );

Returns a list of ports matching the supplied name criteria.

open_port_by_name

    $device->open_port_by_name( $name );
    $device->open_port_by_name( qr/name/ );
    $device->open_port_by_name( [ $name, $othername, qr/anothername/ ] );

Opens the first port found matching the supplied name criteria.

close_port

    $device->close_port();

Closes the currently open port

get_port_count

    $device->get_port_count();

Return the number of available MIDI ports to connect to.

get_port_name

    $self->get_port_name( $port );

Returns the name of the supplied port number.

get_current_api

    $self->get_current_api();

Returns the MIDI API in use for the device.

This is a RtMidiApi constant.

set_callback

    $device->set_callback( sub {
        my ( $ts, $msg ) = @_;
        # handle $msg here
    } );

Type 'in' only. Sets a callback to be executed when an incoming MIDI message is received. Your callback receives the time which has elapsed since the previous event in seconds, alongside the MIDI message.

As a callback may occur at any point in your program's flow, the program should probably not be doing much when it occurs. That is, programs handling RtMidi callbacks should be asleep or awaiting user input when the callback is triggered.

For the sake of compatibility with previous versions, some data may be passed which is passed to the callback for each event. This data parameter exists in the librtmidi interface to work around the lack of closures in C. It is less useful in Perl, though you are free to use it.

The data is not stored by librtmidi, so may be any Perl data structure you like.

    $device->set_callback( sub {
        my ( $ts, $msg, $data ) = @_;
        # handle $msg here
    }, $data );

See the examples included with this dist for some ideas on how to incorporate callbacks into your program.

set_callback_decoded

    $device->set_callback_decoded( sub {
        my ( $ts, $msg, $event ) = @_;
        # handle $msg / $event here
    } );

Same as "set_callback", though also attempts to decode the message with MIDI::Event, which is passed to the callback as an array ref. The original message is also sent in case this fails.

cancel_callback

    $device->cancel_callback();

Type 'in' only. Removes the callback from your device.

ignore_types

    $device->ignore_types( $ignore_sysex, $ignore_timing, $ignore_sensing );
    $device->ignore_types( (1)x3 );

Type 'in' only. Set message types to ignore.

ignore_sysex

    $device->ignore_sysex( 1 );
    $device->ignore_sysex( 0 );

Type 'in' only. Set whether or not to ignore sysex messages.

ignore_timing

    $device->ignore_timing( 1 );
    $device->ignore_timing( 0 );

Type 'in' only. Set whether or not to ignore timing messages.

ignore_sensing

    $device->ignore_sensing( 1 );
    $device->ignore_sensing( 0 );

Type 'in' only. Set whether or not to ignore active sensing messages.

get_message

    $device->get_message();

Type 'in' only. Gets the next message from the queue, if available.

get_event

    $device->get_message_decoded();

Type 'in' only. Gets the next message from the queue, if available, as a decoded MIDI::Event.

get_event

Alias for "get_message_decoded", for backwards compatibility.

NB Previous versions of this call spliced out the channel portion of the message. This is no longer the case. The dtime (or delta-time) portion is still removed.

decode_message

    $device->decode_message( $msg );

Attempts to decode the passed message with Midi::Event. Decoded messages should match the events listed in MIDI::Event documentation, except without dtime.

send_message

    $device->send_message( $msg );

Type 'out' only. Sends a message to the device's open port.

encode_message

    my $msg = $device->encode_message( note_on => 0x00, 0x40, 0x5a )
    $device->send_message( $msg );

Attempts to encode the passed message with MIDI::Event. The specification for events is the same as those listed in MIDI::Event's documentation, except dtime should be omitted.

send_message_encoded

    $device->send_message_encoded( @event );
    # Event, channel, note, velocity
    $device->send_message_encoded( note_on => 0x00, 0x40, 0x5a );
    $device->send_message_encoded( sysex => "Hello, computer?" );

Type 'out' only. Sends a MIDI::Event encoded message to the open port.

send_event

Alias for "send_message_encoded", for backwards compatibility.

NB Previous versions of this module stripped channel data from messages. This is no longer the case - channel should be provided where necessary.

KNOWN ISSUES

Use of MIDI::Event is a bit of a hack for convenience, exploiting the similarity of realtime MIDI messages and MIDI song file messages. It may break in unexpected ways if used for large SysEx messages or other "non-music" events, though should be fine for encoding and decoding note, pitch, aftertouch and CC messages.

SEE ALSO

RtMidi

MIDI::RtMidi::FFI

MIDI::Event

CONTRIBUTING

https://github.com/jbarrett/MIDI-RtMidi-FFI

All comments and contributions welcome.

BUGS AND SUPPORT

Please direct all requests to https://github.com/jbarrett/MIDI-RtMidi-FFI/issues

AUTHOR

John Barrett <john@jbrt.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by John Barrett.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.