Class: MTK::IO::JSoundInput

Inherits:
MIDIInput show all
Defined in:
lib/mtk/io/jsound_input.rb

Overview

Note:

This class is optional and only available if you require ‘mtk/midi/jsound_input’. It depends on the ‘jsound’ gem.

Provides realtime MIDI input for JRuby via the jsound gem.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from MIDIInput

available_input_types, find_by_name, input_types_by_device, open

Constructor Details

#initialize(input_device, options = {}) ⇒ JSoundInput

Returns a new instance of JSoundInput.



24
25
26
27
28
# File 'lib/mtk/io/jsound_input.rb', line 24

def initialize(input_device, options={})
  @device = input_device
  @recorder = ::JSound::Midi::Devices::Recorder.new(false)
  @device.open
end

Instance Attribute Details

#deviceObject (readonly)

Returns the value of attribute device.



22
23
24
# File 'lib/mtk/io/jsound_input.rb', line 22

def device
  @device
end

Class Method Details

.devicesObject



13
14
15
# File 'lib/mtk/io/jsound_input.rb', line 13

def self.devices
  @devices ||= ::JSound::Midi::INPUTS.devices
end

.devices_by_nameObject



17
18
19
# File 'lib/mtk/io/jsound_input.rb', line 17

def self.devices_by_name
  @devices_by_name ||= devices.each_with_object( Hash.new ){|device,hash| hash[device.description] = device }
end

Instance Method Details

#nameObject



30
31
32
# File 'lib/mtk/io/jsound_input.rb', line 30

def name
  @device.description
end

#record(options = {}) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mtk/io/jsound_input.rb', line 34

def record(options={})
  if options[:monitor]
    @monitor = ::JSound::Midi::Devices::Monitor.new
    @device >> [@monitor, @recorder]
  else
    @device >> @recorder
  end

  @recorder.clear
  @recorder.start
end

#stopObject



46
47
48
# File 'lib/mtk/io/jsound_input.rb', line 46

def stop
  @recorder.stop
end

#to_timeline(options = {}) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/mtk/io/jsound_input.rb', line 50

def to_timeline(options={})
  bpm = options.fetch :bmp, 120
  beats_per_second = bpm.to_f/60
  timeline = MTK::Events::Timeline.new
  note_ons = {}
  start = nil

  @recorder.messages_with_timestamps.each do |message,time|
    start = time unless start
    time -= start
    time /= beats_per_second

    message_type = message.type
    message_type = :note_off if message_type == :note_on and message.velocity == 0
    # TODO: this will need to be made more robust when we support off velocities

    next if message_type == :unknown # Ignore garbage messages

    case message_type
      when :note_on
        note_ons[message.pitch] = [message,time]

      when :note_off
        if note_ons.has_key? message.pitch
          note_on, start_time = note_ons.delete(message.pitch)
          duration = time - start_time
          note = MTK::Events::Note.from_midi(note_on.pitch, note_on.velocity, duration, message.channel)
          timeline.add time,note
        end

      else timeline.add time, MTK::Events::Parameter.from_midi([message_type, message.channel], message.data1, message.data2)
    end
  end

  timeline.quantize! options[:quantize] if options.key? :quantize
  timeline.shift_to! options[:shift_to] if options.key? :shift_to

  timeline
end