Git Product home page Git Product logo

unimidi's Introduction

UniMIDI

Platform independent realtime MIDI input and output for Ruby.

Also see MicroMIDI which builds a full MIDI messaging DSL on top of this library.

Features

  • Supports Linux, JRuby, OSX, Windows and Cygwin
  • No compilation required
  • Both input and output to and from multiple devices concurrently
  • Generalized handling of different MIDI and SysEx Message types
  • (OSX Only) Use IAC to internally route MIDI to other programs

Requirements

UniMIDI uses one of the following libraries, depending on which platform you're using it on. The necessary library should install automatically with the unimidi gem.

Platform

Install

If you're using Bundler, add this line to your application's Gemfile:

gem "unimidi"

Otherwise...

gem install unimidi

Usage

Blog Posts

In addition, some examples are included with the library

Tests

UniMIDI includes a set of tests which assume that an output is connected to an input. You will be asked to select which input and output as the test is run.

The tests can be run using

rake spec

See below for additional notes on testing with JRuby

Documentation

rdoc

Platform Specific Notes

JRuby
  • javax.sound has some documented issues with SysEx messages in some versions OSX Snow Leopard which do affect this library.
Linux
  • libasound and libasound-dev packages are required

Author

Ari Russo <ari.russo at gmail.com>

License

Apache 2.0, See the file LICENSE

Copyright (c) 2010-2022 Ari Russo

unimidi's People

Contributors

arirusso avatar dfl avatar kachick avatar lpil avatar rcmc2 avatar teancom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unimidi's Issues

How to access UniMIDI::Output's @buffer to see if a note is still playing?

I have an imperfect method of sending notes to be played to UniMIDI (javascript/ajax) and sometimes the signal to stop playing the note isn't sent, so the note keeps going on indefinitely.

I need a way to view which notes are currently playing, but can't find it in the documentation or demos. When I inspect my Output object, however, I see this:

=> #<UniMIDI::CoreMIDIAdapter::Output:0x007fceb217b5f0
 @device=
  #<CoreMIDI::Destination:0x007fceb21815e0
   @client=#<FFI::Pointer address=0x00000005eeb01c>,
   @enabled=true,
   @entity=
    #<CoreMIDI::Entity:0x007fceb2183930
     @endpoints=
      {:source=>
        [#<CoreMIDI::Source:0x007fceb2183278
          @buffer=
           [{:data=>[144, 36, 100], :timestamp=>19540.279150009155},
            {:data=>[144, 40, 100], :timestamp=>48366.633892059326}],
            ...

That @buffer array is exactly what I need (it's currently showing two notes, 36 and 40, that haven't been stopped), but after several minutes pouring through the docs and poking each of Output's public methods, I can't seem to get at it. Is there a correct way to do this?

Numerous crashes on OSX.

Versions

  • OSX: Yosemite 10.10.5
  • Ruby: MRI 2.2.3
  • UniMIDI: 0.4.6
  • ffi-coremidi: 0.3.8
  • ffi: 1.9.10

Problem

In short, it appears to be the case that if I send messages 'too fast', I get a segfault in a subsequent transition between native code and Ruby (commonly Thread.sleep, but I've seen it happen in other very random places too suggesting that the VM is pre-empting plain Ruby code to service another thread and kaboom).

My current working hypothesis is that the CoreMIDI buffer fills up, and error handling is not a thing that is being done in such a scenario. Looking at the CoreMIDI API, it looks like it's the callers' responsibility to gate themselves using a completion callback, etc.

The problem here is that in some cases I know with absolute certainty that I can robustly send MIDI messages to the particular device much more quickly than I can apparently manage with UniMIDI. For example, using portmidi, I can update every LED on the grid of a Novation Launchpad Mark 2 in RGB mode (sysex payloads are much longer for this; I wind up sending two sysex messages to do a full-board update*) at a rate of about 45hz. Using UniMIDI, things seem generally stable only if I gate it to about 12hz or less.

Proposed Solution

  1. Is there a way to tell CoreMIDI to push messages more quickly? If so, that would be helpful.
    • Note that while it schedules messages based on timestamp, merely setting timestamp to 0 does not appear to help at all. Perhaps setting the message to be slightly in the past would, but I haven't tried that yet.
  2. Implement completion callbacks, and block on sending new messages until the last one is completed. Alternatively if there's some known buffer size behind the scenes that can be controlled or whose size can be queried, block only when it fills up and only until there's room for the next message.

Reproduction

I don't have a great isolated test case, at the moment, but the code I'm working on is here:

https://github.com/MrJoy/surface_master/tree/unimidi_experiment

Specifically, see the examples directory and commit history for those files. The Numark Orbit ones are a bit misleading as I have both the problem of CoreMIDI backlogging and causing a segfault but also a 'soft' issue of the Orbit getting stuck and going into la-la land if I send things too quickly -- but not quickly enough to trigger the fault.

improve device selection error messages

I'm trying out your micromidi library and when I try to run the example in the readme, I get an error when using the use method:

ruby-1.9.2-p290 :001 > require 'midi'
 => true 
ruby-1.9.2-p290 :002 > @i = UniMIDI::Input.use(:first)
NoMethodError: private method `open' called for nil:NilClass
    from /Users/rulfzid/.rvm/gems/ruby-1.9.2-p290@s10-edu/gems/unimidi-0.3.2/lib/unimidi/congruous_api_adapter.rb:147:in `use_device'
    from /Users/rulfzid/.rvm/gems/ruby-1.9.2-p290@s10-edu/gems/unimidi-0.3.2/lib/unimidi/congruous_api_adapter.rb:98:in `use'
    from (irb):2
    from /Users/rulfzid/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
ruby-1.9.2-p290 :003 > @o = UniMIDI::Output.use(:first)
NoMethodError: private method `open' called for nil:NilClass
    from /Users/rulfzid/.rvm/gems/ruby-1.9.2-p290@s10-edu/gems/unimidi-0.3.2/lib/unimidi/congruous_api_adapter.rb:147:in `use_device'
    from /Users/rulfzid/.rvm/gems/ruby-1.9.2-p290@s10-edu/gems/unimidi-0.3.2/lib/unimidi/congruous_api_adapter.rb:98:in `use'
    from (irb):3
    from /Users/rulfzid/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
ruby-1.9.2-p290 :004 > exit

I'm on OSX Lion, running ruby 1.9.2. Is there something I'm missing?

Another strange thing: i couldn't even get it to require 'midi' until i installed the alsa-rawmidi, midi-jruby and midi-winmm gems. The first i understand, but seems like some platform detection might not be working correctly for the latter two.

Issue when listing/connecting to virmidi devices on Linux

amidi -l:

[Thu 30 Aug 2018 04:18:04 GMT]$ amidi -l
Dir Device    Name
IO  hw:0,0    Virtual Raw MIDI (16 subdevices)
IO  hw:0,1    Virtual Raw MIDI (16 subdevices)
IO  hw:0,2    Virtual Raw MIDI (16 subdevices)
IO  hw:0,3    Virtual Raw MIDI (16 subdevices)
IO  hw:1,0    pisound MIDI PS-3255DBQ
IO  hw:3,0,0  Arturia KeyStep 32 MIDI 1
IO  hw:4,0,0  Arturia BeatStep MIDI 1

aconnect -l:

[Thu 30 Aug 2018 04:18:06 GMT]$ aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 16: 'Virtual Raw MIDI 0-0' [type=kernel,card=0]
    0 'VirMIDI 0-0     '
client 17: 'Virtual Raw MIDI 0-1' [type=kernel,card=0]
    0 'VirMIDI 0-1     '
client 18: 'Virtual Raw MIDI 0-2' [type=kernel,card=0]
    0 'VirMIDI 0-2     '
client 19: 'Virtual Raw MIDI 0-3' [type=kernel,card=0]
    0 'VirMIDI 0-3     '
client 20: 'pisound' [type=kernel,card=1]
    0 'pisound MIDI PS-3255DBQ'
client 28: 'Arturia KeyStep 32' [type=kernel,card=3]
    0 'Arturia KeyStep 32 MIDI 1'
client 32: 'Arturia BeatStep' [type=kernel,card=4]
    0 'Arturia BeatStep MIDI 1'
client 128: 'pisound-ctl' [type=user,pid=824]
    0 'pisound-ctl     '

UniMIDI::Input.gets:

Select a MIDI input...
0) Virtual Raw MIDI
1) Virtual Raw MIDI
2) Virtual Raw MIDI
3) Virtual Raw MIDI
4) Virtual Raw MIDI
5) Virtual Raw MIDI
6) Virtual Raw MIDI
7) Virtual Raw MIDI
8) Virtual Raw MIDI
9) Virtual Raw MIDI
10) Virtual Raw MIDI
11) Virtual Raw MIDI
12) Virtual Raw MIDI
13) Virtual Raw MIDI
14) Virtual Raw MIDI
15) Virtual Raw MIDI
16) Virtual Raw MIDI
17) Virtual Raw MIDI
18) Virtual Raw MIDI
19) Virtual Raw MIDI
20) Virtual Raw MIDI
21) Virtual Raw MIDI
22) Virtual Raw MIDI
23) Virtual Raw MIDI
24) Virtual Raw MIDI
25) Virtual Raw MIDI
26) Virtual Raw MIDI
27) Virtual Raw MIDI
28) Virtual Raw MIDI
29) Virtual Raw MIDI
30) Virtual Raw MIDI
31) Virtual Raw MIDI
32) Virtual Raw MIDI
33) Virtual Raw MIDI
34) Virtual Raw MIDI
35) Virtual Raw MIDI
36) Virtual Raw MIDI
37) Virtual Raw MIDI
38) Virtual Raw MIDI
39) Virtual Raw MIDI
40) Virtual Raw MIDI
41) Virtual Raw MIDI
42) Virtual Raw MIDI
43) Virtual Raw MIDI
44) Virtual Raw MIDI
45) Virtual Raw MIDI
46) Virtual Raw MIDI
47) Virtual Raw MIDI
48) Virtual Raw MIDI
49) Virtual Raw MIDI
50) Virtual Raw MIDI
51) Virtual Raw MIDI
52) Virtual Raw MIDI
53) Virtual Raw MIDI
54) Virtual Raw MIDI
55) Virtual Raw MIDI
56) Virtual Raw MIDI
57) Virtual Raw MIDI
58) Virtual Raw MIDI
59) Virtual Raw MIDI
60) Virtual Raw MIDI
61) Virtual Raw MIDI
62) Virtual Raw MIDI
63) Virtual Raw MIDI
128) pisound MIDI PS-3255DBQ
130) Arturia KeyStep 32
132) Arturia BeatStep

Why are there 64 devices listed, no index given, and no other details of the device at all?

When I try to connect to any of the Virtual Raw MIDI ports, UniMIDI hangs, infinitely. When I connect to the other ports, it works fine.

MIDI File IO

Hello,

Is it possible to load MIDI Files and sent the contents to an external device? If yes, how?

Thank you in advance.

No sound unless GarageBand is open

When I run the example code no sound is made When I start up garage band, sound is made.

Platform: OSX Lion with ruby 1.9.3p194

Example code................
require 'unimidi'

duration = 0.5
UniMIDI::Output.open(:first).open do |output|
output.puts(0x90, 36, 100) # note on message
sleep(duration) # wait
output.puts(0x80, 36, 100) # note off message
end

gem install unimidi fails (ruby 1.9.2/ 32-bit snow leopard)

Hello Ari!

I just got (on rvm + ruby 1.9.2-p180 + mac os x):

ERROR:  Could not find a valid gem 'unimidi' (>= 0), here is why:
Found unimidi (0.1.10), but was for platforms i686-linux ,i386-mingw32 ,java ,x86_64-darwin10.7.0

My understanding is that it's because I'm using snow leopard but in 32 bits (which seems to be the default for upgraded install, although I'm not sure).

Not a big deal, I'm going to use JRuby on this one, but wanted to leave a trace of my findings.

midi-message timing not reliable using Ruby sleep method?

Is there a more reliable way to time midi messages than the Ruby sleep method?

I have written some kind of cpu intensive logic to create beats to play but after many iterations you can feel it has slowly lost tiny fractions of tempo. I admit my code it's not optimized, but, shouldn't midi messages be synchronized through Midi Clock (or something like that?) Do you have any ideas how I can do that? Thanks.

No MIDI inputs or outputs listed OSX 10.6.8

Hi Ari,

I am fairly new to messing around with MIDI IO in general and I am basically attempting to run the output.rb in the examples directory out of the built-in speakers on my mac. I am unable to get a list of any MIDI device inputs or outputs.

In irb the following returns an empty list

@output = UniMIDI::Output.gets
Select a MIDI output...

Same thing for input. Any help would be greatly appreciated!

Thanks,
Aaron

Latency when trying to play multiple notes at the same time

Hey, me again ^_^

When I was using MIDIator, I could pass in an array of notes and it would play them all at exactly the same time. The code used in MIDIator looks a little like this:

# Note on for each note in the array.
notes.each do |note|
  output.puts 0x90, note, 100
end

# Sleep to ensure duration.
sleep(note.duration)

# Note off for each note in the array.
notes.each do |note|
  output.puts 0x80, note, 100
end

That's the code that I'm using but it's modelled from the MIDIator equivalent "play" method at: https://github.com/bleything/midiator/blob/master/lib/midiator/interface.rb

It worked perfectly in MIDIator but in unimidi I get these minuscule delays. So if I have a chord of 3 notes, I can hear each one start a split second after the previous. How do I fix this?

Can't connect virtual devices on OSX

I'm trying out micromidi on OSX and have pretty much immediately run into a problem.

Whilst physical devices (i.e. actual external devices connected to the computer) & IAC buses are being picked up fine by unimidi, virtual devices (i.e. the in/out ports exposed by other programs) are not. I know these virtual ports are working fine because they appear in Logic, Reaper, etc etc.

Looking at this blog post here
http://xmidi.com/blog/how-to-access-midi-devices-with-coremidi/
and your code here
https://github.com/arirusso/ffi-coremidi/blob/master/lib/coremidi/device.rb
it seems to me that the problem is that you are using MIDIGetDevice rather than MIDIGetSource and MIDIGetDestination.

Anyway, I understand this may not be a priority for you but I would be very grateful if you could take a look as I would really like to use micromidi for a new live performance system I am writing. If you are too busy to look at this I will just have to dive in myself but I am something of a Ruby n00b so I would definitely feel more comfortable with a solution from yourself...

OSX Lion: no output

Hi Ari!

I'm the author of niki, a DSL to write songs, which from v0.1.0 depends on Unimidi rather than Archaeopteryx. First of all, congratulations for such a great gem! And of course the FFI gems you wrote for it to work :)

Just a heads up, today I tested my gem with unimidi in a Snow Leopard machine, worked flawlessly. Now I'm on my laptop (which has Lion) and apparently the messages get sent (no error or anything), but my host program (Reason) doesn't seem to receive anything through IAC.

If I change to my gem version prior to 0.1.0, using Archaeopteryx, the IAC driver works as expected, so it can't be my midi configuration :S. In the Snow Leopard machine, it works both with Archaeopteryx and Unimidi without problem.

Do you have any machine with Lion to confirm this is not only happening in my laptop?

output.puts doesnt product sound consistently

I'm using the tutorial here: http://tx81z.blogspot.com/2011/06/unimidi-platform-independent-realtime.html

I've found that if I try running the following loop immediately after running it once, it doesnt produce any sound:

output.open do |output|

notes.each do |note|
output.puts(0x90, note, 100) # note on message
sleep(duration) # wait
output.puts(0x80, note, 100) # note off message
end

end

But if I give it a few seconds (20-30) to "catch up"...I can make sounds again...Doing individual output.puts also seems to result in similar "silent lags".

RuntimeError: midiOutOpen: Unspecified when selecting output on Windows

This happens on Windows (10, not sure if that makes a difference). Ruby version is ruby 1.9.3p448 (2013-06-27) [i386-mingw32].

irb(main):001:0> require 'unimidi'
=> true
irb(main):002:0>  @output = UniMIDI::Output.gets

Select a MIDI output...
0) Microsoft GS Wavetable Synth
> 0
RuntimeError: midiOutOpen: Unspecified
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/midi-winmm-0.1.10/lib/midi-winmm/map.rb:217:in `winmm_func'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/midi-winmm-0.1.10/lib/midi-winmm/output.rb:18:in `enable'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/unimidi-0.4.6/lib/unimidi/device.rb:121:in `open'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/unimidi-0.4.6/lib/unimidi/device.rb:49:in `gets'
        from (irb):2
        from C:/Ruby193/bin/irb:12:in `<main>'

unexpected 0x00 at beginning of SysEx message

so i've been trying to make a program so i can mess with my virus c using sysex and i'm seeing an odd issue. here's my code

require 'unimidi'

@output = UniMIDI::Output.gets

sysex_msg = [0xF0, 0x00, 0x20, 0x33, 0x01, 0x10, 0x32, 0x01, 0xF7]
@output.open{|o| o.puts(sysex_msg)}

i send that to the virus. as we all know, it's the sysex command to dump the entire A bank of the synth. i see it's sysex indicator come on.. and then nothing. I fire up midi monitor and it looks like there's an extra 0x00 on the front of the message. any ideas what could cause this?

example

No input devices for my Macbook running OSX 10.5 via SSH

I tried listing the MIDI inputs using UniMIDI::Device.all on both my Macbook Pro (running 10.6) and old Macbook (10.5), with the same USB MIDI keyboard connected.

The keyboard and two built-in MIDI sources show up on the Macbook Pro. Reading input works as expected.

Nothing shows up on the Macbook.

Could this be an issue with the older MIDI API of the OS?

jruby192 vs ruby193p0 input errors and latency on osx lion 10.7.3 and windows 7 64-bit

A loop dumping received MIDI data on JRuby 1.9.2 is returning strange data for the bottom of my controller sliders and knobs (i.e.: if I turn the knobs or pull the sliders towards zero). (Both jruby and ruby where installed via brew.):

$ jruby --1.9 -v
jruby 1.6.6 (ruby-1.9.2-p312) (2012-01-30 5673572) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_29) [darwin-x86_64-java]
$ jruby --1.9 input.rb
java
1.9.2
2012-01-30

Select a MIDI input...
0) Fast Track Ultra
1) Akai APC40
5) Real Time Sequencer
> 1
send some MIDI to your input now...
[{:data=>[176, 14, 33], :timestamp=>15042.999982833862}]
[{:data=>[176, 14, 32], :timestamp=>15138.999938964844}]
[{:data=>[176, 14, 31], :timestamp=>16249.000072479248}]
[{:data=>[176, 14, 30], :timestamp=>16311.000108718872}]
[{:data=>[176, 14, 29], :timestamp=>16497.999906539917}]
[{:data=>[176, 14, 28], :timestamp=>16584.00011062622}]
[{:data=>[176, 14, 27], :timestamp=>16696.00009918213}]
[{:data=>[176, 14, 26], :timestamp=>16854.000091552734}]
[{:data=>[176, 14, 25], :timestamp=>17042.999982833862}]
[{:data=>[176, 14, 24], :timestamp=>17094.000101089478}]
[{:data=>[176, 14, 23], :timestamp=>17194.000005722046}]
[{:data=>[176, 14, 22], :timestamp=>17332.99994468689}]
[{:data=>[176, 14, 21], :timestamp=>17473.000049591064}]
[{:data=>[176, 14, 20], :timestamp=>17614.00008201599}]
[{:data=>[176, 14, 19], :timestamp=>17703.999996185303}]
[{:data=>[176, 14, 18], :timestamp=>17785.00008583069}]
[{:data=>[176, 14, 17], :timestamp=>17884.000062942505}]
[{:data=>[176, 14, 16], :timestamp=>17983.999967575073}]
[{:data=>[0, 235, 240], :timestamp=>18134.000062942505}]
[{:data=>[0, 235, 224], :timestamp=>18394.00005340576}]
[{:data=>[0, 235, 208], :timestamp=>18575.000047683716}]
[{:data=>[0, 235, 192], :timestamp=>18834.00011062622}]
[{:data=>[0, 235, 176], :timestamp=>19184.00001525879}]
[{:data=>[0, 235, 160], :timestamp=>19283.999919891357}]
[{:data=>[0, 235, 144], :timestamp=>19533.999919891357}]
[{:data=>[0, 235, 128], :timestamp=>19927.000045776367}]
[{:data=>[0, 235, 96], :timestamp=>20043.999910354614}]
[{:data=>[0, 235, 80], :timestamp=>20184.99994277954}]
[{:data=>[0, 235, 64], :timestamp=>20394.999980926514}]
[{:data=>[0, 235, 48], :timestamp=>20555.000066757202}]
[{:data=>[0, 235, 32], :timestamp=>20694.000005722046}]
[{:data=>[0, 235, 16], :timestamp=>21114.00008201599}]
[{:data=>[0, 235], :timestamp=>21483.999967575073}]
^C
$

For comparison, ruby 1.9.3p0 running simultaneously (same behaviour if only running one or the other) -- this version also throw exception on ^C that JRuby version does not, and is quite chunky outputting received data compared to the JRuby version (I'm not sure how to measure that to prove it -- unless the number of elements in the dumped arrays is indicative?):

$ ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.3.0]
$ ruby input.rb
x86_64-darwin11.3.0
1.9.3
2011-10-30

Select a MIDI input...
0) M-Audio Fast Track Ultra
2) Akai Akai APC40
> 2
send some MIDI to your input now...
[{:data=>[176, 14, 33], :timestamp=>6656.177759170532},
 {:data=>[176, 14, 32], :timestamp=>6656.36682510376}]
[{:data=>[176, 14, 31], :timestamp=>7866.124629974365},
 {:data=>[176, 14, 30], :timestamp=>7866.4116859436035}]
[{:data=>[176, 14, 29], :timestamp=>8123.588800430298},
 {:data=>[176, 14, 28], :timestamp=>8123.771905899048}]
[{:data=>[176, 14, 27], :timestamp=>8411.648750305176},
 {:data=>[176, 14, 26], :timestamp=>8411.79871559143}]
[{:data=>[176, 14, 25], :timestamp=>8661.818742752075}]
[{:data=>[176, 14, 24], :timestamp=>8662.103652954102}]
[{:data=>[176, 14, 23], :timestamp=>8912.774801254272}]
[{:data=>[176, 14, 22], :timestamp=>8913.033962249756}]
[{:data=>[176, 14, 21], :timestamp=>9193.013668060303},
 {:data=>[176, 14, 20], :timestamp=>9193.187713623047}]
[{:data=>[176, 14, 19], :timestamp=>9430.135726928711},
 {:data=>[176, 14, 18], :timestamp=>9430.555820465088},
 {:data=>[176, 14, 17], :timestamp=>9430.671691894531}]
[{:data=>[176, 14, 16], :timestamp=>9703.298807144165},
 {:data=>[176, 14, 15], :timestamp=>9703.441858291626}]
[{:data=>[176, 14, 14], :timestamp=>10037.22882270813}]
[{:data=>[176, 14, 13], :timestamp=>10309.62586402893}]
[{:data=>[176, 14, 12], :timestamp=>10553.469896316528}]
[{:data=>[176, 14, 11], :timestamp=>10802.077770233154},
 {:data=>[176, 14, 10], :timestamp=>10802.196979522705}]
[{:data=>[176, 14, 9], :timestamp=>11152.296781539917}]
[{:data=>[176, 14, 8], :timestamp=>11542.020797729492}]
[{:data=>[176, 14, 6], :timestamp=>11765.419721603394},
 {:data=>[176, 14, 5], :timestamp=>11765.552759170532}]
[{:data=>[176, 14, 4], :timestamp=>12013.13066482544}]
[{:data=>[176, 14, 3], :timestamp=>12273.216009140015},
 {:data=>[176, 14, 2], :timestamp=>12273.362874984741}]
[{:data=>[176, 14, 1], :timestamp=>12821.009874343872}]
[{:data=>[176, 14, 0], :timestamp=>13143.155813217163}]
^C/usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/ffi-coremidi-0.1.4/lib/coremidi/source.rb:120:in `queued_messages?': Interrupt
    from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/ffi-coremidi-0.1.4/lib/coremidi/source.rb:26:in `gets'
    from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/unimidi-0.3.2/lib/unimidi/congruous_api_adapter.rb:186:in `gets'
    from /Users/sdj/Code/midi/midi.rb:39:in `block (2 levels) in poll_input'
    from /Users/sdj/Code/midi/midi.rb:38:in `loop'
    from /Users/sdj/Code/midi/midi.rb:38:in `block in poll_input'
    from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/unimidi-0.3.2/lib/unimidi/congruous_api_adapter.rb:26:in `open'
    from /Users/sdj/Code/midi/midi.rb:34:in `poll_input'
    from /Users/sdj/Code/midi/input.rb:8:in `<top (required)>'
    from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from ./input_ruby193.rb:3:in `<main>'
$

input.rb:

require 'unimidi'
require 'pp'

def poll_input(input)
  input.open do |i|

    $stdout.puts "send some MIDI to your input now..."

    loop do
      m = i.gets
      yield(m)
    end

  end
end

puts RUBY_PLATFORM, RUBY_VERSION, RUBY_RELEASE_DATE

input = UniMIDI::Input.gets

poll_input(input) do |m|
  pp m
end

This is on Lion 10.7.3 on a late 2010 Mac Book Air.

Any ideas? Am I missing something?

Let me know if you need any more info. Thanks!

question about receive midi

Hi @arirusso ,

This library is really cool!!
I´been playing with unimidi and I would like to ask you a question regarding the midi receive.

In My script , after device selection , there is a loop which receives the midi, then the data is sent over osc connection to another place.

the code is something like this:

    input = UniMIDI::Input[device_index]
    puts "selected #{device_index}"
    input.open do |input|
      $stdout.puts "send some MIDI to your input now..."
      loop do
        m = input.gets
        @osc_client.send_data(@chan, m)
        $stdout.puts(m)
      end
    end 

the @osc_client.send_data(@chan, m) method receives data from the midi input , like this
....
{:data=>[144, 60, 80], :timestamp=>393315.1948451996}
....
{:data=>[128, 60, 64], :timestamp=>394523.4229564667}
.....
....
{:data=>[144, 60, 76], :timestamp=>393315.1948451996}
....
{:data=>[128, 60, 64], :timestamp=>394523.4229564667}
.....
If you look at the data: key of the hash you will note that never receives a 0 value (at last index ), instead it always back to 64 as a Note Off , I guess, event.

the NoteOff is expresed as value 64 of the array ?

I´ve made tests in PureData, and MaxMSP and the data I get is [128, 60, 0] when note off.

Best ,

Is #gets(*args) supposed to clear buffer?

Reading the documentation I get the impression that #gets(*args) should clear the buffer while #gets_buffer(*args) doesn't clear the buffer since the documentation for the latter method mentions

Gets any messages in the buffer in the same format as Input#gets, without removing them from the buffer

However, when I use gets the buffer doesn't seem to be cleared.

require "unimidi"

input = UniMIDI::Input.gets

while true
  m = input.gets
  p m
  puts input.buffer.size
end

gives the following output:

Select a MIDI input...
0) AKAI PROFESSIONAL,LP APC MINI
> 0
[{:data=>[176, 52, 127], :timestamp=>11.573076248168945}]
1
[{:data=>[144, 35, 127], :timestamp=>4276.036977767944}]
2
[{:data=>[128, 35, 127], :timestamp=>4364.193677902222}]
3
[{:data=>[144, 28, 127], :timestamp=>4708.255052566528}]
4
[{:data=>[128, 28, 127], :timestamp=>4820.236682891846}]
5
[{:data=>[144, 44, 127], :timestamp=>5948.585033416748}]
6
[{:data=>[128, 44, 127], :timestamp=>6100.634813308716}]
7
[{:data=>[144, 44, 127], :timestamp=>6316.690921783447}]
8
[{:data=>[128, 44, 127], :timestamp=>6440.645933151245}]
9
[{:data=>[144, 28, 127], :timestamp=>6660.769701004028}]
10
[{:data=>[128, 28, 127], :timestamp=>6792.711019515991}]
11
[{:data=>[144, 21, 127], :timestamp=>6996.846914291382}]
12
[{:data=>[128, 21, 127], :timestamp=>7108.961820602417}]
13
[{:data=>[144, 37, 127], :timestamp=>7320.873022079468}]
14
[{:data=>[128, 37, 127], :timestamp=>7441.043853759766}]
15
[{:data=>[144, 36, 127], :timestamp=>7649.0068435668945}]
16
[{:data=>[128, 36, 127], :timestamp=>7721.003770828247}]
17
[{:data=>[144, 36, 127], :timestamp=>10141.655921936035}]
18
[{:data=>[128, 36, 127], :timestamp=>10245.80693244934}]
19

The buffer grows continously as more MIDI events come in despite being read by #gets. Since the documentation doesn't clearly state if the buffer should be cleared after calling the method but rather is implied by the description for #gets_buffer I am not sure if this is just unclear documentation or unintended behavior.

This is while running unimidi (0.4.6) on ruby 2.3.1p112 under Mac OS X Yosemite.

Failing to get output on Windows 7

On windows 7, with a just-installed ruby 1.9.2 and unimidi from rubygems, I get this (sample code):
require "rubygems"
require "unimidi"
output = UniMIDI::Output.use(:first)

C:/Ruby192/lib/ruby/gems/1.9.1/gems/unimidi-0.2.5-x86-mingw32/lib/unimidi/congruous_api_adapter.rb:18:in `enabled?': undefined method `enabled' for #<MIDIWinMM::Output:0x27ecd00> (NoMethodError)
    from C:/Ruby192/lib/ruby/gems/1.9.1/gems/unimidi-0.2.5-x86-mingw32/lib/unimidi/congruous_api_adapter.rb:23:in `open'
    from C:/Ruby192/lib/ruby/gems/1.9.1/gems/unimidi-0.2.5-x86-mingw32/lib/unimidi/congruous_api_adapter.rb:123:in `use_device'
    from C:/Ruby192/lib/ruby/gems/1.9.1/gems/unimidi-0.2.5-x86-mingw32/lib/unimidi/congruous_api_adapter.rb:75:in `use'
    from C:/Users/tyler/test.rb:3:in `<main>'

The example from midi-winmm's git successfully plays the notes.

My gem list:

C:\Users\tyler>gem list

*** LOCAL GEMS ***

ffi (1.0.9 x86-mingw32)
micromidi (0.0.5)
midi-eye (0.1.3)
midi-message (0.2.2)
midi-nibbler (0.1.1)
midi-winmm (0.1.9)
minitest (1.6.0)
rake (0.8.7)
rdoc (2.5.8)
unimidi (0.2.5 i386-mingw32)

undefined method `enabled?' for nil:NilClass (NoMethodError)

Hi, I'm trying to get running open-midinous on macOS Ventura and it fails on loading unimidi 0.5.1 library:

% ruby midinous.rb
/Library/Ruby/Gems/2.6.0/gems/unimidi-0.5.1/lib/unimidi/device.rb:101:in `use_device': undefined method `enabled?' for nil:NilClass (NoMethodError)
	from /Library/Ruby/Gems/2.6.0/gems/unimidi-0.5.1/lib/unimidi/device.rb:77:in `use'
	from /Users/andrei/Downloads/open-midinous-master/lib/midinous/proc_midi.rb:29:in `initialize'
	from /Users/andrei/Downloads/open-midinous-master/lib/midinous/proc_midi.rb:120:in `new'
	from /Users/andrei/Downloads/open-midinous-master/lib/midinous/proc_midi.rb:120:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /Users/andrei/Downloads/open-midinous-master/lib/midinous/init.rb:19:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	from midinous.rb:19:in `<main>'

I'm not sure if it's specific to midinous or unimid, would you please help? Sorry, I'm not an expert in Ruby and not sure where to look.

Arch Linux: No input or output devices listed

I realise that this error is similar to other existing errors but the solutions all appear to be for OSX machines, so I thought I'd open up a new issue to troubleshoot this on Arch :)

I had to install alsa-rawmidi, midi-jruby and midi-winmm to actually require the unimidi gem in my code.

Running "unimidi list" at the command line returns:

input:
output:

I'm running a software midi synth. I tried with timidity and qsynth and I get the same result with both.

Am I doing something wrong? :)

No timestamp sent with MIDI message

Is it possible to include timestamps with MIDI messages?

Ableton Live isn't consistently acknowledging messages received from UniMIDI, and I suspect timestamps would fix this.

Pointer Error when listing midi devices

Hi,

I got an error when listing midi devices :

unimidi list                                                                                                                                                                                   [15:55:29]
input:
/Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/ffi-1.1.5/lib/ffi/pointer.rb:42:in `get_string': invalid memory read at address=0x00000000000000 (FFI::NullPointerError)
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/ffi-1.1.5/lib/ffi/pointer.rb:42:in `read_string'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/ffi-coremidi-0.1.7/lib/coremidi/device.rb:23:in `initialize'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/ffi-coremidi-0.1.7/lib/coremidi/device.rb:41:in `new'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/ffi-coremidi-0.1.7/lib/coremidi/device.rb:41:in `all'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/ffi-coremidi-0.1.7/lib/coremidi/endpoint.rb:52:in `all_by_type'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/lib/unimidi/adapter/ffi-coremidi.rb:28:in `populate'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/lib/unimidi/congruous_api_adapter.rb:143:in `ensure_initialized'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/lib/unimidi/congruous_api_adapter.rb:110:in `all_by_type'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/lib/unimidi/congruous_api_adapter.rb:249:in `all'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/lib/unimidi/congruous_api_adapter.rb:55:in `list'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/lib/unimidi.rb:26:in `command'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/gems/unimidi-0.3.3/bin/unimidi:10:in `<top (required)>'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/bin/unimidi:19:in `load'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/bin/unimidi:19:in `<main>'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/bin/ruby_noexec_wrapper:14:in `eval'
    from /Users/lyset/.rvm/gems/ruby-1.9.3-p125-perf/bin/ruby_noexec_wrapper:14:in `<main>'

JACK support

Please support jack-midi. Can't see how else I could even use this library.

No input using IAC on OS X 10.6

Hi,
I've been playing around with UniMIDI and encountered a problem. UniMIDI doesn't receive messages on input.

My setup is:

  1. MidiPipe for routing and monitoring MIDI events (also checked with MIDI Patchbay),
  2. Cubase LE 5 for clock source and synthesis :),
  3. Mac OS X 10.6.8,
  4. UniMIDI 0.2.1,
  5. Ruby 1.9.2p290.

MidiPipe shows incoming events and when I hooked up Garage Band to the virtual input it was receiving messages sent from Cubase (in other words - both Cubase and GB played the same notes simultaneously), so I guess everything's OK with my setup, however UniMIDI inputs don't receive those events.

I'll be thankful for any advice.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.