Class: MIDICommunicationsWindows::Input

Inherits:
Object
  • Object
show all
Extended by:
Device::ClassMethods
Includes:
Device::InstanceMethods
Defined in:
lib/midi-communications-windows/input.rb

Overview

A MIDI input port: somewhere messages arrive from.

gets blocks, and that is part of the contract

#gets waits until at least one message has arrived and then returns everything that accumulated. It does not return an empty array.

This is not an incidental property. Musa::Clock::InputMidiClock reads its MIDI Clock in a loop with no delay of its own, relying on gets to be where the thread waits. An implementation that returned immediately would turn that loop into a spin on a full core, and would do it silently — the notes would still play.

Examples:

Read from the first input

input = MIDICommunicationsWindows::Input.first
input.open
input.gets
# => [{ data: [144, 60, 100], timestamp: 1789123456.789 }]

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, name) ⇒ Input

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Input.

Parameters:

  • id (Integer) —

    the port's WinMM index among inputs

  • name (String) —

    the port's name as reported by WinMM



36
37
38
39
40
41
# File 'lib/midi-communications-windows/input.rb', line 36

def initialize(id, name)
  super

  @queue = Queue.new
  @sysex = []
end

Instance Attribute Details

#enabled ⇒ Object (readonly) Also known as: enabled? Originally defined in module Device::InstanceMethods

#id ⇒ Integer (readonly) Originally defined in module Device::InstanceMethods

Returns the port's WinMM index within its direction; see the note on identity in MIDICommunicationsWindows::Device.

Returns:

#name ⇒ String (readonly) Originally defined in module Device::InstanceMethods

Returns the port's name, as WinMM reports it, truncated to 31 characters. Not unique: see the note on names in MIDICommunicationsWindows::Device.

Returns:

Class Method Details

.all ⇒ Array<Input>, Array<Output> Originally defined in module Device::ClassMethods

Every port of this direction.

WinMM is asked afresh on every call, so a port that appeared or went away since the last one is reflected. A port that is still there comes back as the same object as before; see MIDICommunicationsWindows::Device.enumerate.

Returns:

.direction ⇒ Symbol

Returns :input.

Returns:

  • (Symbol) —

    :input



29
30
31
# File 'lib/midi-communications-windows/input.rb', line 29

def self.direction
  :input
end

.first ⇒ Input, ... Originally defined in module Device::ClassMethods

The first port of this direction, or nil if there are none.

Returns:

.last ⇒ Input, ... Originally defined in module Device::ClassMethods

The last port of this direction, or nil if there are none.

Returns:

Instance Method Details

#close ⇒ Boolean Originally defined in module Device::InstanceMethods

Closes the port.

Returns:

  • (Boolean) —

    true if it was open, false if it already was not

#display_name ⇒ String Originally defined in module Device::InstanceMethods

The name to show a person choosing a port.

This is the port name unchanged. On macOS the display name is built as "manufacturer model (name)", which here would render as a name wrapped in the punctuation of two absent fields.

Returns:

  • (String)

#gets ⇒ Array<Hash> Also known as: read

Reads the messages that have arrived.

Blocks until there is at least one. See the note on the class.

Examples:

input.gets
# => [{ data: [248], timestamp: 1789123456.789 },
#     { data: [144, 60, 100], timestamp: 1789123456.812 }]

Returns:

  • (Array<Hash>) —

    each with :data, an array of numeric bytes, and :timestamp, a Float of seconds



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/midi-communications-windows/input.rb', line 54

def gets
  # Queue#pop is where the thread waits, and it is the whole of the waiting
  # mechanism on purpose. The obvious alternative — test whether the queue
  # is empty, then sleep, and have the producer Thread#run the sleeper — has
  # a window between the test and the sleep in which a message can arrive
  # and its wake-up be delivered to a thread that is not sleeping yet. The
  # reader then sleeps forever, and the thread it happens on is the one
  # carrying the MIDI clock. Queue does the same job with no such window.
  messages = [@queue.pop]
  messages << @queue.pop until @queue.empty?

  messages
end

#gets_s ⇒ Array<Hash> Also known as: gets_bytestr

Reads the messages that have arrived, with their data as hex strings.

Examples:

input.gets_s
# => [{ data: 'F8', timestamp: 1789123456.789 }]

Returns:

  • (Array<Hash>) —

    as #gets, but :data is a String



76
77
78
79
80
# File 'lib/midi-communications-windows/input.rb', line 76

def gets_s
  gets.each do |message|
    message[:data] = TypeConversion.numeric_bytes_to_hex_string(message[:data])
  end
end

#manufacturer ⇒ nil Originally defined in module Device::InstanceMethods

Who made the device.

Always nil on Windows. See the note in MIDICommunicationsWindows::Device for why this is not derived from wMid.

Returns:

  • (nil)

#model ⇒ nil Originally defined in module Device::InstanceMethods

The device model.

Always nil on Windows, for the same reason as #manufacturer.

Returns:

  • (nil)

#open {|self| ... } ⇒ self Also known as: enable, start Originally defined in module Device::InstanceMethods

Opens the port.

Opening twice is not an error and does nothing the second time, which is what midi-communications relies on when it opens a port a caller may already hold.

Yields:

  • (self) —

    if a block is given, the port is closed when it returns

Returns:

  • (self)

Raises:

  • (Error) —

    if WinMM refuses to open the port

#to_s ⇒ String Originally defined in module Device::InstanceMethods

Returns:

  • (String)

#type ⇒ Symbol Originally defined in module Device::InstanceMethods

The port's direction.

Returns:

  • (Symbol) —

    :input or :output