480 Din-A-4-Seiten. Aufgrund der Steuerzeichen gibt es hier unter Windows Posting-Probleme, weil das Programmn
ja sofort ausführen würde bzw. teilweise ausführen würde. Ebenfalls sind Demo-Song programmiert und der Codoe.
Es ist also eine komplette DAW mit allen Features, ich behaupte sogar, besser noch als die beste die derzeit
auf dem Weltmnarkzt verkäuflich ist, weil alles noch individuell abprogrammiert werden kann.
Wie gesagt, ich hoffe, der kpomplette Code, 480 DIN-A-4-Seiten, konnte hier eingeschrieben werden,
ansonsten müssen Sie sich mit dem Begbnügen, was hier steht und evtl.auf Features verzichten.
Schgauen Sie auch nochmal im Forum
http://Outbackbrumby.Blogspot.com vorbei, da versuche ich ebenfalls, diese 480 Seiten einzupostenDAW selbst programmieren – SourceCode- Musikproduktion Songwriting
Author D.Selzer-McKenzie
group :test do
- gem "mocha"
- gem "rake"
- gem "shoulda-context"
-end
-
-gem "ffi"
13 app/server/vendor/alsa-rawmidi/LICENSE
@@ -1,13 +0,0 @@
-Copyright 2010-2014 Ari Russo
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
48 app/server/vendor/alsa-rawmidi/README.md
@@ -1,48 +0,0 @@
-# alsa-rawmidi
-
-#### Realtime MIDI IO with Ruby for Linux.
-
-Access the ALSA RawMIDI API with Ruby.
-
-Note that in the interest of allowing people on other platforms to utilize your code, you should consider using [unimidi](http://github.com/arirusso/unimidi). Unimidi is a platform independent wrapper that implements this gem and has a similar API.
-
-## Features
-
-* Simplified API
-* Input and output on multiple devices concurrently
-* Generalized handling of different MIDI Message types (including SysEx)
-* Timestamped input events
-
-## Requirements
-
-* [ffi](http://github.com/ffi/ffi)
-* libasound, libasound-dev packages
-
-## Installation
-
-If you're using Bundler, add this line to your application's Gemfile:
-
-`gem "alsa-rawmidi"`
-
-Otherwise
-
-`gem install alsa-rawmidi`
-
-## Usage
-
-* [input](http://github.com/arirusso/alsa-rawmidi/blob/master/examples/input.rb)
-* [output](http://github.com/arirusso/alsa-rawmidi/blob/master/examples/output.rb)
-
-## Documentation
-
-* [rdoc](http://rdoc.info/gems/alsa-rawmidi)
-
-## Author
-
-[Ari Russo](http://github.com/arirusso)
-
-## License
-
-Apache 2.0, See the file LICENSE
-
-Copyright (c) 2010-2014 Ari Russo
10 app/server/vendor/alsa-rawmidi/Rakefile
@@ -1,10 +0,0 @@
-require "rake"
-require "rake/testtask"
-
-Rake::TestTask.new(:test) do |t|
- t.libs << "test"
- t.test_files = FileList["test/**/*_test.rb"]
- t.verbose = true
-end
-
-task :default => [:test]
26 app/server/vendor/alsa-rawmidi/examples/input.rb
@@ -1,26 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-require "alsa-rawmidi"
-
-# Selects the first MIDI input and prints the first 10 messages it receives to standard out
-
-num_messages = 10
-
-# AlsaRawMIDI::Device.all.to_s will list your midi devices
-# or amidi -l from the command line
-
-AlsaRawMIDI::Input.first.open do |input|
-
- puts "send some MIDI to your input now..."
-
- num_messages.times do
- m = input.gets
- puts(m)
- end
-
- puts "finished"
-
-end
11 app/server/vendor/alsa-rawmidi/examples/list_devices.rb
@@ -1,11 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-# Lists all of the available MIDI devices
-
-require "alsa-rawmidi"
-require "pp"
-
-pp AlsaRawMIDI::Device.all_by_type
36 app/server/vendor/alsa-rawmidi/examples/output.rb
@@ -1,36 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-require "alsa-rawmidi"
-
-# Selects the first MIDI output and sends some arpeggiated chords to it
-
-notes = [36, 40, 43] # C E G
-octaves = 5
-duration = 0.1
-
-# AlsaRawMIDI::Device.all.to_s will list your midi devices
-# or amidi -l from the command line
-
-puts "Press Control-C to exit..."
-
-AlsaRawMIDI::Output.first.open do |output|
-
- loop do
- (0..((octaves-1)*12)).step(12) do |oct|
-
- notes.each do |note|
-
- output.puts(0x90, note + oct, 100) # note on
- sleep(duration) # wait
- output.puts(0x80, note + oct, 100) # note off
- sleep(duration)
-
- end
-
- end
- end
-
-end
13 app/server/vendor/alsa-rawmidi/examples/sysex_output.rb
@@ -1,13 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-# Sends a MIDI system exclusive message to the selected output
-
-require "alsa-rawmidi"
-
-output = AlsaRawMIDI::Output.first
-sysex_msg = [0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7]
-
-output.open { |output| output.puts(sysex_msg) }
24 app/server/vendor/alsa-rawmidi/lib/alsa-rawmidi.rb
@@ -1,24 +0,0 @@
-#
-# Modules and classes to interact with the ALSA Driver Interface
-#
-# Ari Russo
-# (c) 2010-2014
-# Licensed under Apache 2.0
-
-# libs
-require "ffi"
-
-# modules
-require "alsa-rawmidi/api"
-require "alsa-rawmidi/device"
-
-# class
-require "alsa-rawmidi/input"
-require "alsa-rawmidi/output"
-require "alsa-rawmidi/soundcard"
-
-module AlsaRawMIDI
-
- VERSION = "0.3.1"
-
-end
435 app/server/vendor/alsa-rawmidi/lib/alsa-rawmidi/api.rb
@@ -1,435 +0,0 @@
-module AlsaRawMIDI
-
- # libasound RawMIDI struct, enum and function bindings
- module API
-
- extend FFI::Library
- ffi_lib "libasound"
-
- CONSTANTS = {
- :SND_RAWMIDI_STREAM_OUTPUT => 0,
- :SND_RAWMIDI_STREAM_INPUT => 1,
- :SND_RAWMIDI_APPEND => 0x0001,
- :SND_RAWMIDI_NONBLOCK => 0x0002,
- :SND_RAWMIDI_SYNC => 0x0004
- }
-
- typedef :ulong, :SndCtlType
- typedef :ulong, :SndCtl
- typedef :ulong, :SndRawMIDI
-
- # snd_ctl
- class SndCtl < FFI::Struct
- layout :dl_handle, :pointer, # void*
- :name, :pointer, # char*
- :type, :SndCtlType,
- :ops, :pointer, # const snd_ctl_ops_t*
- :private_data, :pointer, # void*
- :nonblock, :ulong,
- :poll_fd, :ulong,
- :async_handlers, :ulong
- end
-
- # snd_ctl_card_info
- class SndCtlCardInfo < FFI::Struct
- layout :card, :int, # card number
- :pad, :int, # reserved for future (was type)
- :id, [:uchar, 16], # ID of card (user selectable)
- :driver, [:uchar, 16], # Driver name
- :name, [:uchar, 32], # Short name of soundcard
- :longname, [:uchar, 80], # name + info text about soundcard
- :reserved_, [:uchar, 16], # reserved for future (was ID of mixer)
- :mixername, [:uchar, 80], # visual mixer identification
- :components, [:uchar, 128] # card components / fine identification, delimited with one space (AC97 etc..)
- end
-
- # snd_rawmidi_info
- class SndRawMIDIInfo < FFI::Struct
- layout :device, :uint, # RO/WR (control): device number
- :subdevice, :uint, # RO/WR (control): subdevice number
- :stream, :int, # WR: stream
- :card, :int, # R: card number
- :flags, :uint, # SNDRV_RAWMIDI_INFO_XXXX
- :id, [:uchar, 64], # ID (user selectable)
- :name, [:uchar, 80], # name of device
- :subname, [:uchar, 32], # name of active or selected subdevice
- :subdevices_count, :uint,
- :subdevices_avail, :uint,
- :reserved, [:uchar, 64] # reserved for future use
- end
-
- # timespec
- class Timespec < FFI::Struct
- layout :tv_sec, :time_t, # Seconds since 00:00:00 GMT
- :tv_nsec, :long # Additional nanoseconds since
- end
-
- # snd_rawmidi_status
- class SndRawMIDIStatus < FFI::Struct
- layout :stream, :int,
- :timestamp, Timespec.by_value, # Timestamp
- :avail, :size_t, # available bytes
- :xruns, :size_t, # count of overruns since last status (in bytes)
- :reserved, [:uchar, 64] # reserved for future use
- end
-
- # Simple doubly linked list implementation
- class LinkedList < FFI::Struct
- layout :next, :pointer, # *LinkedList
- :prev, :pointer # *LinkedList
- end
-
- # snd_rawmidi
- class SndRawMIDI < FFI::Struct
- layout :card, :pointer, # *snd_card
- :list, LinkedList.by_value,
- :device, :uint, # device number
- :info_flags, :uint, # SNDRV_RAWMIDI_INFO_XXXX
- :id, [:char, 64],
- :name, [:char, 80]
- end
-
- # spinlock_t
- class Spinlock < FFI::Struct
- layout :lock, :uint
- end
-
- # wait_queue_head_t
- class WaitQueueHead < FFI::Struct
- layout :lock, Spinlock.by_value,
- :task_list, LinkedList.by_value
- end
-
- class AtomicT < FFI::Struct
- layout :counter, :int # volatile int counter
- end
-
- class Tasklet < FFI::Struct
- layout :next, :pointer, # pointer to the next tasklet in the list / void (*func) (unsigned long)
- :state, :ulong, # state of the tasklet
- :count, AtomicT.by_value, # reference counter
- :func, :pointer, # tasklet handler function / void (*func) (unsigned long)
- :data, :ulong # argument to the tasklet function
- end
-
- # snd_rawmidi_runtime
- class SndRawMIDIRuntime < FFI::Struct
- layout :drain, :uint, 1, # drain stage
- :oss, :uint, 1, # OSS compatible mode
- # midi stream buffer
- :buffer, :pointer, # uchar* / buffer for MIDI data
- :buffer_size, :size_t, # size of buffer
- :appl_ptr, :size_t, # application pointer
- :hw_ptr, :size_t, # hardware pointer
- :avail_min, :size_t, # min avail for wakeup
- :avail, :size_t, # max used buffer for wakeup
- :xruns, :size_t, # over/underruns counter
- # misc
- :lock, Spinlock.by_value,
- :sleep, WaitQueueHead.by_value,
- # event handler (new bytes, input only)
- :substream, :pointer, # void (*event)(struct snd_rawmidi_substream *substream);
- # defers calls to event [input] or ops->trigger [output]
- :tasklet, Tasklet.by_value,
- :private_data, :pointer, # void*
- :private_free, :pointer # void (*private_free)(struct snd_rawmidi_substream *substream)
- end
-
- # snd_rawmidi_params
- class SndRawMIDIParams < FFI::Struct
- layout :stream, :int,
- :buffer_size, :size_t, # queue size in bytes
- :avail_min, :size_t, # minimum avail bytes for wakeup
- :no_active_sensing, :uint, 1, # do not send active sensing byte in close()
- :reserved, [:uchar, 16] # reserved for future use
- end
-
- #
- # snd_card
- #
-
- # Try to load the driver for a card.
- attach_function :snd_card_load, [:int], :int # (int card)
- # Try to determine the next card.
- attach_function :snd_card_next, [:pointer], :int # (int* card)
- # Convert card string to an integer value.
- attach_function :snd_card_get_index, [:pointer], :int # (const char* name)
- # Obtain the card name.
- attach_function :snd_card_get_name, [:int, :pointer], :int # (int card, char **name)
- # Obtain the card long name.
- attach_function :snd_card_get_longname, [:int, :pointer], :int # (int card, char **name)
-
- #
- # snd_ctl
- #
-
- # Opens a CTL.
- attach_function :snd_ctl_open, [:pointer, :pointer, :int], :int # (snd_ctl_t **ctl, const char *name, int mode)
- # Opens a CTL using local configuration.
- attach_function :snd_ctl_open_lconf, [:pointer, :pointer, :int, :pointer], :int # (snd_ctl_t **ctl, const char *name, int mode, snd_config_t *lconf)
- # close CTL handle
- attach_function :snd_ctl_close, [:pointer], :int #(snd_ctl_t *ctl)
- # set nonblock mode
- attach_function :snd_ctl_nonblock, [:pointer, :int], :int # (snd_ctl_t *ctl, int nonblock)
- # Get card related information.
- attach_function :snd_ctl_card_info, [:pointer, :pointer], :int # (snd_ctl_t *ctl, snd_ctl_card_info_t *info)
- # Get card name from a CTL card info.
- attach_function :snd_ctl_card_info_get_name, [:pointer], :string # (const snd_ctl_card_info_t *obj) / const char*
- # Get info about a RawMidi device.
- attach_function :snd_ctl_rawmidi_info, [:SndCtl, :pointer], :int # (snd_ctl_t *ctl, snd_rawmidi_info_t *info)
- # Get next RawMidi device number.
- attach_function :snd_ctl_rawmidi_next_device, [:SndCtl, :pointer], :int # (snd_ctl_t *ctl, int *device)
-
- #
- # snd_rawmidi
- #
-
- # close RawMidi handle
- attach_function :snd_rawmidi_close, [:SndRawMIDI], :int # (snd_rawmidi_t *rmidi)
- # drain all bytes in the rawmidi I/O ring buffer
- attach_function :snd_rawmidi_drain, [:SndRawMIDI], :int # (snd_rawmidi_t *rmidi)
- # drop all bytes in the rawmidi I/O ring buffer immediately
- attach_function :snd_rawmidi_drop, [:SndRawMIDI], :int # int ( snd_rawmidi_t * rawmidi)
- # set nonblock mode
- attach_function :snd_rawmidi_nonblock, [:SndRawMIDI, :int], :int # (snd_rawmidi_t *rmidi, int nonblock)
- # Opens a new connection to the RawMidi interface.
- attach_function :snd_rawmidi_open, [:pointer, :pointer, :string, :int], :int # (snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, const char *name, int mode)
- # Opens a new connection to the RawMidi interface using local configuration.
- attach_function :snd_rawmidi_open_lconf, [:pointer, :pointer, :string, :int, :pointer], :int #(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, const char *name, int mode, snd_config_t *lconf)
- # read MIDI bytes from MIDI stream
- attach_function :snd_rawmidi_read, [:SndRawMIDI, :pointer, :size_t], :ssize_t # (snd_rawmidi_t *rmidi, void *buffer, size_t size)
- # write MIDI bytes to MIDI stream
- attach_function :snd_rawmidi_write, [:SndRawMIDI, :ulong, :size_t], :ssize_t # (snd_rawmidi_t *rmidi, const void *buffer, size_t size)
-
- #
- # snd_rawmidi_info
- #
-
- enum :snd_rawmidi_stream, [
- "SND_RAWMIDI_STREAM_OUTPUT", 0,
- "SND_RAWMIDI_STREAM_INPUT", 1,
- "SND_RAWMIDI_STREAM_LAST", 1
- ]
-
- # get information about RawMidi handle
- attach_function :snd_rawmidi_info, [:pointer, :pointer], :int # (snd_rawmidi_t *rmidi, snd_rawmidi_info_t *info)
- # get rawmidi count of subdevices
- attach_function :snd_rawmidi_info_get_subdevices_count, [:pointer], :uint # (const snd_rawmidi_info_t *obj)
- # set rawmidi device number
- attach_function :snd_rawmidi_info_set_device, [:pointer, :uint], :void # (snd_rawmidi_info_t *obj, unsigned int val)
- # set rawmidi subdevice number
- attach_function :snd_rawmidi_info_set_subdevice, [:pointer, :uint], :void # (snd_rawmidi_info_t *obj, unsigned int val)
- # set rawmidi stream identifier
- attach_function :snd_rawmidi_info_set_stream, [:pointer, :snd_rawmidi_stream], :void # (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val)
- # get size of the snd_rawmidi_info_t structure in bytes
- attach_function :snd_rawmidi_info_sizeof, [], :size_t # (void)
-
- #
- # misc
- #
-
- # Convert an error code to a string
- attach_function :snd_strerror, [:int], :string # (int errnum) / const char*
- # Frees the global configuration tree in snd_config.
- attach_function :snd_config_update_free_global, [], :int # (void)
-
- # Wrapper for ALSA methods dealing with input
- module Input
-
- BUFFER_SIZE = 256
-
- extend self
-
- # Open the output with the given ID
- # @param [Fixnum] id
- # @return [Fixnum]
- def open(id)
- API::Device.open(id) do |pointer|
- API.snd_rawmidi_open(pointer, nil, id, API::CONSTANTS[:SND_RAWMIDI_NONBLOCK])
- end
- end
-
- # Get the next bytes from the buffer
- # @return [String]
- def poll(handle)
- buffer = FFI::MemoryPointer.new(:uint8, BUFFER_SIZE)
- if (err = API.snd_rawmidi_read(handle, buffer, BUFFER_SIZE)) < 0
- raise "Can't read MIDI input: #{API.snd_strerror(err)}" unless err.eql?(-11)
- end
- # Upon success, err is positive and equal to the number of bytes read
- # into the buffer.
- if err > 0
- bytes = buffer.get_bytes(0,err).unpack("a*").first.unpack("H*")
- bytes.first.upcase
- end
- end
-
- end
-
- # Wrapper for ALSA methods dealing with output
- module Output
-
- extend self
-
- # Send the given MIDI data to the output with the given handle
- # @param [Fixnum] handle
- # @param [Array
- # @return [Boolean]
- def puts(handle, data)
- format = "C" * data.size
- pointer = FFI::MemoryPointer.new(data.size)
- bytes = pointer.put_bytes(0, data.pack(format))
-
- API.snd_rawmidi_write(handle, bytes.to_i, data.size)
- API.snd_rawmidi_drain(handle)
- true
- end
-
- # Open the output with the given ID
- # @param [Fixnum] id
- # @return [Fixnum]
- def open(id)
- API::Device.open(id) do |pointer|
- API.snd_rawmidi_open(nil, pointer, id, 0)
- end
- end
-
- end
-
- # Wrapper for ALSA methods dealing with devices
- module Device
-
- extend self
-
- # @param [Fixnum] id
- # @param [Symbol] direction
- # @return [SndCtlCardInfo]
- def get_info(id, direction)
- stream_key = case direction
- when :input then :SND_RAWMIDI_STREAM_INPUT
- when :output then :SND_RAWMIDI_STREAM_OUTPUT
- end
- stream = API::CONSTANTS[stream_key]
- info = API::SndRawMIDIInfo.new
- API.snd_rawmidi_info_set_device(info.pointer, id)
- API.snd_rawmidi_info_set_stream(info.pointer, stream)
- info
- end
-
- # Close the device with the given handle
- # @param [Fixnum] handle
- # @return [Boolean]
- def close(handle)
- API.snd_rawmidi_drain(handle)
- API.snd_rawmidi_close(handle)
- true
- end
-
- # Open the device with the given id
- # @param [Fixnum] id
- # @param [Proc] block
- # @return [Fixnum]
- def open(id, &block)
- handle_pointer = FFI::MemoryPointer.new(FFI.type_size(:int))
- yield(handle_pointer)
- handle_pointer.read_int
- end
-
- end
-
- # Wrapper for ALSA methods dealing with the soundcard and subdevices
- module Soundcard
-
- extend self
-
- # @param [SndCtlCardInfo] info
- # @return [Fixnum]
- def get_subdevice_count(info)
- subdev_count = API.snd_rawmidi_info_get_subdevices_count(info.pointer)
- subdev_count = 0 if subdev_count > 32
- subdev_count
- end
-
- # @param [Fixnum, String] device_num
- # @param [Fixnum] subdev_count
- # @param [Fixnum] id
- # @return [String]
- def get_subdevice_id(soundcard_id, device_id, subdev_count, id)
- ext = (subdev_count > 1) ? ",#{id}" : ''
- name = API::Soundcard.get_name(soundcard_id)
- "#{name},#{device_id.to_s}#{ext}"
- end
-
- # @param [SndCtlCardInfo] info
- # @param [Fixnum] id
- # @param [Fixnum] handle
- # @return [Boolean]
- def valid_subdevice?(info, id, handle)
- API.snd_rawmidi_info_set_subdevice(info.pointer, id)
- API.snd_ctl_rawmidi_info(handle, info.pointer) >= 0
- end
-
- # @param [Fixnum] soundcard_id
- # @param [Fixnum] device_id
- # @param [Symbol] direction
- # @param [Proc] block
- # @return [Array
# MIDIEndpointRef MIDIGetDestination(ItemCount destIndex0);
- attach_function :MIDIGetNumberOfDestinations, [], :ItemCount
-
- # ItemCount MIDIGetNumberOfDevices();
- attach_function :MIDIGetNumberOfDevices, [], :ItemCount
-
- # MIDIEndpointRef MIDIEntityGetDestination(MIDIEntityRef entity, ItemCount destIndex0);
- attach_function :MIDIGetDestination, [:int], :pointer
-
- #extern OSStatus MIDIEndpointDispose( MIDIEndpointRef endpt );
- attach_function :MIDIEndpointDispose, [:MIDIEndpointRef], :OSStatus
-
- # MIDIEndpointRef MIDIEntityGetDestination( MIDIEntityRef entity, ItemCount destIndex0 );
- attach_function :MIDIEntityGetDestination, [:MIDIEntityRef, :int], :MIDIEndpointRef
-
- # ItemCount MIDIEntityGetNumberOfDestinations (MIDIEntityRef entity);
- attach_function :MIDIEntityGetNumberOfDestinations, [:MIDIEntityRef], :ItemCount
-
- # ItemCount MIDIEntityGetNumberOfSources (MIDIEntityRef entity);
- attach_function :MIDIEntityGetNumberOfSources, [:MIDIEntityRef], :ItemCount
-
- # MIDIEndpointRef MIDIEntityGetSource (MIDIEntityRef entity, ItemCount sourceIndex0);
- attach_function :MIDIEntityGetSource, [:MIDIEntityRef, :ItemCount], :MIDIEndpointRef
-
- # MIDIDeviceRef MIDIGetDevice(ItemCount deviceIndex0);
- attach_function :MIDIGetDevice, [:ItemCount], :MIDIDeviceRef
-
- # extern OSStatus MIDIInputPortCreate( MIDIClientRef client, CFStringRef portName,
- # MIDIReadProc readProc, void * refCon, MIDIPortRef * outPort );
- attach_function :MIDIInputPortCreate, [:MIDIClientRef, :CFStringRef, :MIDIReadProc, :pointer, :MIDIPortRef], :OSStatus
-
- # extern OSStatus MIDIObjectGetIntegerProperty( MIDIObjectRef obj, CFStringRef propertyID, SInt32 * outValue );
- attach_function :MIDIObjectGetIntegerProperty, [:MIDIObjectRef, :CFStringRef, :pointer], :OSStatus
-
- # OSStatus MIDIObjectGetStringProperty (MIDIObjectRef obj, CFStringRef propertyID, CFStringRef *str);
- attach_function :MIDIObjectGetStringProperty, [:MIDIObjectRef, :CFStringRef, :pointer], :OSStatus
-
- # extern OSStatus MIDIOutputPortCreate( MIDIClientRef client, CFStringRef portName, MIDIPortRef * outPort );
- attach_function :MIDIOutputPortCreate, [:MIDIClientRef, :CFStringRef, :pointer], :int
-
- # (MIDIPacket*) MIDIPacketListInit(MIDIPacketList *pktlist);
- attach_function :MIDIPacketListInit, [:pointer], :pointer
-
- #extern OSStatus MIDIPortConnectSource( MIDIPortRef port, MIDIEndpointRef source, void * connRefCon )
- attach_function :MIDIPortConnectSource, [:MIDIPortRef, :MIDIEndpointRef, :pointer], :OSStatus
-
- #extern OSStatus MIDIPortDisconnectSource( MIDIPortRef port, MIDIEndpointRef source );
- attach_function :MIDIPortDisconnectSource, [:MIDIPortRef, :MIDIEndpointRef], :OSStatus
-
- #extern OSStatus MIDIPortDispose(MIDIPortRef port );
- attach_function :MIDIPortDispose, [:MIDIPortRef], :OSStatus
-
- #extern OSStatus MIDISend(MIDIPortRef port,MIDIEndpointRef dest,const MIDIPacketList *pktlist);
- attach_function :MIDISend, [:MIDIPortRef, :MIDIEndpointRef, :pointer], :int
-
- #OSStatus MIDISendSysex(MIDISysexSendRequest *request);
- attach_function :MIDISendSysex, [:pointer], :int
-
- # extern MIDIPacket * MIDIPacketListAdd( MIDIPacketList * pktlist, ByteCount listSize,
- # MIDIPacket * curPacket, MIDITimeStamp time,
- # ByteCount nData, const Byte * data)
- if X86_64
- attach_function :MIDIPacketListAdd, [:pointer, :int, :pointer, :int, :int, :pointer], :pointer
- else
- attach_function :MIDIPacketListAdd, [:pointer, :int, :pointer, :int, :int, :int, :pointer], :pointer
- end
-
- module CF
-
- extend FFI::Library
- ffi_lib '/System/Library/Frameworks/CoreFoundation.framework/Versions/Current/CoreFoundation'
-
- typedef :pointer, :CFStringRef
- typedef :long, :CFIndex
- enum :CFStringEncoding, [ :kCFStringEncodingUTF8, 0x08000100 ]
-
- # CFString* CFStringCreateWithCString( ?, CString, encoding)
- attach_function :CFStringCreateWithCString, [:pointer, :string, :int], :pointer
- # CString* CFStringGetCStringPtr(CFString*, encoding)
- attach_function :CFStringGetCStringPtr, [:pointer, :int], :pointer
-
- # CFIndex CFStringGetLength(CFStringRef theString);
- attach_function :CFStringGetLength, [ :CFStringRef ], :CFIndex
-
- # CFIndex CFStringGetMaximumSizeForEncoding(CFIndex length, CFStringEncoding encoding);
- attach_function :CFStringGetMaximumSizeForEncoding, [ :CFIndex, :CFStringEncoding ], :long
-
- # Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding);
- attach_function :CFStringGetCString, [ :CFStringRef, :pointer, :CFIndex, :CFStringEncoding ], :bool
-
- # void CFRelease (CFTypeRef cf);
- attach_function :CFRelease, [ :pointer ], :void
-
- end
-
- module HostTime
- extend FFI::Library
- ffi_lib '/System/Library/Frameworks/CoreAudio.framework/Versions/Current/CoreAudio'
-
- # UInt64 AudioConvertHostTimeToNanos(UInt64 IO)
- attach_function :AudioConvertHostTimeToNanos, [:uint64], :uint64
- end
-
- end
-
-end
146 app/server/vendor/ffi-coremidi/lib/coremidi/destination.rb
@@ -1,146 +0,0 @@
-module CoreMIDI
-
- # Output/Destination endpoint class
- class Destination
-
- include Endpoint
-
- attr_reader :entity
-
- # Close this output
- # @return [Boolean]
- def close
- if @enabled
- @enabled = false
- true
- else
- false
- end
- end
-
- # Send a MIDI message comprised of a String of hex digits
- # @param [String] data A string of hex digits eg "904040"
- # @return [Boolean]
- def puts_s(data)
- data = data.dup
- bytes = []
- until (str = data.slice!(0,2)).eql?("")
- bytes << str.hex
- end
- puts_bytes(*bytes)
- true
- end
- alias_method :puts_bytestr, :puts_s
- alias_method :puts_hex, :puts_s
-
- # Send a MIDI message comprised of numeric bytes
- # @param [*Fixnum] data Numeric bytes eg 0x90, 0x40, 0x40
- # @return [Boolean]
- def puts_bytes(*data)
- type = sysex?(data) ? :sysex : :small
- bytes = API.get_midi_packet(data)
- send("puts_#{type.to_s}", bytes, data.size)
- true
- end
-
- # Send a MIDI message of indeterminate type
- # @param [*Array
- # @return [Boolean]
- def puts(*args)
- case args.first
- when Array then args.each { |arg| puts(*arg) }
- when Fixnum then puts_bytes(*args)
- when String then puts_bytestr(*args)
- end
- end
- alias_method :write, :puts
-
- # Enable this device
- # @return [Destination]
- def enable(options = {}, &block)
- @enabled = true unless @enabled
- if block_given?
- begin
- yield(self)
- ensure
- close
- end
- end
- self
- end
- alias_method :open, :enable
- alias_method :start, :enable
-
- # Shortcut to the first output endpoint available
- # @return [Destination]
- def self.first
- Endpoint.first(:destination)
- end
-
- # Shortcut to the last output endpoint available
- # @return [Destination]
- def self.last
- Endpoint.last(:destination)
- end
-
- # All output endpoints
- # @return [Array
- def self.all
- Endpoint.all_by_type[:destination]
- end
-
- protected
-
- # Base initialization for this endpoint -- done whether or not the endpoint is enabled to
- # check whether it is truly available for use
- # @return [Boolean]
- def connect
- client_error = enable_client
- port_error = initialize_port
- @resource = API.MIDIEntityGetDestination( @entity.resource, @resource_id )
- !@resource.address.zero? && client_error.zero? && port_error.zero?
- end
- alias_method :connect?, :connect
-
- private
-
- # Output a short MIDI message
- def puts_small(bytes, size)
- packet_list = API.get_midi_packet_list(bytes, size)
- API.MIDISend(@handle, @resource, packet_list)
- true
- end
-
- # Output a System Exclusive MIDI message
- def puts_sysex(bytes, size)
- request = API::MIDISysexSendRequest.new
- request[:destination] = @resource
- request[:data] = bytes
- request[:bytes_to_send] = size
- request[:complete] = 0
- request[:completion_proc] = SysexCompletionCallback
- request[:completion_ref_con] = request
- API.MIDISendSysex(request)
- true
- end
-
- SysexCompletionCallback =
- API.get_callback([:pointer]) do |sysex_request_ptr|
- # this isn't working for some reason. as of now, it's not needed though
- end
-
- # Initialize a coremidi port for this endpoint
- def initialize_port
- port = API.create_midi_output_port(@client, @resource_id, @name)
- @handle = port[:handle]
- port[:error]
- end
-
- # Is the given data a MIDI sysex message?
- def sysex?(data)
- data.first.eql?(0xF0) && data.last.eql?(0xF7)
- end
-
- end
-
-end
115 app/server/vendor/ffi-coremidi/lib/coremidi/device.rb
@@ -1,115 +0,0 @@
-module CoreMIDI
-
- # A MIDI device may have multiple logically distinct sub-components. For example, one device may
- # encompass a MIDI synthesizer and a pair of MIDI ports, both addressable via a USB port. Each
- # such element of a device is called a MIDI entity.
- #
- # https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html
- class Device
-
- attr_reader :entities,
- :id, # Unique Numeric id
- :name # Device name from coremidi
-
- # @param [Fixnum] id The ID for the device
- # @param [Object] device_pointer The underlying device pointer
- # @param [Hash] options
- # @option options [Boolean] :include_offline Whether to include offline entities (default: false)
- def initialize(id, device_pointer, options = {})
- @id = id
- @resource = device_pointer
- @entities = []
- populate(options)
- end
-
- # Endpoints for this device
- # @return [Array
- def endpoints
- endpoints = { :source => [], :destination => [] }
- endpoints.keys.each do |key|
- endpoint_group = entities.map { |entity| entity.endpoints[key] }.flatten
- endpoints[key] += endpoint_group
- end
- endpoints
- end
-
- # Assign all of this Device's endpoints an consecutive local id
- # @param [Integer] last_id The highest already used endpoint ID
- # @return [Integer] The highest used endpoint ID after populating this device's endpoints
- def populate_endpoint_ids(last_id)
- id = 0
- entities.each { |entity| id += entity.populate_endpoint_ids(id + last_id) }
- id
- end
-
- # All cached devices
- # @param [Hash] options The options to select devices with
- # @option options [Boolean] :cache If false, the device list will never be cached. This would be useful if one needs to alter the device list (e.g. plug in a USB MIDI interface) while their program is running.
- # @option options [Boolean] :include_offline If true, devices marked offline by coremidi will be included in the list
- # @return [Array
- def self.all(options = {})
- use_cache = options[:cache] || true
- include_offline = options[:include_offline] || false
- if !populated? || !use_cache
- @devices = []
- counter = 0
- while !(device_pointer = API.MIDIGetDevice(counter)).null?
- device = new(counter, device_pointer, :include_offline => include_offline)
- @devices << device
- counter += 1
- end
- populate_endpoint_ids
- end
- @devices
- end
-
- # Refresh the Device cache. This is needed if, for example a USB MIDI device is plugged in while the program is running
- # @return [Array
- def self.refresh
- @devices.clear
- @devices
- end
-
- # Has the device list been populated?
- def self.populated?
- !@devices.nil? && !@devices.empty?
- end
-
- private
-
- # Populate the device name
- def populate_name
- @name = API.get_string(@resource, "name")
- raise RuntimeError.new("Can't get device name") unless @name
- end
-
- # All of the endpoints for all devices a consecutive local id
- def self.populate_endpoint_ids
- counter = 0
- all.each { |device| counter += device.populate_endpoint_ids(counter) }
- counter
- end
-
- # Populates the entities for this device. These entities are in turn used to gather the endpoints.
- # @param [Hash] options
- # @option options [Boolean] :include_offline Whether to include offline entities (default: false)
- # @return [Fixnum] The number of entities populated
- def populate_entities(options = {})
- include_if_offline = options[:include_offline] || false
- i = 0
- while !(entity_pointer = API.MIDIDeviceGetEntity(@resource, i)).null?
- @entities << Entity.new(entity_pointer, :include_offline => include_if_offline)
- i += 1
- end
- i
- end
-
- # Populate the instance
- def populate(options = {})
- populate_name
- populate_entities(:include_offline => options[:include_offline])
- end
-
- end
-
-end
106 app/server/vendor/ffi-coremidi/lib/coremidi/endpoint.rb
@@ -1,106 +0,0 @@
-module CoreMIDI
-
- # A MIDI source or destination, owned by an entity.
- module Endpoint
-
- extend Forwardable
-
- attr_reader :enabled, # has the endpoint been initialized?
- :entity, # unique local Numeric id of the endpoint
- :id,
- :resource_id, # :input or :output
- :type
-
- def_delegators :entity, :manufacturer, :model, :name
-
- alias_method :enabled?, :enabled
-
- # @param [Fixnum] resource_id
- # @param [Entity] entity
- def initialize(resource_id, entity)
- @entity = entity
- @resource_id = resource_id
- @type = get_type
- @enabled = false
- end
-
- # Is this endpoint online?
- # @return [Boolean]
- def online?
- @entity.online? && connect?
- end
-
- # Set the id for this endpoint (the id is immutable)
- # @param [Fixnum] val
- # @return [Fixnum]
- def id=(id)
- @id ||= id
- end
-
- # Select the first endpoint of the specified type
- # @return [Destination, Source]
- def self.first(type)
- all_by_type[type].first
- end
-
- # Select the last endpoint of the specified type
- # @return [Destination, Source]
- def self.last(type)
- all_by_type[type].last
- end
-
- # All source endpoints
- # @return [Array]
- def self.sources
- Device.all.map { |d| d.endpoints[:source] }.flatten
- end
-
- # All destination endpoints
- # @return [Array
- def self.destinations
- Device.all.map { |d| d.endpoints[:destination] }.flatten
- end
-
- # A Hash of :source and :destination endpoints
- # @return [Hash]
- def self.all_by_type
- {
- :source => sources,
- :destination => destinations
- }
- end
-
- # All endpoints of both types
- # @return [Array
- def self.all
- Device.all.map(&:endpoints).flatten
- end
-
- # Get the class for the given endpoint type name
- # @param [Symbol] type The endpoint type eg :source, :destination
- # @return [Class] eg Source, Destination
- def self.get_class(type)
- case type
- when :source then Source
- when :destination then Destination
- end
- end
-
- protected
-
- # Constructs the endpoint type (eg source, destination) for easy consumption
- def get_type
- class_name = self.class.name.split('::').last
- class_name.downcase.to_sym
- end
-
- # Enables the coremidi MIDI client that will go with this endpoint
- def enable_client
- client = API.create_midi_client(@resource_id, @name)
- @client = client[:resource]
- client[:error]
- end
-
- end
-
-end
116 app/server/vendor/ffi-coremidi/lib/coremidi/entity.rb
@@ -1,116 +0,0 @@
-module CoreMIDI
-
- # A MIDI entity can have any number of MIDI endpoints, each of which is a source or destination
- # of a 16-channel MIDI stream. By grouping a device's endpoints into entities, the system has
- # enough information for an application to make reasonable default assumptions about how to
- # communicate in a bi-directional manner with each entity, as is necessary in MIDI librarian
- # applications.
- #
- # https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html
- class Entity
-
- attr_reader :endpoints,
- :manufacturer,
- :model,
- :name,
- :resource
-
- # @param [FFI::Pointer] resource A pointer to the underlying entity
- # @param [Hash] options
- # @option options [Boolean] :include_offline Include offline endpoints in the list
- def initialize(resource, options = {})
- @endpoints = {
- :source => [],
- :destination => []
- }
- @resource = resource
- populate(options)
- end
-
- # Assign all of this Entity's endpoints an consecutive local id
- # @param [Fixnum] starting_id
- # @return [Fixnum]
- def populate_endpoint_ids(starting_id)
- counter = 0
- @endpoints.values.flatten.each do |endpoint|
- endpoint.id = counter + starting_id
- counter += 1
- end
- counter
- end
-
- # Is the entity online?
- # @return [Boolean]
- def online?
- get_int(:offline) == 0
- end
-
- private
-
- # Construct a display name for the entity
- # @return [String]
- def get_name
- "#{@manufacturer} #{@model}"
- end
-
- # Populate endpoints of a specified type for this entity
- # @param [Symbol] type The endpoint type eg :source, :destination
- # @param [Hash] options
- # @option options [Boolean] :include_offline Include offline endpoints in the list
- # @return [Fixnum]
- def populate_endpoints_by_type(type, options = {})
- endpoint_class = Endpoint.get_class(type)
- num_endpoints = number_of_endpoints(type)
- (0..num_endpoints).each do |i|
- endpoint = endpoint_class.new(i, self)
- if endpoint.online? || options[:include_offline]
- @endpoints[type] << endpoint
- end
- end
- @endpoints[type].size
- end
-
- # Populate the endpoints for this entity
- # @param [Hash] options
- # @option options [Boolean] :include_offline Include offline endpoints in the list
- # @return [Fixnum]
- def populate_endpoints(options = {})
- @endpoints.keys.map { |type| populate_endpoints_by_type(type, options) }.reduce(&:+)
- end
-
- # The number of endpoints for this entity
- # @param [Symbol] type The endpoint type eg :source, :destination
- def number_of_endpoints(type)
- case type
- when :source then API.MIDIEntityGetNumberOfSources(@resource)
- when :destination then API.MIDIEntityGetNumberOfDestinations(@resource)
- end
- end
-
- # A CFString property from the underlying entity
- # @param [Symbol, String] name The property name
- # @return [String, nil]
- def get_string(name)
- API.get_string(@resource, name)
- end
-
- # An Integer property from the underlying entity
- # @param [Symbol, String] name The property name
- # @return [Fixnum, nil]
- def get_int(name)
- API.get_int(@resource, name)
- end
-
- # Populate the entity properties from the underlying resource
- # @param [Hash] options
- # @option options [Boolean] :include_offline Include offline endpoints in the list
- def populate(options = {})
- @manufacturer = get_string(:manufacturer)
- @model = get_string(:model)
- @name = get_name
- populate_endpoints(options)
- end
-
- end
-
-end
245 app/server/vendor/ffi-coremidi/lib/coremidi/source.rb
@@ -1,245 +0,0 @@
-module CoreMIDI
-
- # Input/Source endpoint class
- class Source
-
- include Endpoint
-
- attr_reader :buffer
-
- #
- # An array of MIDI event hashes as such:
- # [
- # { :data => [144, 60, 100], :timestamp => 1024 },
- # { :data => [128, 60, 100], :timestamp => 1100 },
- # { :data => [144, 40, 120], :timestamp => 1200 }
- # ]
- #
- # The data is an array of Numeric bytes
- # The timestamp is the number of millis since this input was enabled
- #
- # @return [Array
- def gets
- until queued_messages?
- # per https://github.com/arirusso/unimidi/issues/20#issuecomment-44761318
- sleep(0.0001) # patch to prevent 100% CPU issue with some midi controllers
- end
- messages = queued_messages
- @pointer = @buffer.length
- messages
- end
- alias_method :read, :gets
-
- # Same as Source#gets except that it returns message data as string of hex
- # digits as such:
- # [
- # { :data => "904060", :timestamp => 904 },
- # { :data => "804060", :timestamp => 1150 },
- # { :data => "90447F", :timestamp => 1300 }
- # ]
- #
- # @return [Array
- def gets_s
- messages = gets
- messages.each do |message|
- message[:data] = TypeConversion.numeric_bytes_to_hex_string(message[:data])
- end
- messages
- end
- alias_method :gets_bytestr, :gets_s
-
- # Enable this the input for use; can be passed a block
- # @return [Source]
- def enable(options = {}, &block)
- @enabled = true unless @enabled
- if block_given?
- begin
- yield(self)
- ensure
- close
- end
- end
- self
- end
- alias_method :open, :enable
- alias_method :start, :enable
-
- # Close this input
- # @return [Boolean]
- def close
- #error = API.MIDIPortDisconnectSource( @handle, @resource )
- #raise "MIDIPortDisconnectSource returned error code #{error}" unless error.zero?
- #error = API.MIDIClientDispose(@handle)
- #raise "MIDIClientDispose returned error code #{error}" unless error.zero?
- #error = API.MIDIPortDispose(@handle)
- #raise "MIDIPortDispose returned error code #{error}" unless error.zero?
- #error = API.MIDIEndpointDispose(@resource)
- #raise "MIDIEndpointDispose returned error code #{error}" unless error.zero?
- if @enabled
- @enabled = false
- true
- else
- false
- end
- end
-
- # Shortcut to the first available input endpoint
- # @return [Source]
- def self.first
- Endpoint.first(:source)
- end
-
- # Shortcut to the last available input endpoint
- # @return [Source]
- def self.last
- Endpoint.last(:source)
- end
-
- # All input endpoints
- # @return [Array]
- def self.all
- Endpoint.all_by_type[:source]
- end
-
- protected
-
- # Base initialization for this endpoint -- done whether or not the endpoint is enabled to check whether
- # it is truly available for use
- def connect
- enable_client
- initialize_port
- @resource = API.MIDIEntityGetSource(@entity.resource, @resource_id)
- error = API.MIDIPortConnectSource(@handle, @resource, nil )
- initialize_buffer
- @sysex_buffer = []
- @start_time = Time.now.to_f
-
- error.zero?
- end
- alias_method :connect?, :connect
-
- private
-
- # Add a single message to the buffer
- # @param [Array
- # @param [Float] timestamp The system float timestamp
- # @return [Array
- def enqueue_message(bytes, timestamp)
- if bytes.first.eql?(0xF0) || !@sysex_buffer.empty?
- @sysex_buffer += bytes
- if bytes.last.eql?(0xF7)
- bytes = @sysex_buffer.dup
- @sysex_buffer.clear
- end
- end
- @buffer << get_message_formatted(bytes, timestamp) if @sysex_buffer.empty?
- @buffer
- end
-
- # New MIDI messages from the queue
- def queued_messages
- @buffer.slice(@pointer, @buffer.length - @pointer)
- end
-
- # Are there new MIDI messages in the queue?
- def queued_messages?
- @pointer < @buffer.length
- end
-
- # The callback fired by coremidi when new MIDI messages are in the buffer
- def get_event_callback
- Proc.new do |new_packets, refCon_ptr, connRefCon_ptr|
- begin
- # p "packets received: #{new_packets[:numPackets]}"
- timestamp = Time.now.to_f
- messages = get_messages(new_packets)
- messages.each { |message| enqueue_message(message, timestamp) }
- rescue Exception => exception
- Thread.main.raise(exception)
- end
- end
- end
-
- # Get MIDI messages from the given CoreMIDI packet list
- # @param [API::MIDIPacketList] new_packets The packet list
- # @return [Array
- def get_messages(packet_list)
- count = packet_list[:numPackets]
- first = packet_list[:packet][0]
- data = first[:data].to_a
- messages = []
- messages << data.slice!(0, first[:length])
- (count - 1).times do |i|
- length_index = find_next_length_index(data)
- message_length = data[length_index]
- unless message_length.nil?
- packet_start_index = length_index + 2
- packet_end_index = packet_start_index + message_length
- if data.length >= packet_end_index + 1
- packet = data.slice!(0..packet_end_index)
- message = packet.slice(packet_start_index, message_length)
- messages << message
- end
- end
- end
- messages
- end
-
- # Get the next index for "length" from the blob of MIDI data
- # @param [Array
- # @return [Fixnum]
- def find_next_length_index(data)
- last_is_zero = false
- data.each_with_index do |num, i|
- if num.zero?
- if last_is_zero
- return i + 1
- else
- last_is_zero = true
- end
- else
- last_is_zero = false
- end
- end
- end
-
- # Timestamp for a received MIDI message
- # @return [Fixnum]
- def timestamp(now)
- (now - @start_time) * 1000
- end
-
- # Give a message its timestamp and package it in a Hash
- # @return [Hash]
- def get_message_formatted(raw, time)
- {
- :data => raw,
- :timestamp => timestamp(time)
- }
- end
-
- # Initialize a coremidi port for this endpoint
- # @return [Boolean]
- def initialize_port
- @callback = get_event_callback
- port = API.create_midi_input_port(@client, @resource_id, @name, @callback)
- @handle = port[:handle]
- raise "MIDIInputPortCreate returned error code #{port[:error]}" unless port[:error].zero?
- true
- end
-
- # Initialize the MIDI message buffer
- # @return [Boolean]
- def initialize_buffer
- @pointer = 0
- @buffer = []
- def @buffer.clear
- super
- @pointer = 0
- end
- true
- end
-
- end
-
-end
21 app/server/vendor/ffi-coremidi/lib/coremidi/type_conversion.rb
@@ -1,21 +0,0 @@
-module CoreMIDI
-
- # Helper for convertig MIDI data
- module TypeConversion
-
- extend self
-
- # Convert an array of numeric byes to a hex string (e.g. [0x90, 0x40, 0x40] becomes "904040")
- # @param [Array
- # @return [String]
- def numeric_bytes_to_hex_string(bytes)
- string_bytes = bytes.map do |byte|
- str = byte.to_s(16).upcase
- str = "0" + str if byte < 16
- str
- end
- string_bytes.join
- end
-
- end
-end
58 app/server/vendor/ffi-coremidi/test/helper.rb
@@ -1,58 +0,0 @@
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-require "test/unit"
-require "mocha/test_unit"
-require "shoulda-context"
-require "coremidi"
-
-module TestHelper
-
- def self.select_devices
- $test_device ||= {}
- { :input => CoreMIDI::Source.all, :output => CoreMIDI::Destination.all }.each do |type, devs|
- puts ""
- puts "select an #{type.to_s}..."
- while $test_device[type].nil?
- devs.each do |device|
- puts "#{device.id}: #{device.name}"
- end
- selection = $stdin.gets.chomp
- if selection != ""
- selection = selection.to_i
- $test_device[type] = devs.find { |d| d.id == selection }
- puts "selected #{selection} for #{type.to_s}" unless $test_device[type]
- end
- end
- end
- end
-
- def bytestrs_to_ints(arr)
- data = arr.map { |m| m[:data] }.join
- output = []
- until (bytestr = data.slice!(0,2)).eql?("")
- output << bytestr.hex
- end
- output
- end
-
- # some MIDI messages
- VariousMIDIMessages = [
- [0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7], # SysEx
- [0x90, 100, 100], # note on
- [0x90, 43, 100], # note on
- [0x90, 76, 100], # note on
- [0x90, 60, 100], # note on
- [0x80, 100, 100] # note off
- ]
-
- # some MIDI messages
- VariousMIDIByteStrMessages = [
- "F04110421240007F0041F7", # SysEx
- "906440", # note on
- "804340" # note off
- ]
-
-end
-
-TestHelper.select_devices
42 app/server/vendor/ffi-coremidi/test/input_buffer_test.rb
@@ -1,42 +0,0 @@
-require "helper"
-
-class InputBufferTest < Test::Unit::TestCase
-
- context "CoreMIDI" do
-
- setup do
- sleep(1)
- end
-
- context "Source#buffer" do
-
- setup do
- @messages = TestHelper::VariousMIDIMessages
- @messages_arr = @messages.inject { |a,b| a+b }.flatten
- @received_arr = []
- @pointer = 0
-
- @output = $test_device[:output].open
- @input = $test_device[:input].open
- @input.buffer.clear
- end
-
- should "have the correct messages in the buffer" do
- bytes = []
- @messages.each do |message|
- puts "sending: #{message.inspect}"
- @output.puts(message)
- bytes += message
-
- sleep(0.5)
-
- buffer = @input.buffer.map { |m| m[:data] }.flatten
- puts "received: #{buffer.to_s}"
- assert_equal(bytes, buffer)
- end
- assert_equal(bytes.length, @input.buffer.map { |m| m[:data] }.flatten.length)
- end
- end
-
- end
-end
90 app/server/vendor/ffi-coremidi/test/io_test.rb
@@ -1,90 +0,0 @@
-require "helper"
-
-class CoreMIDI::IOTest < Test::Unit::TestCase
-
- # ** these tests assume that TestOutput is connected to TestInput
- context "CoreMIDI" do
-
- setup do
- sleep(1)
- end
-
- context "full IO" do
-
- context "using Arrays" do
-
- setup do
- @messages = TestHelper::VariousMIDIMessages
- @messages_arr = @messages.inject { |a,b| a+b }.flatten
- @received_arr = []
- @pointer = 0
- end
-
- should "do IO" do
- $test_device[:output].open do |output|
- $test_device[:input].open do |input|
-
- input.buffer.clear
-
- @messages.each do |msg|
-
- $>.puts "sending: " + msg.inspect
-
- output.puts(msg)
- sleep(1)
- received = input.gets.map { |m| m[:data] }.flatten
-
- $>.puts "received: " + received.inspect
-
- assert_equal(@messages_arr.slice(@pointer, received.length), received)
- @pointer += received.length
- @received_arr += received
- end
- assert_equal(@messages_arr.length, @received_arr.length)
- end
- end
-
- end
- end
-
- context "using byte Strings" do
-
- setup do
- @messages = TestHelper::VariousMIDIByteStrMessages
- @messages_str = @messages.join
- @received_str = ""
- @pointer = 0
- end
-
- should "do IO" do
- $test_device[:output].open do |output|
- $test_device[:input].open do |input|
-
- @messages.each do |msg|
-
- $>.puts "sending: " + msg.inspect
-
- output.puts(msg)
- sleep(1)
- received = input.gets_bytestr.map { |m| m[:data] }.flatten.join
- $>.puts "received: " + received.inspect
-
- assert_equal(@messages_str.slice(@pointer, received.length), received)
- @pointer += received.length
- @received_str += received
- end
- assert_equal(@messages_str, @received_str)
-
- end
- end
-
-
- end
-
- end
-
- end
-
- end
-
-end
6 app/server/vendor/midi-winmm/.gitignore
@@ -1,6 +0,0 @@
-.idea
-.idea/*/**
-.loadpath
-.project
-*.gem
-*.gemspec
13 app/server/vendor/midi-winmm/LICENSE
@@ -1,13 +0,0 @@
-Copyright 2010-2011 Ari Russo
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
46 app/server/vendor/midi-winmm/README.rdoc
@@ -1,46 +0,0 @@
-= midi-winmm
-
-== Summary
-
-Realtime MIDI input and output with Ruby for Windows/Cygwin. Uses the WinMM system API
-
-Note that in the interest of allowing people on other platforms to utilize your code, you should consider using {unimidi}[http://github.com/arirusso/unimidi]. Unimidi is a platform independent wrapper which implements midi-winmm.
-
-== Features
-
-* Input and output on multiple devices concurrently
-* Agnostically handle different MIDI Message types (including SysEx)
-* Timestamped input events
-
-== Requirements
-
-* {ffi}[http://github.com/ffi/ffi] (gem install ffi)
-
-== Install
-
- gem install midi-winmm
-
-== Examples
-
-* {input}[http://github.com/arirusso/midi-winmm/blob/master/examples/input.rb]
-* {output}[http://github.com/arirusso/midi-winmm/blob/master/examples/output.rb]
-
-({more}[http://github.com/arirusso/midi-winmm/blob/master/examples])
-
-== Tests
-
-please see {test/config.rb}[http://github.com/arirusso/midi-winmm/blob/master/test/config.rb] before running tests
-
-== Documentation
-
-{rdoc}[http://rdoc.info/gems/midi-winmm]
-
-== Author
-
-{Ari Russo}[http://github.com/arirusso]
-
-== License
-
-Apache 2.0, See the file LICENSE
-
-Copyright (c) 2010-2011 Ari Russo
12 app/server/vendor/midi-winmm/Rakefile
@@ -1,12 +0,0 @@
-
-require 'rake'
-require 'rake/testtask'
-
-Rake::TestTask.new(:test) do |t|
-
- t.libs << "test"
- t.test_files = FileList["test/**/test_*.rb"]
- t.verbose = true
-end
-
-task :default => [:test]
24 app/server/vendor/midi-winmm/examples/input.rb
@@ -1,24 +0,0 @@
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require 'midi-winmm'
-
-# this program selects the first midi input and sends an inspection of the first 10 messages
-# messages it receives to standard out
-
-num_messages = 10
-
-# MIDIWinMM::Input.all.to_s will list your midi inputs
-
-MIDIWinMM::Input.first.open do |input|
-
- $>.puts "send some MIDI to your input now..."
-
- num_messages.times do
- m = input.gets
- $>.puts(m)
- end
-
-end
-
-$>.puts "finished"
10 app/server/vendor/midi-winmm/examples/list_devices.rb
@@ -1,10 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require 'midi-winmm'
-require 'pp'
-
-pp MIDIWinMM::Device.all_by_type
-
24 app/server/vendor/midi-winmm/examples/output.rb
@@ -1,24 +0,0 @@
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require 'midi-winmm'
-
-# this program selects the first midi output and sends some arpeggiated chords to it
-
-notes = [36, 40, 43] # C E G
-octaves = 6
-duration = 0.1
-
-# MIDIWinMM::Output.all.to_s will list your midi outputs
-
-MIDIWinMM::Output.first.open do |output|
-
- (0..((octaves-1)*12)).step(12) do |oct|
- notes.each do |note|
- output.puts(0x90, note + oct, 100)
- sleep(duration)
- output.puts(0x80, note + oct, 100)
- end
- end
-
-end
11 app/server/vendor/midi-winmm/examples/sysex_output.rb
@@ -1,11 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require 'midi-winmm'
-
-output = MIDIWinMM::Output.first
-sysex_msg = [0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7]
-
-output.open { |output| output.puts(sysex_msg) }
15 app/server/vendor/midi-winmm/lib/midi-winmm.rb
@@ -1,15 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Set of modules and classes for interacting with MIDI functions
-# of the WinMM System API
-#
-module MIDIWinMM
- VERSION = "0.1.10"
-end
-
-require 'ffi'
-
-require 'midi-winmm/device'
-require 'midi-winmm/input'
-require 'midi-winmm/map'
-require 'midi-winmm/output'
81 app/server/vendor/midi-winmm/lib/midi-winmm/device.rb
@@ -1,81 +0,0 @@
-#!/usr/bin/env ruby
-module MIDIWinMM
-
- #
- # Module containing methods used by both input and output devices when using the
- # WinMM driver interface
- #
- module Device
-
- attr_reader :enabled, :id, :info, :name, :type
-
- alias_method :enabled?, :enabled
-
- def initialize(id, name, options = {}, &block)
- @id = id
- @info = options[:info]
- @type = self.class.name.split('::').last.downcase.to_sym
- @name = name
- end
-
- def self.all
- all_by_type.values.flatten
- end
-
- def self.all_by_type
- types = { :input => Input,
- :output => Output }
- available_devices = { :input => [], :output => [] }
- count = 0
- types.each do |type, klass|
- (0..(Map::cfunc(type, :getNumDevs)-1)).each do |i|
- data = Map::DeviceInfo[type].new
- Map::cfunc(type, :getDevCapsA, i, data.to_ptr, Map::DeviceInfo[type].size)
- name = data[:szPname].to_s
- dev = klass.new(i, name, :info => data)
- available_devices[type] << dev
- end
- end
- available_devices
- end
-
- # select the first device of type type
- def self.first(type)
- all_by_type[type].first
- end
-
- # select the last device of type type
- def self.last(type)
- all_by_type[type].last
- end
-
- WinmmCallbackFlag = 0x30000 # we plan to use a callback to collect events
-
- private
-
- # High word
- # High-order byte: Not used.
- # Low-order byte: Contains a second byte of MIDI data (when needed).
- # Low word
- # High-order byte: Contains the first byte of MIDI data (when needed).
- # Low-order byte: Contains the MIDI status.
- #
- def dwmsg_to_array_of_bytes(m)
- # there has to be a better way to do this
- s = []
- m = m.to_s(16)
- (1..m.length).step(2) { |i| s << m[(m.length-i)-1, 2].hex }
- s
- end
-
- def error?(num)
- Map::error?(num)
- end
-
- def error(num)
- Map::error(num)
- end
-
- end
-
-end
155 app/server/vendor/midi-winmm/lib/midi-winmm/input.rb
@@ -1,155 +0,0 @@
-#!/usr/bin/env ruby
-module MIDIWinMM
-
- #
- # Input device class for the WinMM driver interface
- #
- class Input
-
- include Device
-
- BufferSize = 256
-
- attr_reader :buffer
-
- # initializes this device
- def enable(options = {}, &block)
- init_input_buffer
- handle_ptr = FFI::MemoryPointer.new(FFI.type_size(:int))
- initialize_local_buffer
- @event_callback = get_event_callback
-
- Map.winmm_func(:midiInOpen, handle_ptr, @id, @event_callback, 0, Device::WinmmCallbackFlag)
-
- @handle = handle_ptr.read_int
-
- Map.winmm_func(:midiInPrepareHeader, @handle, @header.pointer, @header.size)
- Map.winmm_func(:midiInAddBuffer, @handle, @header.pointer, @header.size)
- Map.winmm_func(:midiInStart, @handle)
-
- @enabled = true
-
- unless block.nil?
- begin
- yield(self)
- ensure
- close
- end
- else
- self
- end
-
- end
- alias_method :start, :enable
- alias_method :open, :enable
-
- #
- # returns an array of MIDI event hashes as such:
- # [
- # { :data => [144, 90, 100], :timestamp => 1024 },
- # { :data => [128, 90, 100], :timestamp => 1100 },
- # { :data => [146, 60, 120], :timestamp => 1200 }
- # ]
- #
- # message data is an array of Numeric bytes
- #
- def gets
- until queued_messages?
- end
- msgs = queued_messages
- @pointer = @buffer.length
- msgs
- end
-
- # same as gets but returns message data as string of hex digits as such:
- # [
- # { :data => "904060", :timestamp => 904 },
- # { :data => "804060", :timestamp => 1150 },
- # { :data => "90447F", :timestamp => 1300 }
- # ]
- #
- #
- def gets_s
- msgs = gets
- msgs.each { |msg| msg[:data] = numeric_bytes_to_hex_string(msg[:data]) }
- msgs
- end
- alias_method :gets_bytestr, :gets_s
- alias_method :gets_hex, :gets_s
-
- # close the device
- def close
- Map.winmm_func(:midiInUnprepareHeader, @handle, @header.pointer, @header.size)
- Map.winmm_func(:midiInStop, @handle)
- Map.winmm_func(:midiInClose, @handle)
- @enabled = false
- end
-
- def self.first
- Device.first(:input)
- end
-
- def self.last
- Device.last(:input)
- end
-
- def self.all
- Device.all_by_type[:input]
- end
-
- private
-
- def queued_messages
- @buffer.slice(@pointer, @buffer.length - @pointer)
- end
-
- def queued_messages?
- @pointer < @buffer.length
- end
-
- # prepare the header struct where input event information is held
- def init_input_buffer
- @header = Map::MIDIHdr.new
- @header.write_data(Input::BufferSize)
- @header[:dwBytesRecorded] = 0
- @header[:dwFlags] = 0
- @header[:dwUser] = 0
- @header[:dwBufferLength] = Input::BufferSize
- end
-
- # returns a Proc that is called when the device receives a message
- def get_event_callback
- Proc.new do |hMidiIn,wMsg,dwInstance,dwParam1,dwParam2|
- msg_type = Map::CallbackMessageTypes[wMsg] || ''
- case msg_type
- when :input_data then
- msg = { :data => dwmsg_to_array_of_bytes(dwParam1), :timestamp => dwParam2 }
- @buffer << msg
- when :input_long_data then
- @receiving_sysex = true
- data = @header[:lpData].read_string(Input::BufferSize).gsub(/ /, '')
- unless data.eql?("")
- str = data.unpack(("C" * (data.length-1)))
- msg = { :data => str, :timestamp => dwParam2 }
- @buffer << msg
- end
- end
- end
- end
-
- def initialize_local_buffer
- @pointer = 0
- @buffer = []
- def @buffer.clear
- super
- @pointer = 0
- end
- end
-
- def numeric_bytes_to_hex_string(bytes)
- bytes.map { |b| s = b.to_s(16).upcase; b < 16 ? s = "0" + s : s; s }.join
- end
-
- end
-
-end
229 app/server/vendor/midi-winmm/lib/midi-winmm/map.rb
@@ -1,229 +0,0 @@
-#!/usr/bin/env ruby
-module MIDIWinMM
-
- #
- # Module containing C function and struct binding for the WinMM
- # driver interface library
- #
- module Map
-
- extend FFI::Library
- ffi_lib 'Winmm'
- ffi_convention :stdcall
-
- HeaderFlags = {
- 0x00000001 => :done,
- 0x00000002 => :prepared,
- 0x00000004 => :inqueue,
- 0x00000008 => :isstream
- }
-
- CallbackMessageTypes = {
- 0x3C1 => :input_open,
- 0x3C2 => :input_close,
- 0x3C3 => :input_data,
- 0x3C4 => :input_long_data,
- 0x3C5 => :input_error,
- 0x3C6 => :input_long_error,
- 0x3C7 => :output_open,
- 0x3C8 => :output_close,
- 0x3C9 => :output_data,
- 0x3CC => :output_more_data
- }
-
- Errors = {
- 1 => "Unspecified",
- 2 => "Bad Device ID",
- 3 => "Not Enabled",
- 4 => "Allocation",
- 5 => "Invalid Handle",
- 6 => "No Driver",
- 7 => "No Memory",
- 8 => "Not Supported",
- 9 => "Bad Error Number",
- 10 => "Invalid Flag",
- 11 => "Invalid Parameter",
- 12 => "Handle Busy",
- 13 => "Invalid Alias"
- }
-
- # Byte (8 bits). Declared as unsigned char.
- typedef :uchar, :BYTE
- # 32-bit unsigned integer. The range is 0 through 4,294,967,295 decimal.
- typedef :uint32, :DWORD
- # Unsigned long type for pointer precision. Use when casting a pointer to a long type.
- typedef :ulong, :DWORD_PTR
- # (L) Handle to an object. WinNT.h: #typedef PVOID HANDLE;
- typedef :ulong, :HANDLE
- # Handle for a MIDI input device.
- typedef :HANDLE, :HMIDIIN
- # Handle for a MIDI output device.
- typedef :HANDLE, :HMIDIOUT
- # system function result codes
- typedef :uint, :MMRESULT
- # Unsigned INT_PTR.
- typedef :uint, :UINT_PTR
- # 16-bit unsigned integer. The range is 0 through 65535 decimal.
- typedef :ushort, :WORD
-
- class MIDIEvent < FFI::Struct
- layout :dwDeltaTime, :ulong,
- :dwStreamID, :ulong,
- :dwEvent, :ulong,
- :dwParms, [:ulong, 8]
- end
-
- class MIDIHdr < FFI::Struct
- layout :lpData, :pointer,
- :dwBufferLength, :DWORD,
- :dwBytesRecorded, :DWORD,
- :dwUser, :DWORD_PTR,
- :dwFlags, :DWORD,
- :lpNext, :pointer,
- :reserved, :DWORD_PTR,
- :dwOffset, :DWORD,
- :dwReserved, :DWORD_PTR
-
- def write_data(size, string = '')
- ptr = FFI::MemoryPointer.new(:char, size)
- blank = " " * (size-string.length-1)
- ptr.put_string(0, string + blank)
- self[:lpData] = ptr
- self[:dwBufferLength] = string.length
- end
- end
-
- class MIDIInputInfo < FFI::Struct
- layout :wMid, :WORD,
- :wPid, :WORD,
- :vDriverVersion, :ulong,
- :szPname, [:char, 32],
- :dwSupport, :DWORD
- end
-
- class MIDIOutputInfo < FFI::Struct
- layout :wMid, :WORD,
- :wPid, :WORD,
- :vDriverVersion, :ulong,
- :szPname, [:char, 32],
- :wTechnology, :WORD,
- :wVoices, :WORD,
- :wNotes, :WORD,
- :wChannelMask, :WORD,
- :dwSupport, :DWORD
- end
-
- DeviceInfo = {
-
- :input => MIDIInputInfo,
- :output => MIDIOutputInfo
-
- }
-
- # void CALLBACK MidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2)
- callback :input_callback, [:pointer, :uint, :DWORD_PTR, :DWORD_PTR, :DWORD_PTR], :void
-
- # void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
- callback :output_callback, [:pointer, :uint, :DWORD_PTR, :DWORD_PTR, :DWORD_PTR], :void
-
- #
- # initialize/close devices
- #
-
- # MMRESULT midiInOpen(LPHMIDIIN lphMidiIn, UINT_PTR uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwCallbackInstance, DWORD dwFlags)
- # LPHMIDIIN = *HMIDIIN
- attach_function :midiInOpen, [:pointer, :UINT_PTR, :input_callback, :DWORD_PTR, :DWORD], :MMRESULT
-
- # MMRESULT midiOutOpen(LPHMIDIOUT lphmo, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwCallbackInstance, DWORD dwFlags)
- # LPHMIDIOUT = *HMIDIOUT
- # :output_callback
- attach_function :midiOutOpen, [:pointer, :uint, :output_callback, :DWORD_PTR, :DWORD], :MMRESULT
-
- attach_function :midiInClose, [:ulong], :ulong
- attach_function :midiOutClose, [:ulong], :ulong
- attach_function :midiInReset, [:pointer], :ulong
-
- # MMRESULT midiOutReset(HMIDIOUT hmo)
- attach_function :midiOutReset, [:HMIDIOUT], :MMRESULT
-
- #
- # for message output
- #
# MMRESULT midiOutShortMsg(HMIDIOUT hmo, DWORD dwMsg)
- attach_function :midiOutShortMsg, [:HMIDIOUT, :DWORD], :MMRESULT
-
- # MMRESULT midiOutLongMsg(HMIDIOUT hmo, LPMIDIHDR lpMidiOutHdr,UINT cbMidiOutHdr)
- # LPMIDIHDR = *MIDIHDR
- attach_function :midiOutLongMsg, [:HMIDIOUT, :pointer, :uint], :MMRESULT
-
- # MMRESULT midiStreamOpen(LPHMIDISTRM lphStream,LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
- attach_function :midiStreamOpen, [:pointer, :pointer, :DWORD, :DWORD_PTR, :DWORD_PTR, :DWORD], :MMRESULT
-
- # MMRESULT midiOutPrepareHeader(HMIDIOUT hmo, LPMIDIHDR lpMidiOutHdr, UINT cbMidiOutHdr)
- attach_function :midiOutPrepareHeader, [:HMIDIOUT, :pointer, :uint], :MMRESULT
-
- #MMRESULT midiOutUnprepareHeader(HMIDIOUT hmo, LPMIDIHDR lpMidiOutHdr, UINT cbMidiOutHdr)
- attach_function :midiOutUnprepareHeader, [:HMIDIOUT, :ulong, :uint], :MMRESULT
-
- #MMRESULT midiOutGetVolume(HMIDIOUT hmo, LPDWORD lpdwVolume)
- attach_function :midiOutGetVolume, [:HMIDIOUT, :pointer], :MMRESULT
-
- # MMRESULT midiOutSetVolume(HMIDIOUT hmo, DWORD dwVolume)
- attach_function :midiOutSetVolume, [:HMIDIOUT, :DWORD], :MMRESULT
-
- #
- # input
- #
-
- # MMRESULT midiInPrepareHeader(HMIDIIN hMidiIn, LPMIDIHDR lpMidiInHdr, UINT cbMidiInHdr)
- attach_function :midiInPrepareHeader, [:HMIDIIN, :pointer, :uint], :MMRESULT
-
- attach_function :midiInUnprepareHeader, [:HMIDIIN, :pointer, :uint], :MMRESULT
- attach_function :midiInAddBuffer, [:HMIDIIN, :pointer, :uint], :MMRESULT
-
- # MMRESULT midiInStart(HMIDIIN hMidiIn)
- attach_function :midiInStart, [:HMIDIIN], :MMRESULT
-
- # MMRESULT midiInStop(HMIDIIN hMidiIn)
- attach_function :midiInStop, [:HMIDIIN], :MMRESULT
-
- #
- # enumerate devices
- #
-
- # UINT midiInGetNumDevs(void)
- attach_function :midiInGetNumDevs, [], :uint
-
- # UINT midiOutGetNumDevs(void)
- attach_function :midiOutGetNumDevs, [], :uint
-
- # MMRESULT midiInGetDevCaps(UINT_PTR uDeviceID, LPMIDIINCAPS lpMidiInCaps, UINT cbMidiInCaps);
- attach_function :midiInGetDevCapsA, [:UINT_PTR, :pointer, :uint], :MMRESULT
-
- attach_function :midiOutGetDevCapsA, [:UINT_PTR, :pointer, :uint], :MMRESULT
-
- # shortcut for calling winmm midi functions
- def self.cfunc(type, funcname, *args)
- t = type.to_s.gsub(/put/,'') # convert output to out, input to in
- name = funcname.to_s
- name[0] = name[0,1].upcase # capitalize
- t[0] = t[0,1].upcase # capitalize
- self.send("midi#{t}#{name}", *args)
- end
-
- def self.winmm_func(name, *args)
- status = self.send(name, *args)
- raise "#{name.to_s}: #{error(status)}" if error?(status)
- end
-
- def self.error?(num)
- !Map::Errors[num].nil?
- end
-
- def self.error(num)
- Map::Errors[num]
- end
-
- end
-end
139 app/server/vendor/midi-winmm/lib/midi-winmm/output.rb
@@ -1,139 +0,0 @@
-#!/usr/bin/env ruby
-module MIDIWinMM
-
- #
- # Output device class for the WinMM driver interface
- #
- class Output
-
- include Device
-
- BufferSize = 2048
-
- attr_reader :buffer
-
- # initialize this device
- def enable(options = {}, &block)
- init_output_buffer
- Map.winmm_func(:midiOutOpen, Output::HandlePointer, @id, Output::EventCallback, 0, Device::WinmmCallbackFlag)
- @handle = HandlePointer.read_int
- @enabled = true
- unless block.nil?
- begin
- yield(self)
- ensure
- close
- end
- else
- self
- end
- end
- alias_method :start, :enable
- alias_method :open, :enable
-
- # close this device
- def close
- Map.winmm_func(:midiOutClose, @handle)
- @enabled = false
- end
-
- # returns a hash of fixnum values { :left => n, :right => n2 }
- def volume
- volume = FFI::MemoryPointer.new(FFI.type_size(:ulong))
-
- Map.winmm_func(:midiOutGetVolume, @handle, volume)
-
- str = dwmsg_to_array_of_bytes(volume.read_ulong)
- left = str.slice!(0,4)
-
- { :left => left.hex, :right => str.hex }
- end
-
- # accepts either a hash of fixnums { :left => n, :right => n2 } or
- # a single fixnum that will be applied to both channels
- def volume=(val)
- vol = val.kind_of?(Hash) ? (val[:left] + (val[:right] << 16)) : (val + (val << 16))
- Map.winmm_func(:midiOutSetVolume, @handle, vol)
- end
-
- def reset
- Map.winmm_func(:midiOutReset, @handle)
- end
-
- # send a message of an indeterminate type
- def puts(*a)
- case a.first
- when Array then puts_bytes(*a.first)
- when Numeric then puts_bytes(*a)
- when String then puts_s(*a)
- end
- end
-
- # send a message consisting of Numeric bytes
- def puts_bytes(*message_bytes)
- format = "C" * message_bytes.size
-
- packed = message_bytes.pack(format)
- data_pointer = FFI::MemoryPointer.new(message_bytes.size).put_bytes(0, packed)
-
- @header[:dwBufferLength] = message_bytes.size
- @header[:dwBytesRecorded] = message_bytes.size
- @header[:lpData] = data_pointer
-
- Map.winmm_func(:midiOutPrepareHeader, @handle, @header.pointer, @header.size)
-
- Map.winmm_func(:midiOutLongMsg, @handle, @header.pointer, @header.size)
-
- end
-
- # send a message consisisting of a String of hex digits
- def puts_s(data)
- data = data.dup
- output = []
- until (str = data.slice!(0,2)).eql?("")
- output << str.hex
- end
- puts_bytes(*output)
- end
- alias_method :puts_bytestr, :puts_s
- alias_method :puts_hex, :puts_s
-
- def self.first
- Device::first(:output)
- end
-
- def self.last
- Device::last(:output)
- end
-
- def self.all
- Device.all_by_type[:output]
- end
-
- private
-
- EventCallback = Proc.new do |hmo, wMsg, dwInstance, dwParam1, dwParam2|
- msg_type = Map::CallbackMessageTypes[wMsg] || ''
- if msg_type.eql?(:output_data)
- header = dwParam1
- handle = HandlePointer.read_int
- Map.winmm_func(:midiOutUnprepareHeader, handle, header, Map::MIDIHdr.size)
- end
- end
-
- HandlePointer = FFI::MemoryPointer.new(FFI.type_size(:int))
-
- def init_output_buffer
- @header = Map::MIDIHdr.new
- d = FFI::MemoryPointer.new(:char, Output::BufferSize)
- d.put_string(0, " " * (Output::BufferSize - 1)) # initialize with a string of spaces
- @header[:lpData] = d.address
- @header[:dwBufferLength] = Output::BufferSize
- @header[:dwBytesRecorded] = 0
- @header[:dwFlags] = 0
- @header[:dwUser] = 0
- end
-
- end
-
-end
2 app/server/vendor/midi-winmm/test/.gitignore
@@ -1,2 +0,0 @@
-.loadpath
-.project
12 app/server/vendor/midi-winmm/test/config.rb
@@ -1,12 +0,0 @@
-module TestHelper::Config
-
- include MIDIWinMM
-
- # adjust these constants to suit your hardware configuration
- # before running tests
-
- NumDevices = 4 # this is the total number of MIDI devices that are connected to your system
- TestInput = Input.first # this is the device you wish to use to test input
- TestOutput = Output.all[1] # likewise for output
-
-end
37 app/server/vendor/midi-winmm/test/helper.rb
@@ -1,37 +0,0 @@
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require 'test/unit'
-require 'midi-winmm'
-
-module TestHelper
-
- def bytestrs_to_ints(arr)
- data = arr.map { |m| m[:data] }.join
- output = []
- until (bytestr = data.slice!(0,2)).eql?("")
- output << bytestr.hex
- end
- output
- end
-
- # some MIDI messages
- VariousMIDIMessages = [
- [0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7], # SysEx
- [0x90, 100, 100], # note on
- [0x90, 43, 100], # note on
- [0x90, 76, 100], # note on
- [0x90, 60, 100], # note on
- [0x80, 100, 100] # note off
- ]
-
- # some MIDI messages
- VariousMIDIByteStrMessages = [
- "F04110421240007F0041F7", # SysEx
- "906440", # note on
- "804340" # note off
- ]
-
-end
-
-require File.dirname(__FILE__) + '/config'
45 app/server/vendor/midi-winmm/test/test_input_buffer.rb
@@ -1,45 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'helper'
-
-class InputBufferTest < Test::Unit::TestCase
-
- include MIDIWinMM
- include TestHelper
- include TestHelper::Config # before running these tests, adjust the constants in config.rb to suit your hardware setup
- # ** this test assumes that TestOutput is connected to TestInput
-
- def test_input_buffer
- sleep(1)
-
- messages = VariousMIDIMessages
- bytes = []
-
- TestOutput.open do |output|
- TestInput.open do |input|
-
- messages.each do |msg|
-
- $>.puts "sending: " + msg.inspect
-
- output.puts(msg)
-
- bytes += msg
-
- sleep(0.5)
-
- buffer = input.buffer.map { |m| m[:data] }.flatten
-
- $>.puts "received: " + buffer.to_s
-
- assert_equal(bytes, buffer)
-
- end
-
- assert_equal(bytes.length, input.buffer.map { |m| m[:data] }.flatten.length)
-
- end
- end
- end
-
-end
82 app/server/vendor/midi-winmm/test/test_io.rb
@@ -1,82 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'helper'
-
-class IoTest < Test::Unit::TestCase
-
- include MIDIWinMM
- include TestHelper
- include TestHelper::Config # before running these tests, adjust the constants in config.rb to suit your hardware setup
- # ** this test assumes that TestOutput is connected to TestInput
-
- def test_full_io
- sleep(1)
- messages = VariousMIDIMessages
- messages_arr = messages.inject { |a,b| a+b }.flatten
- received_arr = []
- pointer = 0
- TestOutput.open do |output|
- TestInput.open do |input|
-
- messages.each do |msg|
-
- $>.puts "sending: " + msg.inspect
-
- output.puts(msg)
- sleep(1)
- received = input.gets.map { |m| m[:data] }.flatten
-
-
- $>.puts "received: " + received.inspect
-
- assert_equal(messages_arr.slice(pointer, received.length), received)
-
- pointer += received.length
-
- received_arr += received
-
- end
-
- assert_equal(messages_arr.length, received_arr.length)
-
- end
- end
- end
-
- # ** this test assumes that TestOutput is connected to TestInput
- def test_full_io_bytestr
- sleep(1) # pause between tests
-
- messages = VariousMIDIByteStrMessages
- messages_str = messages.join
- received_str = ""
- pointer = 0
-
- TestOutput.open do |output|
- TestInput.open do |input|
-
- messages.each do |msg|
-
- $>.puts "sending: " + msg.inspect
-
- output.puts(msg)
- sleep(1)
- received = input.gets_bytestr.map { |m| m[:data] }.flatten.join
- $>.puts "received: " + received.inspect
-
- assert_equal(messages_str.slice(pointer, received.length), received)
-
- pointer += received.length
-
- received_str += received
-
- end
-
- assert_equal(messages_str, received_str)
-
- end
- end
-
- end
-
-end
3 app/server/vendor/midilib/.gitignore
@@ -1,3 +0,0 @@
-html
-pkg
-.rbenv-version
129 app/server/vendor/midilib/ChangeLog
@@ -1,129 +0,0 @@
-For any further change descriptions, see the Git logs.
-
-2007-12-11 Jim Menard
-
- * lib/midilib/io/seqreader.rb: Fixed text method and added default
- implementation of key_signature.
-
-2007-12-09 Jim Menard
-
- * examples/measures_mbt.rb: Added.
-
-2007-12-09 Jim Menard
-
- * lib/midilib/event.rb: Added code that fixes bpm calculation
- bugs, and his TimeSig and KeySig classes.
-
- * lib/midilib/measure.rb: Added.
-
- * lib/midilib/sequence.rb: Fixed clock. Added get_measures method.
-
-2007-12-09 Jim Menard
-
- * lib/midilib/event.rb: added program_change? and
- print_channel_numbers_from_one to Event.
-
-2007-03-17 Jim Menard
-
- * Version 1.0.0 released. I will no longer be maintaining this
- change log; the Subversion comments should be sufficient.
-
-2006-08-20 Jim Menard
-
- * lib/midilib/event.rb (PolyPressure::initialize): Fixed the
- misspelled POLY_PRESSURE cosntant, thanks to Mario Pehle
-
-
-2006-05-15 Jim Menard
-
- * test/test.mid: created (copied examples/from_scratch.mid).
-
-2005-03-21 Jim Menard
-
- * Version 0.8.4 released.
-
- * lib/midilib/event.rb (Realtime::initialize): set @is_realtime
- to true, not false.
- (SystemCommon::initialize): moved @is_system = true to here
- (SystemExclusive::initialize): ...from here.
-
-2005-03-20 Jim Menard
-
- * lib/midilib/sequence.rb (Sequence::note_to_delta): created.
- (Sequence::note_to_length): created.
- (Sequence::length_to_delta): created.
-
- * examples/from_scratch.rb: created.
-
-2004-07-16 Jim Menard
-
- * Version 0.8.3 released.
-
-2004-07-10 Jim Menard
-
- * lib/midilib/event.rb (NoteEvent::note_to_s): created.
- (Event::number_to_s): created.
- (Event): added @print_note_names and @print_decimal_numbers
- attributes.
- (to_s all classes): use @print_note_names and @print_decimal_numbers
-
-2004-06-30 Jim Menard
-
- * Version 0.8.2 released.
-
- * lib/midilib/event.rb (MetaEvent): changed @type to @meta_type to
- avoid warnings like "Object#type is deprecated; use Object#class".
-
- * lib/midilib/track.rb (Track::name): use Event.meta_type (renamed
- from Event.type).
- (Track::name=): use Event.meta_type (renamed from Event.type).
-
- * test/event_equality.rb (MIDI::MetaEvent): use meta_type instead
- of type.
-
- * examples/transpose.rb: fixed $LOAD_PATH. Added 'b' to file open
- modes for Windows.
-
- * examples/strings.rb: fixed $LOAD_PATH. Fixed arguments passed to
- read block. Fixed code that looks for meta events. Added 'b' to
- file open modes for Windows.
-
- * examples/seq2text.rb: fixed $LOAD_PATH. Fixed arguments passed
- to read block. Added 'b' to file open modes for Windows.
-
- * examples/reader2text.rb: fixed $LOAD_PATH. Fixed TextTranslator
- superclass. Fixed arguments passed to read block. Added 'b' to
- file open modes for Windows.
-
- * lib/midilib/io/seqwriter.rb (SeqWriter::initialize): added block
- rdoc comment.
- (SeqWriter::write_to): added track to @update_block args.
-
- * lib/midilib/io/seqreader.rb (SeqReader::initialize): added block
- rdoc comment.
-
-2004-06-27 Jim Menard
-
- * Version 0.8.1 released.
-
- * test/test_event.rb: created.
-
- * lib/midilib/track.rb: more documentation.
- (Track::sort): sorts by events' time_from_start and modifies
- @events (which wasn't happening before; I forgot to assign the
- sorted results back to @events).
- (Track::recalc_delta_from_times): fixed.
- (Track::quantize): call recalc_delta_from_times.
-
- * test/test_track.rb (TrackTester::test_sort): created.
- (TrackTester::test_recalc_delta_from_times): created.
-
- * lib/midilib/sequence.rb: more documentation.
-
- * lib/midilib/consts.rb: hid some comments from RDoc.
-
- * lib/midilib/event.rb: more documentation.
- (Event::realtime): fix quantize_to so it changes the event's
- time_from_start instead of delta_time.
-
- * test/*.rb: removed redundant copyright and license notices.
56 app/server/vendor/midilib/Credits
@@ -1,56 +0,0 @@
-midilib is developed by Jim Menard, jim@jimmenard.com. Additional bug fixes
-and suggestions have come from:
-
-Mario Pehle
-
- Noticed that the PolyPressure class used the misspelled constant
- POLY_PRESSSURE.
-
-Mike Hall
-
- Found errors in example scripts' $LOAD_PATH and a bug in sequence reading
- block callback arguments. Found a bug in meta events that caused
- "Object#type is deprecated" error messages.
-
-Emanuel Borsboom
-
- Found and fixed an error in PitchBend data encoding.
-
-Christopher Rose
-
- Found bug in Track#recalc_delta_from_times.
-
-Jari Williamsson
-
- Contributed Measure and Measures, TimeSig and KeySig, and fixes to events.
- Added get_measures to Sequence. Added default implementation of
- key_signature in SeqReader. Contributed the measures_mbt.rb example.
-
-Noah Thorp
-
- Found a bug in the code intended to make midilib work under Ruby 1.9.
- Found another bug in KeySing.data_as_bytes.
-
-Zach Chadwick (zachad on Github)
-
- Reported a problem that led to a fix in the way that strings and byte
- arrays are handled and output in meta events.
-
-Adam Murray (adamjmurray on Github)
-
- Found problem with Track#recalc_delta_from_times sorting, and wrote the
- fix that is incorporated there.
-
-Shai Rosenfeld (shaiguitar on Github)
-
- Corrected missing block arg in README.
-
-J (dark-panda on Github)
-
- Instead of monkeypatching ::Array, put sorting methods into new
- MIDI::Array subclass to avoid clashes with Rails app.
-
-Lucas lfzawacki (lfzawacki on Github)
-
- Found a bug in the MIDI::IO::SeqReader class: the pitch_bend method's
- msb and lsb parameters were reversed.
480 app/server/vendor/midilib/README.rdoc
@@ -1,480 +0,0 @@
-= midilib
-
-midilib is a pure Ruby MIDI library useful for reading and writing standard
-MIDI files and manipulating MIDI event data.
-
-The GitHub project page and Web site of midilib is
-http://github.com/jimm/midilib and the RubyGems.org page is
-http://rubygems.org/gems/midilib, where you can also find all the RDoc
-documentation.
-
-midilib is compatible with Ruby 1.8.x 1.9.x, and 2.x.
-
-
-== Dependencies
-
-midilib does not require any other packages. The test suite in the tests
-directory requires the testing framework TestUnit, which comes with Ruby 1.8
-and later and can also be found in the Ruby Application Archive
-(http://raa.ruby-lang.org).
-
-To rebuild the gem or RDocs or run the tests easily, you can use the Rakefile
-which requires Rake (http://rake.rubyforge.org).
-
-
-== Installation
-
-=== RubyGems Installation
-
-To install midilib as a gem, type
-
- % gem install midilib
-or, if you already have a previous version, use
- % gem update midilib
-
-You may need root privileges to install or update the gem.
-
-=== Manual Installation
-
-After downloading and expanding the archive, you can install midilib with the
-command
-
- % ruby install.rb
-(or)
- % ruby install.rb --install-dir=my_directory
-
-You may need root privileges to install.
-
-
-== Testing
-
- % rake test
-
-runs all of the tests in the test directory.
-
-
-== Overview
-
-The midilib MIDI file reader only understands MIDI file format 1, where a
-sequence is made up of multiple tracks. It doesn't yet understand format 0
-(a single track containing all events) or format 2 (a collection of format 0
-files in one file).
-
-=== MIDI::Sequence
-
-A sequence contains a collection of tracks and global information like the
-sequence's pulses per quarter note (ppqn) and time signature.
-
-The first track in a sequence is special; it holds meta-events like tempo and
-sequence name. Don't put any notes in this track.
-
-MIDI::Sequence also contains some convenience methods that let you set and
-retrieve the sequence's name, the time signature, and to retrieve the first
-tempo event's beats-per-minute value.
-
-Normally instances of MIDI::IO::SeqReader and MIDI::IO::SeqWriter are used
-when a sequence reads itself from or writes itself to a MIDI file. You can
-change that by setting a sequence's reader_class or writer_class attributes.
-Instances of the classes contained in those attributes are created and used
-whenever the sequence reads or writes itself.
-
-=== MIDI::Track
-
-A track contains an array of events.
-
-When you modify the +events+ array, make sure to call recalc_times so each
-event gets its +time_from_start+ recalculated. You don't have to do that
-after every event you add; just remember to do so before using the track in a
-way that expects the list of events to be ordered correctly.
-
-A Track also holds a bit mask that specifies the channels used by the track.
-This bit mask is set when the track is read from the MIDI file by a SeqReader
-but is _not_ kept up to date by any other methods. Specifically, if you add
-events to a track at any other time, the bit mask will not be updated.
-
-=== MIDI::Measure
-
-This class contains information about a measure from the sequence. Measure
-data is based on the time signature information from the sequence and is not
-stored in the sequence itself.
-
-=== MIDI::Measures
-
-The class MIDI::Sequence method get_measures returns a MIDI::Measures object.
-MIDI::Measures is a subclass of Array. It is a specialized container for
-MIDI::Measure objects, which can be use to map event times to measure numbers.
-Please note that this object has to be remade when events are deleted/added in
-the sequence.
-
-MIDI::Measure and MIDI::Measures are brought to us by Jari Williamsson
-
-to the MIDI::Event and MIDI::Track classes.
-
-=== MIDI::Event
-
-Each event holds not only its delta time but also its time from the start of
-the track. The track is responsible for recalculating its events' start times.
-You can call MIDI::Track#recalc_times to do so.
-
-Subclasses of MIDI::Event implement the various MIDI messages such as note on
-and off, controller values, system exclusive data, and realtime bytes.
-
-MIDI::Realtime events have delta values and start times, just like all the
-other midilib event types do. (MIDI real time status bytes don't have delta
-times, but this way we can record when in a track the realtime byte was
-received and should be sent. This is useful for start/continue/stop events
-that control other devices, for example.) Note that when a MIDI::Realtime
-event is written out to a MIDI file, the delta time is not written.
-
-MIDI::MetaEvent events hold an array of bytes named 'data'. Many meta events
-are string holders (text, lyric, marker, etc.) Though the 'data' value is
-always an array of bytes, MIDI::MetaEvent helps with saving and accessing
-string. The MIDI::MetaEvent#data_as_str method returns the data bytes as a
-string. When assigning to a meta event's data, if you pass in a string it will
-get converted to an array of bytes.
-
-
-== How To Use
-
-The following examples show you how to use midilib to read, write, and
-manipulate MIDI files and modify track events. See also the files in the
-examples directory, which are described below.
-
-
-=== Reading a MIDI File
-
-To read a MIDI file, create a MIDI::Sequence object and call its #read method,
-passing in an IO object.
-
-The #read method takes an optional block. If present, the block is called
-once after each track has finished being read. Each time, it is passed the
-track object, the total number of tracks and the number of the current track
-that has just been read. This is useful for notifying the user of progress,
-for example by updating a GUI progress bar.
-
- require 'midilib/io/seqreader'
-
- # Create a new, empty sequence.
- seq = MIDI::Sequence.new()
-
- # Read the contents of a MIDI file into the sequence.
- File.open('my_midi_file.mid', 'rb') { | file |
- seq.read(file) { | track, num_tracks, i |
- # Print something when each track is read.
- puts "read track #{i} of #{num_tracks}"
- }
- }
-
-
-=== Writing a MIDI File
-
-To write a MIDI file, call the write method, passing in an IO object.
-
-
- require 'midilib/io/seqwriter'
-
- # Start with a sequence that has something worth saving.
- seq = read_or_create_seq_we_care_not_how()
-
- # Write the sequence to a MIDI file.
- File.open('my_output_file.mid', 'wb') { | file | seq.write(file) }
-
-
-=== Editing a MIDI File
-
-Combining the last two examples, here is a script that reads a MIDI file,
-transposes some events, and writes the sequence out to a different file. This
-is a useful template for programatically manipulating MIDI data.
-
-
-This code transposes all of the note events (note on, note off, and poly
-pressure) on channel 5 down one octave.
-
-==== Transposing One Channel
-
- require 'midilib/io/seqreader'
- require 'midilib/io/seqwriter'
-
- # Create a new, empty sequence.
- seq = MIDI::Sequence.new()
-
- # Read the contents of a MIDI file into the sequence.
- File.open('my_input_file.mid', 'rb') { | file |
- seq.read(file) { | track, num_tracks, i |
- # Print something when each track is read.
- puts "read track #{i} of #{num_tracks}"
- }
- }
-
- # Iterate over every event in every track.
- seq.each { | track |
- track.each { | event |
- # If the event is a note event (note on, note off, or poly
- # pressure) and it is on MIDI channel 5 (channels start at
- # 0, so we use 4), then transpose the event down one octave.
- if MIDI::NoteEvent === event && event.channel == 4
- event.note -= 12
- end
- }
- }
-
- # Write the sequence to a MIDI file.
- File.open('my_output_file.mid', 'wb') { | file | seq.write(file) }
-
-
-=== Manipulating tracks
-
-If you modify a track's list of events directly, don't forget to call
-MIDI::Track#recalc_times when you are done.
-
- track.events[42, 1] = array_of_events
- track.events << an_event
- track.merge(array_of_events)
- track.recalc_times
-
-=== Calculating delta times
-
-A few methods in MIDI::Sequence make it easier to calculate the delta times
-that represent note lengths. MIDI::Sequence#length_to_delta takes a note
-length (a multiple of a quarter note) and returns the delta time given the
-sequence's current ppqn (pulses per quarter note) setting. 1 is a quarter
-note, 1.0/32.0 is a 32nd note (use floating-point numbers to avoid integer
-rounding), 1.5 is a dotted quarter, etc. See the documentation for that method
-for more information.
-
-MIDI::Sequence#note_to_length takes a note name and returns a length value
-(again, as a multiple of a quarter note). Legal note names are those found in
-MIDI::Sequence::NOTE_TO_LENGTH, and may begin with "dotted" and/or end with
-"triplet". For example, "whole", "sixteenth", "32nd", "quarter triplet",
-"dotted 16th", and "dotted 8th triplet" are all legal note names.
-
-Finally, MIDI::Sequence#note_to_delta takes a note name and returns a delta
-time. It does this by calling note_to_length, then passing the result to
-length_to_delta.
-
-
-=== Example Scripts
-
-Here are short descriptions of each of the examples found in the examples
-directory.
-
-* examples/from_scratch.rb shows you how to create a new sequence from scratch
- and save it to a MIDI file. It creates a file called 'from_scratch.mid'.
-
-* examples/seq2text.rb dumps a MIDI file as text. It reads in a sequence and
- uses the to_s method of each event.
-
-* examples/reader2text.rb dumps a MIDI file as text. It subclasses
- MIDI::SeqReader instead of creating a sequence containing tracks and events.
-
-* examples/transpose.rb transposes all note events (note on, note off, poly
- pressure) on a specified channel by a specified amount.
-
-* There is also one MIDI file, examples/NoFences.mid. It is a little pop ditty
- I wrote. The instruments in this file use General MIDI patch numbers and
- drum note assignments. Since I don't normally use GM patches, the sounds
- used here are at best approximations of the sounds I use.
-
-
-== Resources
-
-The Ruby Web site (http://www.ruby-lang.org/en/index.html) contains an
-introduction to Ruby, the Ruby Application Archive (RAA) at
-http://raa.ruby-lang.org, and pointers to more information.
-
-
-Programming Ruby, The Pragmatic Programmer's Guide, by David
-Thomas and Andrew Hunt, is a well-written and practical introduction to Ruby.
-Its Web page at http://www.rubycentral.com/book also contains a wealth of Ruby
-information. Though the first edition book is available online, I encourage
-you to purchase a copy of the latest edition.
-
-A description of the MIDI file format can be found in a few places such as
-http://www.borg.com/~jglatt/tech/midifile.htm.
-
-The MIDI message reference at http://www.jimmenard.com/midi_ref.html
-describes the format of MIDI commands.
-
-
-= To Do
-
-:include: TODO.rdoc
-
-
-= Support
-
-* Visit the forums, bug list, and mailing list pages at
- http://rubyforge.org/projects/midilib
-
-* Send email to Jim Menard at mailto:jim@jimmenard.com
-
-* Ask on the ruby-talk mailing list
-
-
-= Administrivia
-
-Author:: Jim Menard (mailto:jim@jimmenard.com)
-Copyright:: Copyright (c) 2003-2013 Jim Menard
-License:: Distributed under the same license as Ruby.
-
-
-== Copying
-
-midilib is copyrighted free software by Jim Menard and is released under the
-same license as Ruby. See the Ruby license at
-http://www.ruby-lang.org/en/LICENSE.txt.
-
-midilib may be freely copied in its entirety providing this notice, all
-source code, all documentation, and all other files are included.
-
-midilib is Copyright (c) 2003-2013 by Jim Menard.
-
-The song "No Fences" contained in the MIDI file examples/NoFences.mid is
-Copyright (c) 1992 by Jim Menard (jim@jimmenard.com). It may be freely used
-for non-commercial purposes as long as the author is given credit.
-
-
-== Recent Changes
-
-=== Changes for 2.0.3:
-
-New MIDI::Sequence.pulses_to_seconds method.
-
-=== Changes for 2.0.2:
-
-Stop monkeypatching Array in MIDI::Track.
-
-=== Changes for 2.0.0:
-
-MIDI::NoteOnEvent and MIDI::NoteOffEvent renamed to MIDI::NoteOn and
-MIDI::NoteOff. The old names will still work for a while.
-
-The MIDI::Event boolean methods like meta? and note? have been removed. Use
-the event classes themselves (for example, MIDI::MetaEvent === my_event or
-my_event.kind_of?(MIDI::MetaEvent)). Case statements that use classes work,
-too:
-
- case my_event
- when MIDI::NoteEvent # superclass of note on, note off, poly press
- do_this()
- when MIDI::Controller
- do_that()
- end
-
-Introduced Adam Murray's stable sorting code for
-MIDI::Track#recalc_delta_from_times. See
-http://wiki.github.com/adamjmurray/cosy/midilib-notes and
-http://github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb
-for details.
-
-Aliased MIDI::Track#sort to MIDI::Track#recalc_delta_from_times, since all
-sort did was sort the events then call recalc_delta_from_times, and
-recalc_delta_from_times sorts the events before doing anything else.
-
-MIDI::Tempo#mpq_to_bpm now returns a float.
-
-=== Changes for 1.2.0:
-
-Use byte arrays instead of strings for passing around data. All tests now pass
-for both Ruby 1.8.X and 1.9.X.
-
-=== New code repository
-
-The midilib code is now hosted at Github (http://github.com/jimm/midilib).
-
-=== Changes for 1.1.4:
-
-* Fixed a bug in KeySig.data_as_bytes. Thanks to Noah Thorp for finding this
- and the bug fixed in 1.1.3.
-
-=== Changes for 1.1.3:
-
-* Fixed the way midilib detects the behavior of IO.getc.
-
-=== Changes for 1.1.2:
-
-* Define MIDI::IO::MIDIFile.getc differently for different Ruby versions,
- instead of checking for String.bytes every time we read a byte.
-
-=== Changes for 1.1.1:
-
-* Make MIDI::IO::MIDIFile.getc do the right thing for both Ruby 1.8 and 1.9.
-
-=== Changes for 1.1.0:
-
-* Added test/test.mid to list of files to be included when packaging midifile
- for distribution.
-
-=== Changes for 1.0.0:
-
-* Fixed the bug in Track#recalc_delta_from_times found by Christopher Rose.
-
-=== Changes for 0.8.7:
-
-* All system common events now set @is_system to true and return true when
- system? is called, not just system exclusive events.
-
-* Added examples/from_scratch.rb, which shows how to create a sequence
- manually.
-
-* New MIDI::Sequence methods that turn note length names like "32nd", "dotted
- quarter", and "16th triplet" into delta times. See the docs below and
- MIDI::Sequence::length_to_delta, MIDI::Sequence::note_to_length, and
- MIDI::Sequence::note_to_delta.
-
-
-=== Changes for 0.8.3:
-
-* Added MIDI::NoteEvent.note_to_s, which returns note name as a string like
- "C4" or "F#6".
-
-* Added new boolean attributes to MIDI::Event: @print_decimal_numbers and
- @print_note_names. These are used by all Event to_s methods. See
- examples/seq2text.rb for an example.
-
-=== Changes for 0.8.2:
-
-* Changed MIDI::MetaEvent.type to MIDI::MetaEvent.event_type to avoid
- runtime complaints about Object#type calls.
-* Added 'b' binary flag to file open modes for Windows.
-* Fixed $LOAD_PATH in example files.
-* Fixed read and write block arguments.
-* Fixed other example script bugs.
-
-=== Changes for 0.8.1:
-
-* Fixed track sorting.
-* Fixed track's recalc_delta_from_times method.
-* Fixed event quantization.
-* More tests and documentation.
-
-
-== Warranty
-
-This software is provided "as is" and without any express or implied
-warranties, including, without limitation, the implied warranties of
-merchantability and fitness for a particular purpose.
89 app/server/vendor/midilib/Rakefile
@@ -1,89 +0,0 @@
-require 'rubygems'
-require 'rake'
-if RUBY_VERSION >= '1.9'
- require 'rdoc/task'
- require 'rubygems/package_task'
- require 'rake/testtask'
-else
-require 'rake/rdoctask'
- require 'rake/gempackagetask'
- require 'rake/runtest'
-end
-
-PROJECT_NAME = 'midilib'
-RDOC_DIR = 'html'
-
-PKG_FILES = FileList[ 'ChangeLog', 'Credits', 'Rakefile',
- 'README.rdoc', 'TODO.rdoc',
- 'examples/**/*',
- 'html/**/*',
- 'install.rb',
- 'lib/**/*.rb',
- 'test/**/*']
-
-task :default => [:package]
-
-spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = PROJECT_NAME
- s.version = `ruby -Ilib -e 'require "midilib/info"; puts MIDI::Version'`.strip
- s.requirements << 'none'
-
- s.require_path = 'lib'
-
- s.files = PKG_FILES.to_a
-
- s.has_rdoc = true
- s.rdoc_options << '--main' << 'README.rdoc'
- s.extra_rdoc_files = ['README.rdoc', 'TODO.rdoc']
-
- s.author = 'Jim Menard'
- s.email = 'jim@jimmenard.com'
- s.homepage = 'http://github.com/jimm/midilib'
- s.rubyforge_project = PROJECT_NAME
-
- s.summary = "MIDI file and event manipulation library"
- s.description = <
-writing standard MIDI files and manipulating MIDI event data.
-EOF
-end
-
-if RUBY_VERSION >= '1.9'
- # Creates a :package task (also named :gem). Also useful are
- # :clobber_package and :repackage.
- Gem::PackageTask.new(spec) do |pkg|
- pkg.need_zip = true
- pkg.need_tar = true
- end
-else
- # Creates a :package task (also named :gem). Also useful are
- # :clobber_package and :repackage.
- Rake::GemPackageTask.new(spec) do |pkg|
- pkg.need_zip = true
- pkg.need_tar = true
- end
-end
-
-# creates an "rdoc" task
-Rake::RDocTask.new do | rd |
- rd.main = 'README.rdoc'
- rd.title = PROJECT_NAME
- rd.rdoc_files.include('README.rdoc', 'TODO.rdoc', 'lib/**/*.rb')
-end
-
-desc "Publish gem"
-task :publish => [:rdoc, :package] do
- version = `ruby -Ilib -e 'require "midilib/info"; puts MIDI::Version'`.strip
- system "gem push pkg/midilib-#{version}.gem"
-end
-
-if RUBY_VERSION >= '1.9'
- Rake::TestTask.new
-else
- task :test do
- Rake::run_tests
- end
-end
-
-task :clean => [:clobber_rdoc, :clobber_package]
28 app/server/vendor/midilib/TODO.rdoc
@@ -1,28 +0,0 @@
-== Bugs
-
-No known bugs. (If that's not a challenge, I don't know what is.)
-
-== Features
-
-* +print_decimal_numbers+ and +print_channel_numbers_from_one+ should be
- associated with sequence, or perhaps track, not event.
-
-* Method to translate event's time_from_start to number of milliseconds from
- start.
-
-* Swing quantizing. (Implied by list email from Carl Youngblood
-
-
-* Implement key signature in SeqReader.
-
-* Format 0 files.
-
-* Format 2 files(?).
-
-== Documentation
-
-* Write better docs.
-
-== Tests
-
-* Tests for Noah Thorp's midilib bug fixes.
BIN app/server/vendor/midilib/examples/NoFences.mid
Binary file not shown.
BIN app/server/vendor/midilib/examples/from_scratch.mid
Binary file not shown.
54 app/server/vendor/midilib/examples/from_scratch.rb
@@ -1,54 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: from_scratch.rb
-#
-# This script shows you how to create a new sequence from scratch and save it
-# to a MIDI file. It creates a file called 'from_scratch.mid'.
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-require 'midilib/consts'
-include MIDI
-
-seq = Sequence.new()
-
-# Create a first track for the sequence. This holds tempo events and stuff
-# like that.
-track = Track.new(seq)
-seq.tracks << track
-track.events << Tempo.new(Tempo.bpm_to_mpq(120))
-track.events << MetaEvent.new(META_SEQ_NAME, 'Sequence Name')
-
-# Create a track to hold the notes. Add it to the sequence.
-track = Track.new(seq)
-seq.tracks << track
-
-# Give the track a name and an instrument name (optional).
-track.name = 'My New Track'
-track.instrument = GM_PATCH_NAMES[0]
-
-# Add a volume controller event (optional).
-track.events << Controller.new(0, CC_VOLUME, 127)
-
-# Add events to the track: a major scale. Arguments for note on and note off
-# constructors are channel, note, velocity, and delta_time. Channel numbers
-# start at zero. We use the new Sequence#note_to_delta method to get the
-# delta time length of a single quarter note.
-track.events << ProgramChange.new(0, 1, 0)
-quarter_note_length = seq.note_to_delta('quarter')
-[0, 2, 4, 5, 7, 9, 11, 12].each do |offset|
- track.events << NoteOn.new(0, 64 + offset, 127, 0)
- track.events << NoteOff.new(0, 64 + offset, 127, quarter_note_length)
-end
-
-# Calling recalc_times is not necessary, because that only sets the events'
-# start times, which are not written out to the MIDI file. The delta times are
-# what get written out.
-
-# track.recalc_times
-
-File.open('from_scratch.mid', 'wb') { |file| seq.write(file) }
30 app/server/vendor/midilib/examples/measures_mbt.rb
@@ -1,30 +0,0 @@
-#!/usr/bin/env ruby
-#
-# usage: measure_mbt.rb midi_file
-#
-# This program loads a sequences and prints out all start-of-notes
-# in a "sequencer-style" manner:
-# Measure:Beat:Tick Channel: Note-name
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-
-seq = MIDI::Sequence.new()
-File.open(ARGV[0], 'rb') { | file | seq.read(file) }
-
-# Get all measures, so events can be mapped to measures:
-measures = seq.get_measures
-
-seq.each { |track|
- track.each { |e|
- if e.kind_of?(MIDI::NoteOn) then
- # Print out start of notes
- e.print_note_names = true
- puts measures.to_mbt(e) + " ch #{e.channel}: #{e.note_to_s}"
- end
- }
-}
28 app/server/vendor/midilib/examples/print_program_changes.rb
@@ -1,28 +0,0 @@
-#! /usr/bin/env ruby
-#
-# Shows use of print_decimal_numbers and print_channel_numbers_from_one.
-
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-
-DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
-
-# Read from MIDI file
-seq = MIDI::Sequence.new()
-
-File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
- # The block we pass in to Sequence.read is called at the end of every
- # track read. It is optional, but is useful for progress reports.
- seq.read(file)
-end
-
-seq.each do |track|
- puts
- puts "*** track name \"#{track.name}\", \"#{track.instrument}\""
- track.each do |e|
- e.print_decimal_numbers = true
- e.print_channel_numbers_from_one = true
- puts e if e.kind_of?(MIDI::ProgramChange)
- end
-end
221 app/server/vendor/midilib/examples/reader2text.rb
@@ -1,221 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: reader2text.rb [midi_file]
-#
-# This script translates a MIDI file into text. It subclasses MIDI::MIDIFile
-# and overrides the methods that are called when various events are seen
-# in the file.
-#
-# For a simpler way to do the same thing, see seq2text.rb.
-#
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-require 'midilib/io/midifile'
-
-DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
-
-class TextTranslator < MIDI::IO::MIDIFile
-
- def initialize(seq, proc = nil)
- super()
- @seq = seq
- @track = nil
- @update_block = block_given?() ? Proc.new() : proc
- end
-
- # Generate a unique number for a channel/note combination. This is used
- # to remember pending note on events.
- def note_hash(chan, note)
- return (chan << 8) + note
- end
-
- # Print a delta time.
- def pdelta
- print "#{@curr_ticks}: "
- end
-
- # The remaining methods are overrides of methods in MIDI::IO::MIDIFile.
-
- def header(format, ntrks, division)
- puts "header: format = #{format}, ntrks = #{ntrks}," +
- " division = #{division}"
-
- @ntrks = ntrks
- @update_block.call(nil, @ntrks, 0) if @update_block
- end
-
- def start_track()
- pdelta()
- puts "track start"
-
- @pending = []
- @chan_mask = 0
- end
-
- def end_track()
- pdelta()
- puts "track end; chans used bitmask = #{@chan_mask}"
- # Write message for any pending note on messages
- @pending.each_with_index do |num, chan|
- puts "pending note off missing for chan #{num >> 8}," +
- " note #{num & 0xff}" if note_obj
- end
- @pending = nil
-
- # call update block
- @update_block.call(@track, @ntrks, @seq.tracks.length) if @update_block
- end
-
- def note_on(chan, note, vel)
- pdelta()
- if vel == 0
- print "(note on, vel 0) "
- note_off(chan, note, 64)
- return
- end
-
- puts "note on chan #{chan}, note #{note}, vel #{vel}"
- @pending << note_hash(chan, note)
- track_uses_channel(chan)
- end
-
- def note_off(chan, note, vel)
- pdelta()
- # Find note on, create note off, connect the two, and remove
- # note on from pending list.
- pnum = note_hash(chan, note)
- @pending.each_with_index do |num, i|
- if pnum == num
- puts "note off chan #{chan}, note #{note}, vel #{vel}"
- @pending.delete_at(i)
- return
- end
- end
- puts "note off with no earlier note on (ch #{chan}, note" +
- " #{note}, vel #{vel})"
- end
-
- def pressure(chan, note, press)
- pdelta()
- puts "pressure chan #{chan}, note #{note}, press #{press}"
- track_uses_channel(chan)
- end
-
- def controller(chan, control, value)
- pdelta()
- puts "controller chan #{chan}, control #{control}, value #{value}"
- track_uses_channel(chan)
- end
-
- def pitch_bend(chan, msb, lsb)
- pdelta()
- puts "pitch bend chan #{chan}, msb #{msb}, lsb #{lsb}"
- track_uses_channel(chan)
- end
-
- def program(chan, program)
- pdelta()
- puts "program chan #{chan}, program #{program}"
- track_uses_channel(chan)
- end
-
- def chan_pressure(chan, press)
- pdelta()
- puts "chan press chan #{chan}, press #{press}"
- track_uses_channel(chan)
- end
-
- def sysex(msg)
- pdelta()
- puts "sysex size #{msg.length}"
- end
-
- def meta_misc(type, msg)
- pdelta()
- puts "meta misc type #{type}, length #{msg.length}"
- end
-
- def sequencer_specific(type, msg)
- pdelta()
- puts "sequencer specific type #{type}, msg #{msg.length}"
- end
-
- def sequence_number(num)
- pdelta()
- puts "sequence number #{num}"
- end
-
- def text(type, msg)
- pdelta()
- msg = MIDI::MetaEvent.bytes_as_str(msg)
- case type
- when MIDI::META_SEQ_NAME
- puts "seq or track name #{msg}"
- when MIDI::META_INSTRUMENT
- puts "instrument name #{msg}"
- when MIDI::META_MARKER
- puts "marker #{msg}"
- else
- puts "text = #{msg}, type = #{type}"
- end
- end
-
- def eot()
- pdelta()
- puts "end of track event"
- end
-
- def time_signature(numer, denom, clocks, qnotes)
- pdelta()
- puts "time sig numer #{numer}, denom #{denom}, clocks #{clocks}," +
- " qnotes #{qnotes}"
- end
-
- def smpte(hour, min, sec, frame, fract)
- pdelta()
- puts "smpte #{hour}:#{min}.#{sec}, frame #{frame}, fract #{fract}"
- end
-
- def tempo(microsecs)
- pdelta()
- bpm = 1.0 / microsecs # quarter notes per microsecond
- bpm *= 1000000.0 # quarter notes per second
- bpm *= 60.0 # quarter notes per minute
- puts "tempo microsecs pqn = #{microsecs} (#{bpm} bpm)"
- end
-
- def key_signature(sharpflat, is_minor)
- pdelta()
- puts "key sig sharpflat #{sharpflat}, is_minor #{is_minor}"
- end
-
- def arbitrary(msg)
- pdelta()
- puts "arbitrary length = #{msg.length}"
- end
-
- def track_uses_channel(chan)
- @chan_mask = @chan_mask | (1 << chan)
- end
-
-end
-
-# ================================================================
-
-seq = MIDI::Sequence.new()
-
-# Specify what class to use when reading the MIDI file.
-seq.reader_class = TextTranslator
-
-File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do | file |
- # The block we pass in to Sequence.read is called at the end of every
- # track read. It is optional, but is useful for progress reports.
- seq.read(file) do |track, num_tracks, i|
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
- end
-end
41 app/server/vendor/midilib/examples/seq2text.rb
@@ -1,41 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: seq2text.rb [midi_file]
-#
-# This script translates a MIDI file into text. It reads the file into
-# a MIDI::Sequence and calls to_s for each event.
-#
-# For a different (and more verbose) way to do the same thing, see
-# reader2tex.rb.
-#
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-
-DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
-
-# Read from MIDI file
-seq = MIDI::Sequence.new()
-
-File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
- # The block we pass in to Sequence.read is called at the end of every
- # track read. It is optional, but is useful for progress reports.
- seq.read(file) do |track, num_tracks, i|
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
- end
-end
-
-seq.each do |track|
- puts "*** track name \"#{track.name}\""
- puts "instrument name \"#{track.instrument}\""
- puts "#{track.events.length} events"
- track.each do |e|
- e.print_decimal_numbers = true # default = false (print hex)
- e.print_note_names = true # default = false (print note numbers)
- puts e
- end
-end
52 app/server/vendor/midilib/examples/split.rb
@@ -1,52 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: split.rb [-x] [midi_file]
-#
-# This script splits a MIDI file into muliple files, one for each track. The
-# output files are named with the track's names. Each file contains a copy of
-# the 0th track, which contains tempo information.
-#
-# If -x is specified, the 0th temp track is not included in each file.
-# Instead, it is output in a separate file named 'tempo_track.mid'.
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-
-DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
-
-# Command line argument processing
-filename = ARGV[0]
-include_tempo_track = true
-if filename == '-x'
- include_tempo_track = false
- filename = ARGV[1]
-end
-
-# Read from MIDI file
-seq = MIDI::Sequence.new()
-
-File.open(filename || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
- # The block we pass in to Sequence.read is called at the end of every
- # track read. It is optional, but is useful for progress reports.
- seq.read(file) do |track, num_tracks, i|
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
- end
-end
-
-t0 = seq.tracks[0]
-unless include_tempo_track
- s = MIDI::Sequence.new
- s.tracks << t0
- File.open("tempo_track.mid", 'wb') { | file | s.write(file) }
-end
-seq.each_with_index do |track, i|
- next unless i > 0
- s = MIDI::Sequence.new
- s.tracks << t0 if include_tempo_track
- s.tracks << track
- File.open("#{track.name}.mid", 'wb') { | file | s.write(file) }
-end
34 app/server/vendor/midilib/examples/strings.rb
@@ -1,34 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: strings.rb [midi_file]
-#
-# Prints all strings (track names, etc.) found in the MIDI file.
-#
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'midilib/sequence'
-require 'midilib/consts'
-
-DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
-
-seq = MIDI::Sequence.new()
-File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
- # The block we pass in to Sequence.read is called at the end of every
- # track read. It is optional, but is useful for progress reports.
- seq.read(file) do |track, num_tracks, i|
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
- end
-end
-
-include MIDI
-seq.each do |track|
- track.each do |event|
- puts event.data if event.kind_of?(MIDI::MetaEvent) &&
- [META_TEXT, META_COPYRIGHT, META_SEQ_NAME, META_INSTRUMENT,
- META_LYRIC, META_CUE, META_MARKER].include?(event.meta_type)
- end
-end
75 app/server/vendor/midilib/examples/transpose.rb
@@ -1,75 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: transpose.rb [--channel|-c channel] [--transpose|-t half_steps]
-# midi_file [output_file]
-#
-# -c channel 1-16; default is 1
-# -t half_steps default = 12 (one octave up)
-#
-
-# Start looking for MIDI module classes in the directory above this one.
-# This forces us to use the local copy, even if there is a previously
-# installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'getoptlong'
-require 'midilib/sequence'
-require 'midilib/io/seqreader'
-require 'midilib/io/seqwriter'
-
-
-def usage
- $stderr.print <
- input_midi_file output_midi_file
-
- --channel|-c channel 1-16; default is 1
- --transpose|-t half_steps default = 12 (one octave up)
-EOF
- exit(1)
-end
-
-transpose = 12
-channel = 0
-
-g = GetoptLong.new(['--transpose', '-t', GetoptLong::REQUIRED_ARGUMENT],
- ['--channel', '-c', GetoptLong::REQUIRED_ARGUMENT])
-g.each do |name, arg|
- case name
- when '--transpose'
- transpose = arg.to_i
- when '--channel'
- channel = arg.to_i - 1
- else
- usage()
- end
-end
-
-usage() unless ARGV.length >= 2
-
-seq = MIDI::Sequence.new()
-File.open(ARGV[0], 'rb') do |file|
- # The block we pass in to Sequence.read is called at the end of every
- # track read. It is optional, but is useful for progress reports.
- seq.read(file) do |num_tracks, i|
- puts "read track #{i} of #{num_tracks}"
- end
-end
-
-seq.each do |track|
- track.each do |event|
- if event.kind_of?(MIDI::NoteEvent) && event.channel == channel
- val = event.note + transpose
- if val < 0 || val > 127
- $stderr.puts "transposition out of range; ignored"
- else
- event.note = val
- end
- end
- end
-end
-
-# Output to named file or stdout.
-file = ARGV[1] ? File.open(ARGV[1], 'wb') : $stdout
-seq.write(file)
-file.close() if ARGV[1]
56 app/server/vendor/midilib/install.rb
@@ -1,56 +0,0 @@
-#! /usr/bin/env ruby
-#
-# usage: install.rb [(--install-dir | -i) install_directory]
-#
-# This script installs midilib into the Ruby site-local library directory.
-#
-# Author:: Jim Menard (mailto:jim@jimmenard.com)
-# Copyright:: Copyright (c) 2003-2013 by Jim Menard
-# License:: Distributed under the same license as Ruby.
-#
-
-require 'getoptlong'
-require 'ftools'
-require 'find'
-
-SOURCE_DIR = 'lib'
-LIB_DIR = 'midilib'
-IO_DIR = File.join(LIB_DIR, 'io')
-
-def instdir
- g = GetoptLong.new(['--install-dir', '-i', GetoptLong::REQUIRED_ARGUMENT])
- g.each do |name, arg|
- if name == '--install-dir'
- return arg
- else
- $stderr.puts "usage: $0 [--install-dir dir]"
- end
- end
-
- begin
- require 'rbconfig'
- libdir = Config::CONFIG['sitedir'] + "/" +
- Config::CONFIG['MAJOR'] + "." +
- Config::CONFIG['MINOR']
- rescue ScriptError
- $LOAD_PATH.each do |l|
- if l =~ /site_ruby/ && l =~ /\d$/ && l !~ /#{PLATFORM}/
- libdir = l
- break
- end
- end
- STDERR.puts "Can't find required file `rbconfig.rb'."
- STDERR.puts "The `midilib' files need to be installed manually in #{libdir}"
- end
- return libdir
-end
-
-INSTALL_DIR = instdir()
-files = Dir.chdir('lib') { Dir['**/*.rb'] }
-
-files.each do |f|
- dir = File.dirname(f)
- target_dir = File.join(INSTALL_DIR, dir)
- File.makedirs(target_dir) unless File.exist?(target_dir)
- File.install(File.join('lib', f), File.join(INSTALL_DIR, f), 0644, true)
-end
16 app/server/vendor/midilib/lib/midilib.rb
@@ -1,16 +0,0 @@
-# = midilib
-#
-# This is the top-level include file for midilib. You can require this
-# file or require individual files from the midilib directory.
-#
-# See the README.rdoc file or http://midilib.rubyforge.org for details.
-
-require 'midilib/info'
-require 'midilib/sequence'
-require 'midilib/track'
-require 'midilib/io/seqreader'
-require 'midilib/io/seqwriter'
-
-# --
-# consts.rb, utils.rb, and event.rb are included by these files.
-# ++
426 app/server/vendor/midilib/lib/midilib/consts.rb
@@ -1,426 +0,0 @@
-# MIDI constants.
-module MIDI
-
- # Number of MIDI channels
- MIDI_CHANNELS = 16
- # Number of note per MIDI channel
- NOTES_PER_CHANNEL = 128
-
- #--
- # Standard MIDI File meta event defs.
- #++
- META_EVENT = 0xff
- META_SEQ_NUM = 0x00
- META_TEXT = 0x01
- META_COPYRIGHT = 0x02
- META_SEQ_NAME = 0x03
- META_INSTRUMENT = 0x04
- META_LYRIC = 0x05
- META_MARKER = 0x06
- META_CUE = 0x07
- META_MIDI_CHAN_PREFIX = 0x20
- META_TRACK_END = 0x2f
- META_SET_TEMPO = 0x51
- META_SMPTE = 0x54
- META_TIME_SIG = 0x58
- META_KEY_SIG = 0x59
- META_SEQ_SPECIF = 0x7f
-
- #--
- # Channel messages
- #++
- # Note, val
- NOTE_OFF = 0x80
- # Note, val
- NOTE_ON = 0x90
- # Note, val
- POLY_PRESSURE = 0xA0
- # Controller #, val
- CONTROLLER = 0xB0
- # Program number
- PROGRAM_CHANGE = 0xC0
- # Channel pressure
- CHANNEL_PRESSURE = 0xD0
- # LSB, MSB
- PITCH_BEND = 0xE0
-
- #--
- # System common messages
- #++
- # System exclusive start
- SYSEX = 0xF0
- # Beats from top: LSB/MSB 6 ticks = 1 beat
- SONG_POINTER = 0xF2
- # Val = number of song
- SONG_SELECT = 0xF3
- # Tune request
- TUNE_REQUEST = 0xF6
- # End of system exclusive
- EOX = 0xF7
-
- #--
- # System realtime messages
- #++
- # MIDI clock (24 per quarter note)
- CLOCK = 0xF8
- # Sequence start
- START = 0xFA
- # Sequence continue
- CONTINUE = 0xFB
- # Sequence stop
- STOP = 0xFC
- # Active sensing (sent every 300 ms when nothing else being sent)
- ACTIVE_SENSE = 0xFE
- # System reset
- SYSTEM_RESET = 0xFF
-
- # Controller numbers
- # = 0 - 31 = continuous, LSB
- # = 32 - 63 = continuous, MSB
- # = 64 - 97 = switches
- CC_MOD_WHEEL = 1
- CC_BREATH_CONTROLLER = 2
- CC_FOOT_CONTROLLER = 4
- CC_PORTAMENTO_TIME = 5
- CC_DATA_ENTRY_MSB = 6
- CC_VOLUME = 7
- CC_BALANCE = 8
- CC_PAN = 10
- CC_EXPRESSION_CONTROLLER = 11
- CC_GEN_PURPOSE_1 = 16
- CC_GEN_PURPOSE_2 = 17
- CC_GEN_PURPOSE_3 = 18
- CC_GEN_PURPOSE_4 = 19
-
- # [32 - 63] are LSB for [0 - 31]
- CC_DATA_ENTRY_LSB = 38
-
- #--
- # Momentaries:
- #++
- CC_SUSTAIN = 64
- CC_PORTAMENTO = 65
- CC_SUSTENUTO = 66
- CC_SOFT_PEDAL = 67
- CC_HOLD_2 = 69
- CC_GEN_PURPOSE_5 = 50
- CC_GEN_PURPOSE_6 = 51
- CC_GEN_PURPOSE_7 = 52
- CC_GEN_PURPOSE_8 = 53
- CC_TREMELO_DEPTH = 92
- CC_CHORUS_DEPTH = 93
- CC_DETUNE_DEPTH = 94
- CC_PHASER_DEPTH = 95
- CC_DATA_INCREMENT = 96
- CC_DATA_DECREMENT = 97
- CC_NREG_PARAM_LSB = 98
- CC_NREG_PARAM_MSB = 99
- CC_REG_PARAM_LSB = 100
- CC_REG_PARAM_MSB = 101
-
- #--
- # Channel mode message values
- #++
- # Val 0 == off, 0x7f == on
- CM_LOCAL_CONTROL = 0x7A
- CM_ALL_NOTES_OFF = 0x7B # Val must be 0
- CM_OMNI_MODE_OFF = 0x7C # Val must be 0
- CM_OMNI_MODE_ON = 0x7D # Val must be 0
- CM_MONO_MODE_ON = 0x7E # Val = # chans
- CM_POLY_MODE_ON = 0x7F # Val must be 0
-
- # Controller names
- CONTROLLER_NAMES = [
- "0",
- "Modulation",
- "Breath Control",
- "3",
- "Foot Controller",
- "Portamento Time",
- "Data Entry",
- "Volume",
- "Balance",
- "9",
- "Pan",
- "Expression Control",
- "12", "13", "14", "15",
- "General Controller 1",
- "General Controller 2",
- "General Controller 3",
- "General Controller 4",
- "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
- "30", "31",
- "32", "33", "34", "35", "36", "37", "38", "39", "40", "41",
- "42", "43", "44", "45", "46", "47", "48", "49", "50", "51",
- "52", "53", "54", "55", "56", "57", "58", "59", "60", "61",
- "62", "63",
- "Sustain Pedal",
- "Portamento",
- "Sostenuto",
- "Soft Pedal",
- "68",
- "Hold 2",
- "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
- "General Controller 5",
- "Tempo Change",
- "General Controller 7",
- "General Controller 8",
- "84", "85", "86", "87", "88", "89", "90",
- "External Effects Depth",
- "Tremolo Depth",
- "Chorus Depth",
- "Detune (Celeste) Depth",
- "Phaser Depth",
- "Data Increment",
- "Data Decrement",
- "Non-Registered Param LSB",
- "Non-Registered Param MSB",
- "Registered Param LSB",
- "Registered Param MSB",
- "102", "103", "104", "105", "106", "107", "108", "109",
- "110", "111", "112", "113", "114", "115", "116", "117",
- "118", "119", "120",
- "Reset All Controllers",
- "Local Control",
- "All Notes Off",
- "Omni Mode Off",
- "Omni Mode On",
- "Mono Mode On",
- "Poly Mode On"
- ]
-
- # General MIDI patch names
- GM_PATCH_NAMES = [
- #--
- # Pianos
- #++
- "Acoustic Grand Piano",
- "Bright Acoustic Piano",
- "Electric Grand Piano",
- "Honky-tonk Piano",
- "Electric Piano 1",
- "Electric Piano 2",
- "Harpsichord",
- "Clavichord",
- #--
- # Tuned Idiophones
- #++
- "Celesta",
- "Glockenspiel",
- "Music Box",
- "Vibraphone",
- "Marimba",
- "Xylophone",
- "Tubular Bells",
- "Dulcimer",
- #--
- # Organs
- #++
- "Drawbar Organ",
- "Percussive Organ",
- "Rock Organ",
- "Church Organ",
- "Reed Organ",
- "Accordion",
- "Harmonica",
- "Tango Accordion",
- #--
- # Guitars
- #++
- "Acoustic Guitar (nylon)",
- "Acoustic Guitar (steel)",
- "Electric Guitar (jazz)",
- "Electric Guitar (clean)",
- "Electric Guitar (muted)",
- "Overdriven Guitar",
- "Distortion Guitar",
- "Guitar harmonics",
- #--
- # Basses
- #++
- "Acoustic Bass",
- "Electric Bass (finger)",
- "Electric Bass (pick)",
- "Fretless Bass",
- "Slap Bass 1",
- "Slap Bass 2",
- "Synth Bass 1",
- "Synth Bass 2",
- #--
- # Strings
- #++
- "Violin",
- "Viola",
- "Cello",
- "Contrabass",
- "Tremolo Strings",
- "Pizzicato Strings",
- "Orchestral Harp",
- "Timpani",
- #--
- # Ensemble strings and voices
- #++
- "String Ensemble 1",
- "String Ensemble 2",
- "SynthStrings 1",
- "SynthStrings 2",
- "Choir Aahs",
- "Voice Oohs",
- "Synth Voice",
- "Orchestra Hit",
- #--
- # Brass
- #++
- "Trumpet",
- "Trombone",
- "Tuba",
- "Muted Trumpet",
- "French Horn",
- "Brass Section",
- "SynthBrass 1",
- "SynthBrass 2",
- #--
- # Reeds
- #++
- "Soprano Sax", # 64
- "Alto Sax",
- "Tenor Sax",
- "Baritone Sax",
- "Oboe",
- "English Horn",
- "Bassoon",
- "Clarinet",
- #--
- # Pipes
- #++
- "Piccolo",
- "Flute",
- "Recorder",
- "Pan Flute",
- "Blown Bottle",
- "Shakuhachi",
- "Whistle",
- "Ocarina",
- #--
- # Synth Leads
- #++
- "Lead 1 (square)",
- "Lead 2 (sawtooth)",
- "Lead 3 (calliope)",
- "Lead 4 (chiff)",
- "Lead 5 (charang)",
- "Lead 6 (voice)",
- "Lead 7 (fifths)",
- "Lead 8 (bass + lead)",
- #--
- # Synth Pads
- #++
- "Pad 1 (new age)",
- "Pad 2 (warm)",
- "Pad 3 (polysynth)",
- "Pad 4 (choir)",
- "Pad 5 (bowed)",
- "Pad 6 (metallic)",
- "Pad 7 (halo)",
- "Pad 8 (sweep)",
- #--
- # Effects
- #++
- "FX 1 (rain)",
- "FX 2 (soundtrack)",
- "FX 3 (crystal)",
- "FX 4 (atmosphere)",
- "FX 5 (brightness)",
- "FX 6 (goblins)",
- "FX 7 (echoes)",
- "FX 8 (sci-fi)",
- #--
- # Ethnic
- #++
- "Sitar",
- "Banjo",
- "Shamisen",
- "Koto",
- "Kalimba",
- "Bag pipe",
- "Fiddle",
- "Shanai",
- #--
- # Percussion
- #++
- "Tinkle Bell",
- "Agogo",
- "Steel Drums",
- "Woodblock",
- "Taiko Drum",
- "Melodic Tom",
- "Synth Drum",
- "Reverse Cymbal",
- #--
- # Sound Effects
- #++
- "Guitar Fret Noise",
- "Breath Noise",
- "Seashore",
- "Bird Tweet",
- "Telephone Ring",
- "Helicopter",
- "Applause",
- "Gunshot"
- ]
-
- # GM drum notes start at 35 (C), so subtrack GM_DRUM_NOTE_LOWEST from your
- # note number before using this array.
- GM_DRUM_NOTE_LOWEST = 35
- # General MIDI drum channel note names.
- GM_DRUM_NOTE_NAMES = [
- "Acoustic Bass Drum", # 35, C
- "Bass Drum 1", # 36, C#
- "Side Stick", # 37, D
- "Acoustic Snare", # 38, D#
- "Hand Clap", # 39, E
- "Electric Snare", # 40, F
- "Low Floor Tom", # 41, F#
- "Closed Hi Hat", # 42, G
- "High Floor Tom", # 43, G#
- "Pedal Hi-Hat", # 44, A
- "Low Tom", # 45, A#
- "Open Hi-Hat", # 46, B
- "Low-Mid Tom", # 47, C
- "Hi Mid Tom", # 48, C#
- "Crash Cymbal 1", # 49, D
- "High Tom", # 50, D#
- "Ride Cymbal 1", # 51, E
- "Chinese Cymbal", # 52, F
- "Ride Bell", # 53, F#
- "Tambourine", # 54, G
- "Splash Cymbal", # 55, G#
- "Cowbell", # 56, A
- "Crash Cymbal 2", # 57, A#
- "Vibraslap", # 58, B
- "Ride Cymbal 2", # 59, C
- "Hi Bongo", # 60, C#
- "Low Bongo", # 61, D
- "Mute Hi Conga", # 62, D#
- "Open Hi Conga", # 63, E
- "Low Conga", # 64, F
- "High Timbale", # 65, F#
- "Low Timbale", # 66, G
- "High Agogo", # 67, G#
- "Low Agogo", # 68, A
- "Cabasa", # 69, A#
- "Maracas", # 70, B
- "Short Whistle", # 71, C
- "Long Whistle", # 72, C#
- "Short Guiro", # 73, D
- "Long Guiro", # 74, D#
- "Claves", # 75, E
- "Hi Wood Block", # 76, F
- "Low Wood Block", # 77, F#
- "Mute Cuica", # 78, G
- "Open Cuica", # 79, G#
- "Mute Triangle", # 80, A
- "Open Triangle" # 81, A#
- ]
-
-end
639 app/server/vendor/midilib/lib/midilib/event.rb
@@ -1,639 +0,0 @@
-require 'midilib/consts'
-require 'midilib/utils'
-
-module MIDI
-
- # The abstract superclass of all MIDI events.
- class Event
-
- # Modifying delta_time does not affect time_from_start. You need to call
- # the event's track's +recalc_time+ method.
- attr_accessor :delta_time
- # The start time of this event from the beginning of the track. This value
- # is held here but is maintained by the track.
- attr_accessor :time_from_start
- # The MIDI status byte. Never includes the channel, which is held
- # separately by MIDI::ChannelEvent.
- attr_reader :status
-
- # Determines if to_s outputs hex note numbers (false, the default) or
- # decimal note names (true).
- attr_accessor :print_note_names
-
- # Determines if to_s outputs numbers as hex (false, the default) or
- # decimal # (true). Delta times are always printed as decimal.
- attr_accessor :print_decimal_numbers
-
- # Determines if to_s outputs MIDI channel numbers from 1-16 instead
- # of the default 0-15.
- attr_accessor :print_channel_numbers_from_one
-
- def initialize(status = 0, delta_time = 0)
- @status = status
- @delta_time = delta_time
- @time_from_start = 0 # maintained by tracks
- end
- protected :initialize
-
- # Returns the raw bytes that are written to a MIDI file or output to a
- # MIDI stream. In MIDI::EVENT this raises a "subclass responsibility"
- # exception.
- def data_as_bytes
- raise "subclass responsibility"
- end
-
- # Quantize this event's time_from_start by moving it to the nearest
- # multiple of +boundary+. See MIDI::Track#quantize. *Note*: does not
- # modify the event's delta_time, though MIDI::Track#quantize calls
- # recalc_delta_from_times after it asks each event to quantize itself.
- def quantize_to(boundary)
- diff = @time_from_start % boundary
- @time_from_start -= diff
- if diff >= boundary / 2
- @time_from_start += boundary
- end
- end
-
- # For sorting. Uses @time_from_start, which is maintained by this event's
- # track. I'm not sure this is necessary, since each track has to
- # maintain its events' time-from-start values anyway.
- def <=>(an_event)
- return @time_from_start <=> an_event.time_from_start
- end
-
- # Returns +val+ as a decimal or hex string, depending upon the value of
- # @print_decimal_numbers.
- def number_to_s(val)
- return @print_decimal_numbers ? val.to_s : ('%02x' % val)
- end
-
- # Returns +val+ as a decimal or hex string, depending upon the value of
- # @print_decimal_numbers.
- def channel_to_s(val)
- val += 1 if @print_channel_numbers_from_one
- return number_to_s(val)
- end
-
- def to_s
- "#{@delta_time}: "
- end
- end
-
- # The abstract superclass of all channel events (events that have a MIDI
- # channel, like notes and program changes).
- class ChannelEvent < Event
- # MIDI channel, 0-15.
- attr_accessor :channel
-
- def initialize(status, channel, delta_time)
- super(status, delta_time)
- @channel = channel
- end
- protected :initialize
-
- def to_s
- return super << "ch #{channel_to_s(@channel)} "
- end
-
- end
-
- # The abstract superclass of all note on, and note off, and polyphonic
- # pressure events.
- class NoteEvent < ChannelEvent
- attr_accessor :note, :velocity
- def initialize(status, channel, note, velocity, delta_time)
- super(status, channel, delta_time)
- @note = note
- @velocity = velocity
- end
- protected :initialize
-
- PITCHES = %w(C C# D D# E F F# G G# A A# B)
-
- # Returns note name as a pitch/octave string like "C4" or "F#6".
- def pch_oct(val=@note)
- pch = val % 12
- oct = (val / 12) - 1
- "#{PITCHES[pch]}#{oct}"
- end
-
- # If @print_note_names is true, returns pch_oct(val) else returns value
- # as a number using number_to_s.
- def note_to_s
- return @print_note_names ? pch_oct(@note) : number_to_s(@note)
- end
-
- def data_as_bytes
- data = []
- data << (@status + @channel)
- data << @note
- data << @velocity
- end
- end
-
- class NoteOn < NoteEvent
- attr_accessor :off
- def initialize(channel = 0, note = 64, velocity = 64, delta_time = 0)
- super(NOTE_ON, channel, note, velocity, delta_time)
- end
-
- def to_s
- return super <<
- "on #{note_to_s} #{number_to_s(@velocity)}"
- end
- end
-
- # Old class name for compatability
- NoteOnEvent = NoteOn
-
- class NoteOff < NoteEvent
- attr_accessor :on
- def initialize(channel = 0, note = 64, velocity = 64, delta_time = 0)
- super(NOTE_OFF, channel, note, velocity, delta_time)
- end
-
- def to_s
- return super <<
- "off #{note_to_s} #{number_to_s(@velocity)}"
- end
- end
-
- # Old class name for compatability
- NoteOffEvent = NoteOff
-
- class PolyPressure < NoteEvent
- def initialize(channel = 0, note = 64, value = 0, delta_time = 0)
- super(POLY_PRESSURE, channel, note, value, delta_time)
- end
-
- def pressure
- return @velocity
- end
- def pressure=(val)
- @velocity = val
- end
- def to_s
- return super <<
- "poly press #{channel_to_s(@channel)} #{note_to_s} #{number_to_s(@velocity)}"
- end
- end
-
- class Controller < ChannelEvent
- attr_accessor :controller, :value
-
- def initialize(channel = 0, controller = 0, value = 0, delta_time = 0)
- super(CONTROLLER, channel, delta_time)
- @controller = controller
- @value = value
- end
-
- def data_as_bytes
- data = []
- data << (@status + @channel)
- data << @controller
- data << @value
- end
-
- def to_s
- return super << "cntl #{number_to_s(@controller)} #{number_to_s(@value)}"
- end
- end
-
- class ProgramChange < ChannelEvent
- attr_accessor :program
-
- def initialize(channel = 0, program = 0, delta_time = 0)
- super(PROGRAM_CHANGE, channel, delta_time)
- @program = program
- end
-
- def data_as_bytes
- data = []
- data << (@status + @channel)
- data << @program
- end
-
- def to_s
- return super << "prog #{number_to_s(@program)}"
- end
- end
-
- class ChannelPressure < ChannelEvent
- attr_accessor :pressure
-
- def initialize(channel = 0, pressure = 0, delta_time = 0)
- super(CHANNEL_PRESSURE, channel, delta_time)
- @pressure = pressure
- end
-
- def data_as_bytes
- data = []
- data << (@status + @channel)
- data << @pressure
- end
-
- def to_s
- return super << "chan press #{number_to_s(@pressure)}"
- end
- end
-
- class PitchBend < ChannelEvent
- attr_accessor :value
-
- def initialize(channel = 0, value = 0, delta_time = 0)
- super(PITCH_BEND, channel, delta_time)
- @value = value
- end
-
- def data_as_bytes
- data = []
- data << (@status + @channel)
- data << (@value & 0x7f) # lsb
- data << ((@value >> 7) & 0x7f) # msb
- end
-
- def to_s
- return super << "pb #{number_to_s(@value)}"
- end
- end
-
- class SystemCommon < Event
- def initialize(status, delta_time)
- super(status, delta_time)
- end
- end
-
- class SystemExclusive < SystemCommon
- attr_accessor :data
-
- def initialize(data, delta_time = 0)
- super(SYSEX, delta_time)
- @data = data
- end
-
- def data_as_bytes
class SongPointer < SystemCommon
- attr_accessor :pointer
-
- def initialize(pointer = 0, delta_time = 0)
- super(SONG_POINTER, delta_time)
- @pointer = pointer
- end
-
- def data_as_bytes
- data = []
- data << @status
- data << ((@pointer >> 8) & 0xff)
- data << (@pointer & 0xff)
- end
-
- def to_s
- return super << "song ptr #{number_to_s(@pointer)}"
- end
- end
-
- class SongSelect < SystemCommon
- attr_accessor :song
-
- def initialize(song = 0, delta_time = 0)
- super(SONG_SELECT, delta_time)
- @song = song
- end
-
- def data_as_bytes
- data = []
- data << @status
- data << @song
- end
-
- def to_s
- return super << "song sel #{number_to_s(@song)}"
- end
- end
-
- class TuneRequest < SystemCommon
- def initialize(delta_time = 0)
- super(TUNE_REQUEST, delta_time)
- end
-
- def data_as_bytes
- data = []
- data << @status
- end
-
- def to_s
- return super << "tune req"
- end
- end
-
- class Realtime < Event
- def initialize(status, delta_time)
- super(status, delta_time)
- end
-
- def data_as_bytes
- data = []
- data << @status
- end
-
- def to_s
- return super << "realtime #{number_to_s(@status)}"
- end
- end
-
- class Clock < Realtime
- def initialize(delta_time = 0)
- super(CLOCK, delta_time)
- end
-
- def to_s
- return super << "clock"
- end
- end
-
- class Start < Realtime
- def initialize(delta_time = 0)
- super(START, delta_time)
- end
- def to_s
- return super << "start"
- end
- end
-
- class Continue < Realtime
- def initialize(delta_time = 0)
- super(CONTINUE, delta_time)
- end
- def to_s
- return super << "continue"
- end
- end
-
- class Stop < Realtime
- def initialize(delta_time = 0)
- super(STOP, delta_time)
- end
- def to_s
- return super << "stop"
- end
- end
-
- class ActiveSense < Realtime
- def initialize(delta_time = 0)
- super(ACTIVE_SENSE, delta_time)
- end
- def to_s
- return super << "act sens"
- end
- end
-
- class SystemReset < Realtime
- def initialize(delta_time = 0)
- super(SYSTEM_RESET, delta_time)
- end
- def to_s
- return super << "sys reset"
- end
- end
-
- class MetaEvent < Event
- attr_reader :meta_type
- attr_reader :data
-
- def self.bytes_as_str(bytes)
- bytes ? bytes.collect { |byte| byte.chr }.join : nil
- end
-
- if RUBY_VERSION >= '1.9'
- def self.str_as_bytes(str)
- str.split(//).collect { |chr| chr.ord }
- end
- else
- def self.str_as_bytes(str)
- str.split(//).collect { |chr| chr[0] }
- end
- end
-
- def initialize(meta_type, data = nil, delta_time = 0)
- super(META_EVENT, delta_time)
- @meta_type = meta_type
- self.data=(data)
- end
-
- def data_as_bytes
- data = []
- data << @status
- data << @meta_type
- data << (@data ? Utils.as_var_len(@data.length) : 0)
- data << @data if @data
- data.flatten
- end
-
- def data_as_str
- MetaEvent.bytes_as_str(@data)
- end
-
- # Stores bytes. If data is a string, splits it into an array of bytes.
- def data=(data)
- case data
- when String
- @data = MetaEvent.str_as_bytes(data)
- else
- @data = data
- end
- end
-
- def to_s
- str = super()
- str << "meta #{number_to_s(@meta_type)} "
- # I know, I know...this isn't OO.
- case @meta_type
- when META_SEQ_NUM
- str << "sequence number"
- when META_TEXT
- str << "text: #{data_as_str}"
- when META_COPYRIGHT
- str << "copyright: #{data_as_str}"
- when META_SEQ_NAME
- str << "sequence or track name: #{data_as_str}"
- when META_INSTRUMENT
- str << "instrument name: #{data_as_str}"
- when META_LYRIC
- str << "lyric: #{data_as_str}"
- when META_MARKER
- str << "marker: #{data_as_str}"
- when META_CUE
- str << "cue point: #{@data}"
- when META_TRACK_END
- str << "track end"
- when META_SMPTE
- str << "smpte"
- when META_TIME_SIG
- str << "time signature"
- when META_KEY_SIG
- str << "key signature"
- when META_SEQ_SPECIF
- str << "sequence specific"
- else
- # Some other possible @meta_type values are handled by subclasses.
- str << "(other)"
- end
- return str
- end
- end
-
- class Marker < MetaEvent
- def initialize(msg, delta_time = 0)
- super(META_MARKER, msg, delta_time)
- end
- end
-
- class Tempo < MetaEvent
-
- MICROSECS_PER_MINUTE = 1_000_000 * 60
-
- # Translates beats per minute to microseconds per quarter note (beat).
- def Tempo.bpm_to_mpq(bpm)
- return MICROSECS_PER_MINUTE / bpm
- end
-
- # Translates microseconds per quarter note (beat) to beats per minute.
- def Tempo.mpq_to_bpm(mpq)
- return MICROSECS_PER_MINUTE.to_f / mpq.to_f
- end
-
- def initialize(msecs_per_qnote, delta_time = 0)
- super(META_SET_TEMPO, msecs_per_qnote, delta_time)
- end
-
- def tempo
- return @data
- end
-
- def tempo=(val)
- @data = val
- end
-
- def data_as_bytes
- data = []
- data << @status
- data << @meta_type
- data << 3
- data << ((@data >> 16) & 0xff)
- data << ((@data >> 8) & 0xff)
- data << (@data & 0xff)
- end
-
- def to_s
- "tempo #{@data} msecs per qnote (#{Tempo.mpq_to_bpm(@data)} bpm)"
- end
- end
-
- # Container for time signature events
- class TimeSig < MetaEvent
-
- # Constructor
- def initialize(numer, denom, clocks, qnotes, delta_time = 0)
- super(META_TIME_SIG, [numer, denom, clocks, qnotes], delta_time)
- end
-
- # Returns the complete event as stored in the sequence
- def data_as_bytes
- data = []
- data << @status
- data << @meta_type
- data << 4
- data << @data[0]
- data << @data[1]
- data << @data[2]
- data << @data[3]
- end
-
- # Calculates the duration (in ticks) for a full measure
- def measure_duration(ppqn)
- (4 * ppqn * @data[0]) / (2**@data[1])
- end
-
- # Returns the numerator (the top digit) for the time signature
- def numerator
- @data[0]
- end
-
- # Returns the denominator of the time signature. Use it as a power of 2
- # to get the displayed (lower-part) digit of the time signature.
- def denominator
- @data[1]
- end
-
- # Returns the metronome tick duration for the time signature. On
- # each quarter note, there's 24 ticks.
- def metronome_ticks
- @data[2]
- end
-
- # Returns the time signature for the event as a string.
- # Example: "time sig 3/4"
- def to_s
- "time sig #{@data[0]}/#{2**@data[1]}"
- end
- end
-
- # Container for key signature events
- class KeySig < MetaEvent
-
- # Constructor
- def initialize(sharpflat, is_minor, delta_time = 0)
- super(META_KEY_SIG, [sharpflat, is_minor], delta_time)
- end
-
- # Returns the complete event as stored in the sequence
- def data_as_bytes
- data = []
- data << @status
- data << @meta_type
- data << 2
- data << @data[0]
- data << (@data[1] ? 1 : 0)
- end
-
- # Returns true if it's a minor key, false if major key
- def minor_key?
- @data[1]
- end
-
- # Returns true if it's a major key, false if minor key
- def major_key?
- !@data[1]
- end
-
- # Returns the number of sharps/flats in the key sig. Negative for flats.
- def sharpflat
- @data[0] > 7 ? @data[0] - 256 : @data[0]
- end
-
- # Returns the key signature as a text string.
- # Example: "key sig A flat major"
- def to_s
- majorkeys = ['C flat', 'G flat', 'D flat', 'A flat', 'E flat', 'B flat', 'F',
- 'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#']
- minorkeys = ['a flat', 'e flat', 'b flat', 'f', 'c', 'g', 'd',
- 'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']
- minor_key? ? "key sig #{minorkeys[sharpflat + 7]} minor" :
- "key sig #{majorkeys[sharpflat + 7]} major"
- end
- end
-
-end
9 app/server/vendor/midilib/lib/midilib/info.rb
@@ -1,9 +0,0 @@
-module MIDI
-
- VERSION_MAJOR = 2
- VERSION_MINOR = 0
- VERSION_TWEAK = 4
- Version = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_TWEAK}"
- Copyright = 'Copyright (c) 2003-2013 by Jim Menard
-
-end
466 app/server/vendor/midilib/lib/midilib/io/midifile.rb
@@ -1,466 +0,0 @@
-require 'midilib/consts'
-
-if RUBY_VERSION < '1.9'
- class IO
- def readbyte
- c = getc()
- raise 'unexpected EOF' unless c
- c
- end
- end
-end
-
-module MIDI
-
- module IO
-
- # A MIDIFile parses a MIDI file and calls methods when it sees MIDI events.
- # Most of the methods are stubs. To do anything interesting with the events,
- # override these methods (those between the "The rest of these are NOPs by
- # default" and "End of NOPs" comments).
- #
- # See SeqReader for a subclass that uses these methods to create Event
- # objects.
- class MIDIFile
-
- MThd_BYTE_ARRAY = [77, 84, 104, 100] # "MThd"
- MTrk_BYTE_ARRAY = [77, 84, 114, 107] # "MTrk"
-
- # This array is indexed by the high half of a status byte. Its
- # value is either the number of bytes needed (1 or 2) for a channel
- # message, or 0 if it's not a channel message.
- NUM_DATA_BYTES = [
- 0, 0, 0, 0, 0, 0, 0, 0, # 0x00 - 0x70
- 2, 2, 2, 2, 1, 1, 2, 0 # 0x80 - 0xf0
- ]
-
- attr_accessor :curr_ticks # Current time, from delta-time in MIDI file
- attr_accessor :ticks_so_far # Number of delta-time ticks so far
- attr_accessor :bytes_to_be_read # Counts number of bytes expected
-
- attr_accessor :no_merge # true means continued sysex are not collapsed
- attr_accessor :skip_init # true if initial garbage should be skipped
-
- # Raw data info
- attr_accessor :raw_time_stamp_data
- attr_accessor :raw_var_num_data
- attr_accessor :raw_data
-
- def initialize
- @no_merge = false
- @skip_init = true
- @io = nil
- @bytes_to_be_read = 0
- @msg_buf = nil
- end
-
- # The only public method. Each MIDI event in the file causes a
- # method to be called.
- def read_from(io)
- error('must specify non-nil input stream') if io.nil?
- @io = io
-
- ntrks = read_header()
- error('No tracks!') if ntrks <= 0
-
- ntrks.times { read_track() }
- end
-
- # This default getc implementation tries to read a single byte
- # from io and returns it as an integer.
- def getc
- @bytes_to_be_read -= 1
- @io.readbyte()
- end
-
- # Return the next +n+ bytes from @io as an array.
- def get_bytes(n)
- buf = []
- n.times { buf << getc() }
- buf
- end
-
- # The default error handler.
- def error(str)
- loc = @io.tell() - 1
- raise "#{self.class.name} error at byte #{loc} (0x#{'%02x' % loc}): #{str}"
- end
-
- # The rest of these are NOPs by default.
-
- # MIDI header.
- def header(format, ntrks, division)
- end
-
- def start_track(bytes_to_be_read)
- end
-
- def end_track()
- end
-
- def note_on(chan, note, vel)
- end
-
- def note_off(chan, note, vel)
- end
-
- def pressure(chan, note, press)
- end
-
- def controller(chan, control, value)
- end
-
- def pitch_bend(chan, msb, lsb)
- end
-
- def program(chan, program)
- end
-
- def chan_pressure(chan, press)
- end
-
- def sysex(msg)
- end
-
- def meta_misc(type, msg)
- end
-
- def sequencer_specific(type, msg)
- end
-
- def sequence_number(num)
- end
-
- def text(type, msg)
- end
-
- def eot()
- end
-
- def time_signature(numer, denom, clocks, qnotes)
- end
-
- def smpte(hour, min, sec, frame, fract)
- end
-
- def tempo(microsecs)
- end
-
- def key_signature(sharpflat, is_minor)
- end
-
- def arbitrary(msg)
- end
-
- # End of NOPs.
-
-
- # Read through 'MThd' or 'MTrk' header string. If skip is true, attempt
- # to skip initial trash. If there is an error, #error is called.
- def read_mt_header_string(bytes, skip)
- b = []
- bytes_to_read = 4
- while true
- data = get_bytes(bytes_to_read)
- b += data
- if b.length < 4
- error("unexpected EOF while trying to read header string #{s}")
- end
-
- # See if we found the bytes we're looking for
- return if b == bytes
-
- if skip # Try again with the next char
- i = b[1..-1].index(bytes[0])
- if i.nil?
- b = []
- bytes_to_read = 4
- else
- b = b[i..-1]
- bytes_to_read = 4 - i
- end
- else
- error("header string #{bytes.collect{|b| b.chr}.join} not found")
- end
- end
- end
-
- # Read a header chunk.
- def read_header
- @bytes_to_be_read = 0
- read_mt_header_string(MThd_BYTE_ARRAY, @skip_init) # "MThd"
-
- @bytes_to_be_read = read32()
- format = read16()
- ntrks = read16()
- division = read16()
-
- header(format, ntrks, division)
-
- # Flush any extra stuff, in case the length of the header is not 6
- if @bytes_to_be_read > 0
- get_bytes(@bytes_to_be_read)
- @bytes_to_be_read = 0
- end
-
- return ntrks
- end
-
- # Read a track chunk.
- def read_track
- c = c1 = type = needed = 0
- sysex_continue = false # True if last msg was unfinished
- running = false # True when running status used
- status = 0 # (Possibly running) status byte
-
- @bytes_to_be_read = 0
- read_mt_header_string(MTrk_BYTE_ARRAY, false)
-
- @bytes_to_be_read = read32()
- @curr_ticks = @ticks_so_far = 0
-
- start_track()
-
- while @bytes_to_be_read > 0
- @curr_ticks = read_var_len() # Delta time
- @ticks_so_far += @curr_ticks
-
- # Copy raw var num data into raw time stamp data
- @raw_time_stamp_data = @raw_var_num_data.dup()
-
- c = getc() # Read first byte
-
- if sysex_continue && c != EOX
- error("didn't find expected continuation of a sysex")
- end
-
- if (c & 0x80).zero? # Running status?
- error('unexpected running status') if status.zero?
- running = true
- else
- status = c
- running = false
- end
-
- needed = NUM_DATA_BYTES[(status >> 4) & 0x0f]
-
- if needed.nonzero? # i.e., is it a channel message?
- c1 = running ? c : (getc() & 0x7f)
-
- # The "& 0x7f" here may seem unnecessary, but I've seen
- # "bad" MIDI files that had, for example, volume bytes
- # with the upper bit set. This code should not harm
- # proper data.
- chan_message(running, status, c1,
- (needed > 1) ? (getc() & 0x7f) : 0)
- next
- end
-
- case c
- when META_EVENT # Meta event
- type = getc()
- msg_init()
- msg_read(read_var_len())
- meta_event(type)
- when SYSEX # Start of system exclusive
- msg_init()
- msg_add(SYSEX)
- c = msg_read(read_var_len())
-
- if c == EOX || !@no_merge
- handle_sysex(msg())
- else
- sysex_continue = true
- end
- when EOX # Sysex continuation or arbitrary stuff
- msg_init() if !sysex_continue
- c = msg_read(read_var_len())
-
- if !sysex_continue
- handle_arbitrary(msg())
- elsif c == EOX
- handle_sysex(msg())
- sysex_continue = false
- end
- else
- bad_byte(c)
- end
- end
- end_track()
- end
-
- # Handle an unexpected byte.
- def bad_byte(c)
- error(sprintf("unexpected byte: 0x%02x", c))
- end
-
- # Handle a meta event.
- def meta_event(type)
- m = msg() # Copy of internal message buffer
-
- # Create raw data array
- @raw_data = []
- @raw_data << META_EVENT
- @raw_data << type
- @raw_data << @raw_var_num_data
- @raw_data << m
- @raw_data.flatten!
-
- case type
- when META_SEQ_NUM
- sequence_number((m[0] << 8) + m[1])
- when META_TEXT, META_COPYRIGHT, META_SEQ_NAME, META_INSTRUMENT,
- META_LYRIC, META_MARKER, META_CUE, 0x08, 0x09, 0x0a,
- 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
- text(type, m)
- when META_TRACK_END
- eot()
- when META_SET_TEMPO
- tempo((m[0] << 16) + (m[1] << 8) + m[2])
- when META_SMPTE
- smpte(m[0], m[1], m[2], m[3], m[4])
- when META_TIME_SIG
- time_signature(m[0], m[1], m[2], m[3])
- when META_KEY_SIG
- key_signature(m[0], m[1] == 0 ? false : true)
- when META_SEQ_SPECIF
- sequencer_specific(type, m)
- else
- meta_misc(type, m)
- end
- end
-
- # Handle a channel message (note on, note off, etc.)
- def chan_message(running, status, c1, c2)
- @raw_data = []
- @raw_data << status unless running
- @raw_data << c1
- @raw_data << c2
-
- chan = status & 0x0f
-
- case (status & 0xf0)
- when NOTE_OFF
- note_off(chan, c1, c2)
- when NOTE_ON
- note_on(chan, c1, c2)
- when POLY_PRESSURE
- pressure(chan, c1, c2)
- when CONTROLLER
- controller(chan, c1, c2)
- when PITCH_BEND
- pitch_bend(chan, c1, c2)
- when PROGRAM_CHANGE
- program(chan, c1)
- when CHANNEL_PRESSURE
- chan_pressure(chan, c1)
- else
- error("illegal chan message 0x#{'%02x' % (status & 0xf0)}\n")
- end
- end
-
- # Copy message into raw data array, then call sysex().
- def handle_sysex(msg)
- @raw_data = msg.dup()
- sysex(msg)
- end
-
- # Copy message into raw data array, then call arbitrary().
- def handle_arbitrary(msg)
- @raw_data = msg.dup()
- arbitrary(msg)
- end
-
- # Read and return a sixteen bit value.
def read16
- val = (getc() << 8) + getc()
- val = -(val & 0x7fff) if (val & 0x8000).nonzero?
- return val
- end
-
- # Read and return a 32-bit value.
- def read32
- val = (getc() << 24) + (getc() << 16) + (getc() << 8) +
- getc()
- val = -(val & 0x7fffffff) if (val & 0x80000000).nonzero?
- return val
- end
-
- # Read a varlen value.
- def read_var_len
- @raw_var_num_data = []
- c = getc()
- @raw_var_num_data << c
- val = c
- if (val & 0x80).nonzero?
- val &= 0x7f
- while true
- c = getc()
- @raw_var_num_data << c
- val = (val << 7) + (c & 0x7f)
- break if (c & 0x80).zero?
- end
- end
- return val
- end
-
- # Write a sixteen-bit value.
- def write16(val)
- val = (-val) | 0x8000 if val < 0
- putc((val >> 8) & 0xff)
- putc(val & 0xff)
- end
-
- # Write a 32-bit value.
- def write32(val)
- val = (-val) | 0x80000000 if val < 0
- putc((val >> 24) & 0xff)
- putc((val >> 16) & 0xff)
- putc((val >> 8) & 0xff)
- putc(val & 0xff)
- end
-
- # Write a variable length value.
- def write_var_len(val)
- if val.zero?
- putc(0)
- return
- end
-
- buf = []
-
- buf << (val & 0x7f)
- while (value >>= 7) > 0
- buf << (val & 0x7f) | 0x80
- end
-
- buf.reverse.each { |b| putc(b) }
- end
-
- # Add a byte to the current message buffer.
- def msg_add(c)
- @msg_buf << c
- end
-
- # Read and add a number of bytes to the message buffer. Return
- # the last byte (so we can see if it's an EOX or not).
- def msg_read(n_bytes)
- @msg_buf += get_bytes(n_bytes)
- @msg_buf.flatten!
- return @msg_buf[-1]
- end
-
- # Initialize the internal message buffer.
- def msg_init
- @msg_buf = []
- end
-
- # Return a copy of the internal message buffer.
- def msg
- return @msg_buf.dup()
- end
-
- end
-
- end
-end
202 app/server/vendor/midilib/lib/midilib/io/seqreader.rb
@@ -1,202 +0,0 @@
-require 'midilib/io/midifile'
-require 'midilib/track'
-require 'midilib/event'
-
-module MIDI
-
- module IO
-
- # Reads MIDI files. As a subclass of MIDIFile, this class implements the
- # callback methods for each MIDI event and use them to build Track and
- # Event objects and give the tracks to a Sequence.
- #
- # We append new events to the end of a track's event list, bypassing a
- # call to Track.#add. This means that we must call Track.recalc_times at
- # the end of the track so it can update each event with its time from
- # the track's start (see end_track below).
- #
- # META_TRACK_END events are not added to tracks. This way, we don't have
- # to worry about making sure the last event is always a track end event.
- # We rely on the SeqWriter to append a META_TRACK_END event to each
- # track when it is output.
-
- class SeqReader < MIDIFile
-
- # The optional proc block is called once at the start of the file and
- # again at the end of each track. There are three arguments to the
- # block: the track, the track number (1 through _n_), and the total
- # number of tracks.
- def initialize(seq, proc = nil) # :yields: track, num_tracks, index
- super()
- @seq = seq
- @track = nil
- @chan_mask = 0
- @update_block = block_given?() ? Proc.new() : proc
- end
-
- def header(format, ntrks, division)
- @seq.format = format
- @seq.ppqn = division
-
- @ntrks = ntrks
- @update_block.call(nil, @ntrks, 0) if @update_block
- end
-
- def start_track()
- @track = Track.new(@seq)
- @seq.tracks << @track
-
- @pending = []
- end
-
- def end_track()
- # Turn off any pending note on messages
- @pending.each { |on| make_note_off(on, 64) }
- @pending = nil
-
- # Don't bother adding the META_TRACK_END event to the track.
- # This way, we don't have to worry about making sure the
- # last event is always a track end event.
-
- # Let the track calculate event times from start of track. This is
- # in lieu of calling Track.add for each event.
- @track.recalc_times()
-
- # Store bitmask of all channels used into track
- @track.channels_used = @chan_mask
-
- # call update block
- @update_block.call(@track, @ntrks, @seq.tracks.length) if @update_block
- end
-
- def note_on(chan, note, vel)
- if vel == 0
- note_off(chan, note, 64)
- return
- end
-
- on = NoteOn.new(chan, note, vel, @curr_ticks)
- @track.events << on
- @pending << on
- track_uses_channel(chan)
- end
-
- def note_off(chan, note, vel)
- # Find note on, create note off, connect the two, and remove
- # note on from pending list.
- @pending.each_with_index do |on, i|
- if on.note == note && on.channel == chan
- make_note_off(on, vel)
- @pending.delete_at(i)
- return
- end
- end
- $stderr.puts "note off with no earlier note on (ch #{chan}, note" +
- " #{note}, vel #{vel})" if $DEBUG
- end
-
- def make_note_off(on, vel)
- off = NoteOff.new(on.channel, on.note, vel, @curr_ticks)
- @track.events << off
- on.off = off
- off.on = on
- end
-
- def pressure(chan, note, press)
- @track.events << PolyPressure.new(chan, note, press, @curr_ticks)
- track_uses_channel(chan)
- end
-
- def controller(chan, control, value)
- @track.events << Controller.new(chan, control, value, @curr_ticks)
- track_uses_channel(chan)
- end
-
- def pitch_bend(chan, lsb, msb)
- @track.events << PitchBend.new(chan, (msb << 7) + lsb, @curr_ticks)
- track_uses_channel(chan)
- end
-
- def program(chan, program)
- @track.events << ProgramChange.new(chan, program, @curr_ticks)
- track_uses_channel(chan)
- end
-
- def chan_pressure(chan, press)
- @track.events << ChannelPressure.new(chan, press, @curr_ticks)
- track_uses_channel(chan)
- end
-
- def sysex(msg)
- @track.events << SystemExclusive.new(msg, @curr_ticks)
- end
-
- def meta_misc(type, msg)
- @track.events << MetaEvent.new(type, msg, @curr_ticks)
- end
-
- # --
- # def sequencer_specific(type, msg)
- # end
-
- # def sequence_number(num)
- # end
- # ++
-
- def text(type, msg)
- case type
- when META_TEXT, META_LYRIC, META_CUE
- @track.events << MetaEvent.new(type, msg, @curr_ticks)
- when META_SEQ_NAME, META_COPYRIGHT
- @track.events << MetaEvent.new(type, msg, 0)
- when META_INSTRUMENT
- @track.instrument = msg
- when META_MARKER
- @track.events << Marker.new(msg, @curr_ticks)
- else
- $stderr.puts "text = #{msg}, type = #{type}" if $DEBUG
- end
- end
-
- # --
- # Don't bother adding the META_TRACK_END event to the track. This way,
- # we don't have to worry about always making sure the last event is
- # always a track end event. We just have to make sure to write one when
- # the track is output back to a file.
- # def eot()
- # @track.events << MetaEvent.new(META_TRACK_END, nil, @curr_ticks)
- # end
- # ++
-
- def time_signature(numer, denom, clocks, qnotes)
- @seq.time_signature(numer, denom, clocks, qnotes)
- @track.events << TimeSig.new(numer, denom, clocks, qnotes, @curr_ticks)
- end
-
- # --
- # def smpte(hour, min, sec, frame, fract)
- # end
- # ++
-
- def tempo(microsecs)
- @track.events << Tempo.new(microsecs, @curr_ticks)
- end
-
- def key_signature(sharpflat, is_minor)
- @track.events << KeySig.new(sharpflat, is_minor, @curr_ticks)
- end
-
- # --
- # def arbitrary(msg)
- # end
- # ++
-
- # Return true if the current track uses the specified channel.
- def track_uses_channel(chan)
- @chan_mask = @chan_mask | (1 << chan)
- end
-
- end
-
- end
-end
152 app/server/vendor/midilib/lib/midilib/io/seqwriter.rb
@@ -1,152 +0,0 @@
-# Writes MIDI files.
-
-require 'midilib/event'
-require 'midilib/utils'
-
-module MIDI
-
- module IO
-
- class SeqWriter
-
- def initialize(seq, proc = nil) # :yields: num_tracks, index
- @seq = seq
- @update_block = block_given?() ? Proc.new() : proc
- end
-
- # Writes a MIDI format 1 file.
- def write_to(io)
- @io = io
- @bytes_written = 0
- write_header()
- @update_block.call(nil, @seq.tracks.length, 0) if @update_block
- @seq.tracks.each_with_index do |track, i|
- write_track(track)
- @update_block.call(track, @seq.tracks.length, i) if @update_block
- end
- end
-
- def write_header
- @io.print 'MThd'
- write32(6)
- write16(1) # Ignore sequence format; write as format 1
- write16(@seq.tracks.length)
- write16(@seq.ppqn)
- end
-
- def write_track(track)
- @io.print 'MTrk'
- track_size_file_pos = @io.tell()
- write32(0) # Dummy byte count; overwritten later
- @bytes_written = 0 # Reset after previous write
-
- write_instrument(track.instrument)
-
- prev_event = nil
- prev_status = 0
- track.events.each do |event|
- if !event.kind_of?(Realtime)
- write_var_len(event.delta_time)
- end
-
- data = event.data_as_bytes()
- status = data[0] # status byte plus channel number, if any
-
- # running status byte
- status = possibly_munge_due_to_running_status_byte(data, prev_status)
-
- @bytes_written += write_bytes(data)
-
- prev_event = event
- prev_status = status
- end
-
- # Write track end event.
- event = MetaEvent.new(META_TRACK_END)
- write_var_len(0)
- @bytes_written += write_bytes(event.data_as_bytes())
-
- # Go back to beginning of track data and write number of bytes,
- # then come back here to end of file.
- @io.seek(track_size_file_pos)
- write32(@bytes_written)
- @io.seek(0, ::IO::SEEK_END)
- end
-
- # If we can use a running status byte, delete the status byte from
- # the given data. Return the status to remember for next time as the
- # running status byte for this event.
- def possibly_munge_due_to_running_status_byte(data, prev_status)
- status = data[0]
- return status if status >= 0xf0 || prev_status >= 0xf0
-
- chan = (status & 0x0f)
- return status if chan != (prev_status & 0x0f)
-
- status = (status & 0xf0)
- prev_status = (prev_status & 0xf0)
-
- # Both events are on the same channel. If the two status bytes are
- # exactly the same, the rest is trivial. If it's note on/note off,
- # we can combine those further.
- if status == prev_status
- data[0,1] = [] # delete status byte from data
- return status + chan
- elsif status == NOTE_OFF && data[2] == 64
- # If we see a note off and the velocity is 64, we can store
- # a note on with a velocity of 0. If the velocity isn't 64
- # then storing a note on would be bad because the would be
- # changed to 64 when reading the file back in.
- data[2] = 0 # set vel to 0; do before possible shrinking
- status = NOTE_ON + chan
- if prev_status == NOTE_ON
- data[0,1] = [] # delete status byte
- else
- data[0] = status
- end
- return status
- else
- # Can't compress data
- return status + chan
- end
- end
-
- def write_instrument(instrument)
- event = MetaEvent.new(META_INSTRUMENT, instrument)
- write_var_len(0)
- data = event.data_as_bytes()
- @bytes_written += write_bytes(data)
- end
-
- def write_var_len(val)
- buffer = Utils.as_var_len(val)
- @bytes_written += write_bytes(buffer)
- end
-
- def write16(val)
- val = (-val | 0x8000) if val < 0
-
- buffer = []
- @io.putc((val >> 8) & 0xff)
- @io.putc(val & 0xff)
- @bytes_written += 2
- end
-
- def write32(val)
- val = (-val | 0x80000000) if val < 0
-
- @io.putc((val >> 24) & 0xff)
- @io.putc((val >> 16) & 0xff)
- @io.putc((val >> 8) & 0xff)
- @io.putc(val & 0xff)
- @bytes_written += 4
- end
-
- def write_bytes(bytes)
- bytes.each { |b| @io.putc(b) }
- bytes.length
- end
- end
-
- end
-end
80 app/server/vendor/midilib/lib/midilib/measure.rb
@@ -1,80 +0,0 @@
-require 'midilib/consts'
-
-module MIDI
-
- # The Measure class contains information about a measure from the sequence.
- # The measure data is based on the time signature information from the sequence
- # and is not stored in the sequence itself
- class Measure
- # The numerator (top digit) for the measure's time signature
- attr_reader :numerator
- # The denominator for the measure's time signature
- attr_reader :denominator
- # Start clock tick for the measure
- attr_reader :start
- # End clock tick for the measure (inclusive)
- attr_reader :end
- # The measure number (1-based)
- attr_reader :measure_number
- # The metronome tick for the measure
- attr_reader :metronome_ticks
-
- # Constructor
- def initialize(meas_no, start_time, duration, numer, denom, met_ticks)
- @measure_number = meas_no
- @start = start_time
- @end = start_time + duration - 1
- @numerator = numer
- @denominator = denom
- @metronome_ticks = met_ticks
- end
-
- # Returns a detailed string with information about the measure
- def to_s
- t = "#{@numerator}/#{2**@denominator}"
- m = @metronome_ticks.to_f / 24
- "measure #{@measure_number} #{@start}-#{@end} #{t} #{m} qs metronome"
- end
-
- # Returns +true+ if the event is in the measure
- def contains_event?(e)
- (e.time_from_start >= @start) && (e.time_from_start <= @end)
- end
- end
-
- # A specialized container for MIDI::Measure objects, which can be use to map
- # event times to measure numbers. Please note that this object has to be remade
- # when events are deleted/added in the sequence.
- class Measures < Array
- # The highest event time in the sequence (at the time when the
- # object was created)
- attr_reader :max_time
-
- # The ppqd from the sequence
- attr_reader :ppqd
-
- # Constructor
- def initialize(max_time, ppqd)
- super(0)
- @max_time = max_time
- @ppqd = ppqd
- end
-
- # Returns the MIDI::Measure object where the event is located.
- # Returns +nil+ if the event isn't found in the container (should
- # never happen if the MIDI::Measures object is up to date).
- def measure_for_event(e)
- detect { |m| m.contains_event?(e) }
- end
-
- # Returns the event's time as a formatted MBT string (Measure:Beat:Ticks)
- # as found in MIDI sequencers.
- def to_mbt(e)
- m = measure_for_event(e)
- b = (e.time_from_start.to_f - m.start.to_f) / @ppqd
- b *= 24 / m.metronome_ticks
- sprintf("%d:%02d:%03d", m.measure_number, b.to_i + 1, (b - b.to_i) * @ppqd)
- end
- end
-
-end
196 app/server/vendor/midilib/lib/midilib/sequence.rb
@@ -1,196 +0,0 @@
-require 'midilib/io/seqreader'
-require 'midilib/io/seqwriter'
-require 'midilib/measure.rb'
-
-module MIDI
-
- # A MIDI::Sequence contains MIDI::Track objects.
- class Sequence
-
- include Enumerable
-
- UNNAMED = 'Unnamed Sequence'
- DEFAULT_TEMPO = 120
-
- NOTE_TO_LENGTH = {
- 'whole' => 4.0,
- 'half' => 2.0,
- 'quarter' => 1.0,
- 'eighth' => 0.5,
- '8th' => 0.5,
- 'sixteenth' => 0.25,
- '16th' => 0.25,
- 'thirty second' => 0.125,
- 'thirtysecond' => 0.125,
- '32nd' => 0.125,
- 'sixty fourth' => 0.0625,
- 'sixtyfourth' => 0.0625,
- '64th' => 0.0625
- }
-
- # Array with all tracks for the sequence
- attr_accessor :tracks
- # Pulses (i.e. clocks) Per Quarter Note resolution for the sequence
- attr_accessor :ppqn
- # The MIDI file format (0, 1, or 2)
- attr_accessor :format
- attr_accessor :numer, :denom, :clocks, :qnotes
- # The class to use for reading MIDI from a stream. The default is
- # MIDI::IO::SeqReader. You can change this at any time.
- attr_accessor :reader_class
- # The class to use for writeing MIDI from a stream. The default is
- # MIDI::IO::SeqWriter. You can change this at any time.
- attr_accessor :writer_class
-
- def initialize
- @tracks = Array.new()
- @ppqn = 480
-
- # Time signature
- @numer = 4 # Numer + denom = 4/4 time default
- @denom = 2
- @clocks = 24 # Bug fix Nov 11, 2007 - this is not the same as ppqn!
- @qnotes = 8
-
- @reader_class = IO::SeqReader
- @writer_class = IO::SeqWriter
- end
-
- # Sets the time signature.
- def time_signature(numer, denom, clocks, qnotes)
- @numer = numer
- @denom = denom
- @clocks = clocks
- @qnotes = qnotes
- end
-
- # Returns the song tempo in beats per minute.
- def beats_per_minute
- return DEFAULT_TEMPO if @tracks.nil? || @tracks.empty?
- event = @tracks.first.events.detect { |e| e.kind_of?(MIDI::Tempo) }
- return event ? (Tempo.mpq_to_bpm(event.tempo)) : DEFAULT_TEMPO
- end
- alias_method :bpm, :beats_per_minute
- alias_method :tempo, :beats_per_minute
-
- # Pulses (also called ticks) are the units of delta times and event
- # time_from_start values. This method converts a number of pulses to a
- # float value that is a time in seconds.
- def pulses_to_seconds(pulses)
- (pulses.to_f / @ppqn.to_f / beats_per_minute()) * 60.0
- end
-
- # Given a note length name like "whole", "dotted quarter", or "8th
- # triplet", return the length of that note in quarter notes as a delta
- # time.
- def note_to_delta(name)
- return length_to_delta(note_to_length(name))
- end
-
- # Given a note length name like "whole", "dotted quarter", or "8th
- # triplet", return the length of that note in quarter notes as a
- # floating-point number, suitable for use as an argument to
- # length_to_delta.
- #
- # Legal names are any value in NOTE_TO_LENGTH, optionally prefixed by
- # "dotted_" and/or suffixed by "_triplet". So, for example,
- # "dotted_quarter_triplet" returns the length of a dotted quarter-note
- # triplet and "32nd" returns 1/32.
- def note_to_length(name)
- name.strip!
- name =~ /^(dotted)?(.*?)(triplet)?$/
- dotted, note_name, triplet = $1, $2, $3
- note_name.strip!
- mult = 1.0
- mult = 1.5 if dotted
- mult /= 3.0 if triplet
- len = NOTE_TO_LENGTH[note_name]
- raise "Sequence.note_to_length: \"#{note_name}\" not understood in \"#{name}\"" unless len
- return len * mult
- end
-
- # Translates +length+ (a multiple of a quarter note) into a delta time.
- # For example, 1 is a quarter note, 1.0/32.0 is a 32nd note, 1.5 is a
- # dotted quarter, etc. Be aware when using division; 1/32 is zero due to
- # integer mathematics and rounding. Use floating-point numbers like 1.0
- # and 32.0. This method always returns an integer.
- #
- # See also note_to_delta and note_to_length.
- def length_to_delta(length)
- return (@ppqn * length).to_i
- end
-
- # Returns the name of the first track (track zero). If there are no
- # tracks, returns UNNAMED.
- def name
- return UNNAMED if @tracks.empty?
- return @tracks.first.name()
- end
-
- # Hands the name to the first track. Does nothing if there are no tracks.
- def name=(name)
- return if @tracks.empty?
- @tracks.first.name = name
- end
-
- # Reads a MIDI stream.
- def read(io, proc = nil) # :yields: track, num_tracks, index
- reader = @reader_class.new(self, block_given?() ? Proc.new() : proc)
- reader.read_from(io)
- end
-
- # Writes to a MIDI stream.
- def write(io, proc = nil) # :yields: track, num_tracks, index
- writer = @writer_class.new(self, block_given?() ? Proc.new() : proc)
- writer.write_to(io)
- end
-
- # Iterates over the tracks.
- def each # :yields: track
- @tracks.each { |track| yield track }
- end
-
- # Returns a Measures object, which is an array container for all measures
- # in the sequence
- def get_measures
- # Collect time sig events and scan for last event time
- time_sigs = []
- max_pos = 0
- @tracks.each do |t|
- t.each do |e|
- time_sigs << e if e.kind_of?(MIDI::TimeSig)
- max_pos = e.time_from_start if e.time_from_start > max_pos
- end
- end
- time_sigs.sort { |x,y| x.time_from_start <=> y.time_from_start }
-
- # Add a "fake" time sig event at the very last position of the sequence,
- # just to make sure the whole sequence is calculated.
- t = MIDI::TimeSig.new(4, 2, 24, 8, 0)
- t.time_from_start = max_pos
- time_sigs << t
-
- # Default to 4/4
- measure_length = @ppqn * 4
- oldnumer, olddenom, oldbeats = 4, 2, 24
-
- measures = MIDI::Measures.new(max_pos, @ppqn)
- curr_pos = 0
- curr_meas_no = 1
- time_sigs.each do |te|
- meas_count = (te.time_from_start - curr_pos) / measure_length
- meas_count += 1 if (te.time_from_start - curr_pos) % measure_length > 0
- 1.upto(meas_count) do |i|
- measures << MIDI::Measure.new(curr_meas_no, curr_pos, measure_length,
- oldnumer, olddenom, oldbeats)
- curr_meas_no += 1
- curr_pos += measure_length
- end
- oldnumer, olddenom, oldbeats = te.numerator, te.denominator, te.metronome_ticks
- measure_length = te.measure_duration(@ppqn)
- end
- measures
- end
-
- end
-end
179 app/server/vendor/midilib/lib/midilib/track.rb
@@ -1,179 +0,0 @@
-require 'midilib/event'
-
-module MIDI
-
- # This is taken from
- # http://github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb
- # with permission from Adam Murray, who originally suggested this fix.
- # See http://wiki.github.com/adamjmurray/cosy/midilib-notes for details.
- # First we need to add some API infrastructure:
- class MIDI::Array < ::Array
- # This code borrowed from 'Moser' http://codesnippets.joyent.com/posts/show/1699
-
- # A stable sorting algorithm that maintains the relative order of equal elements
- def mergesort(&cmp)
- if cmp == nil
- cmp = lambda { |a, b| a <=> b }
- end
- if size <= 1
- self.dup
- else
- halves = split.map { |half| half.mergesort(&cmp) }
- merge(*halves, &cmp)
- end
- end
-
- protected
- def split
- n = (length / 2).floor - 1
- [self[0..n], self[n+1..-1]]
- end
-
- def merge(first, second, &predicate)
- result = []
- until first.empty? || second.empty?
- if predicate.call(first.first, second.first) <= 0
- result << first.shift
- else
- result << second.shift
- end
- end
- result.concat(first).concat(second)
- end
- end
-
- # A Track is a list of events.
- #
- # When you modify the +events+ array, make sure to call recalc_times so
- # each Event gets its +time_from_start+ recalculated.
- #
- # A Track also holds a bitmask that specifies the channels used by the track.
- # This bitmask is set when the track is read from the MIDI file by an
- # IO::SeqReader but is _not_ kept up to date by any other methods.
-
- class Track
-
- include Enumerable
-
- UNNAMED = 'Unnamed'
-
- attr_accessor :events, :channels_used
- attr_reader :sequence
-
- def initialize(sequence)
- @sequence = sequence
- @events = Array.new()
-
- # Bitmask of all channels used. Set when track is read in from
- # a MIDI file.
- @channels_used = 0
- end
-
- # Return track name. If there is no name, return UNNAMED.
- def name
- event = @events.detect { |e| e.kind_of?(MetaEvent) && e.meta_type == META_SEQ_NAME }
- event ? event.data_as_str : UNNAMED
- end
-
- # Set track name. Replaces or creates a name meta-event.
- def name=(name)
- event = @events.detect { |e| e.kind_of?(MetaEvent) && e.meta_type == META_SEQ_NAME }
- if event
- event.data = name
- else
- event = MetaEvent.new(META_SEQ_NAME, name, 0)
- @events[0, 0] = event
- end
- end
-
- def instrument
- MetaEvent.bytes_as_str(@instrument)
- end
-
- def instrument=(str_or_bytes)
- @instrument = case str_or_bytes
- when String
- MetaEvent.str_as_bytes(str_or_bytes)
- else
- str_or_bytes
- end
- end
-
- # Merges an array of events into our event list. After merging, the
- # events' time_from_start values are correct so you don't need to worry
- # about calling recalc_times.
- def merge(event_list)
- @events = merge_event_lists(@events, event_list)
- end
-
- # Merges two event arrays together. Does not modify this track.
- def merge_event_lists(list1, list2)
- recalc_times(0, list1)
- recalc_times(0, list2)
- list = list1 + list2
- recalc_delta_from_times(0, list)
- return list
- end
-
- # Quantize every event. length_or_note is either a length (1 = quarter,
- # 0.25 = sixteenth, 4 = whole note) or a note name ("sixteenth", "32nd",
- # "8th triplet", "dotted quarter").
- #
- # Since each event's time_from_start is modified, we call
- # recalc_delta_from_times after each event quantizes itself.
- def quantize(length_or_note)
- delta = case length_or_note
- when String
- @sequence.note_to_delta(length_or_note)
- else
- @sequence.length_to_delta(length_or_note.to_i)
- end
- @events.each { |event| event.quantize_to(delta) }
- recalc_delta_from_times
- end
-
- # Recalculate start times for all events in +list+ from starting_at to
- # end.
- def recalc_times(starting_at=0, list=@events)
- t = (starting_at == 0) ? 0 : list[starting_at - 1].time_from_start
- list[starting_at .. -1].each do |e|
- t += e.delta_time
- e.time_from_start = t
- end
- end
-
- # The opposite of recalc_times: recalculates delta_time for each event
- # from each event's time_from_start. This is useful, for example, when
- # merging two event lists. As a side-effect, elements from starting_at
- # are sorted by time_from_start.
- def recalc_delta_from_times(starting_at=0, list=@events)
- prev_time_from_start = 0
- # We need to sort the sublist. sublist.sort! does not do what we want.
- # We call mergesort instead of Array.sort because sort is not stable
- # (it can mix up the order of events that have the same start time).
- # See http://wiki.github.com/adamjmurray/cosy/midilib-notes for details.
- list[starting_at .. -1] = MIDI::Array.new(list[starting_at .. -1]).mergesort do |e1, e2|
- e1.time_from_start <=> e2.time_from_start
- end
- list[starting_at .. -1].each do |e|
- e.delta_time = e.time_from_start - prev_time_from_start
- prev_time_from_start = e.time_from_start
- end
- end
-
- # Iterate over events.
- def each # :yields: event
- @events.each { |event| yield event }
- end
-
- # Sort events by their time_from_start. After sorting,
- # recalc_delta_from_times is called to make sure that the delta times
- # reflect the possibly new event order.
- #
- # Note: this method is redundant, since recalc_delta_from_times sorts
- # the events first. This method may go away in a future release, or at
- # least be aliased to recalc_delta_from_times.
- alias_method :sort, :recalc_delta_from_times
- end
-
-end
36 app/server/vendor/midilib/lib/midilib/utils.rb
@@ -1,36 +0,0 @@
-module MIDI
-
- # Utility methods.
- class Utils
-
- # MIDI note names. NOTE_NAMES[0] is 'C', NOTE_NAMES[1] is 'C#', etc.
- NOTE_NAMES = [
- 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'
- ]
-
- # Given a MIDI note number, return the name and octave as a string.
- def Utils.note_to_s(num)
- note = num % 12
- octave = num / 12
- return "#{NOTE_NAMES[note]}#{octave - 1}"
- end
-
- # Given an integer, returns it as a variable length array of bytes (the
- # format used by MIDI files).
- #
- # The converse operation--converting a var len into a number--requires
- # input from a stream of bytes. Therefore we don't supply it here. That is
- # a part of the MIDIFile class.
- def Utils.as_var_len(val)
- buffer = []
- buffer << (val & 0x7f)
- val = (val >> 7)
- while val > 0
- buffer << (0x80 + (val & 0x7f))
- val = (val >> 7)
- end
- return buffer.reverse!
- end
-
- end
-end
81 app/server/vendor/midilib/test/event_equality.rb
@@ -1,81 +0,0 @@
-# This code defines equality operators for all of the event classes. It's
-# used by SeqTester.
-#
-# I don't think it is necessary to include these methods in the base Event
-# classes. If someone disagrees, it would be trivial to move them there.
-
-module MIDI
-
- class Event
- def ==(an_obj)
- return an_obj.instance_of?(self.class) &&
- @status == an_obj.status &&
- @delta_time == an_obj.delta_time &&
- @time_from_start == an_obj.time_from_start
- end
- end
-
- class ChannelEvent
- def ==(an_obj)
- return super(an_obj) && @channel == an_obj.channel
- end
- end
-
- class NoteEvent < ChannelEvent
- def ==(an_obj)
- return super(an_obj) &&
- @note == an_obj.note && @velocity == an_obj.velocity
- end
- end
-
- class Controller < ChannelEvent
- def ==(an_obj)
- return super(an_obj) &&
- @controller == an_obj.controller && @value == an_obj.value
- end
- end
-
- class ProgramChange < ChannelEvent
- def ==(an_obj)
- return super(an_obj) && @program == an_obj.program
- end
- end
-
- class ChannelPressure < ChannelEvent
- def ==(an_obj)
- return super(an_obj) && @pressure == an_obj.pressure
- end
- end
-
- class PitchBend < ChannelEvent
- def ==(an_obj)
- return super(an_obj) && @value == an_obj.value
- end
- end
-
- class SystemExclusive < SystemCommon
- def ==(an_obj)
- return super(an_obj) && @data == an_obj.data
- end
- end
-
- class SongPointer < SystemCommon
- def ==(an_obj)
- return super(an_obj) && @pointer == an_obj.pointer
- end
- end
-
- class SongSelect < SystemCommon
- def ==(an_obj)
- return super(an_obj) && @song == an_obj.song
- end
- end
-
- class MetaEvent < Event
- def ==(an_obj)
- return super(an_obj) && @meta_type == an_obj.meta_type &&
- @data == an_obj.data
- end
- end
-
-end
BIN app/server/vendor/midilib/test/test.mid
Binary file not shown.
135 app/server/vendor/midilib/test/test_event.rb
@@ -1,135 +0,0 @@
-# Start looking for MIDI classes in the directory above this one.
-# This forces us to use the local copy of MIDI, even if there is
-# a previously installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'test/unit'
-require 'midilib'
-
-class EventTester < Test::Unit::TestCase
-
- def test_note_on
- e = MIDI::NoteOn.new
- assert_equal(MIDI::NOTE_ON, e.status)
- assert_equal(0, e.channel)
- assert_equal(64, e.note)
- assert_equal(64, e.velocity)
- assert_equal(0, e.delta_time)
- assert_equal(0, e.time_from_start)
- end
-
- def test_to_s
- e = MIDI::NoteOn.new
- assert_equal("0: ch 00 on 40 40", e.to_s)
- e.print_decimal_numbers = true
- assert_equal("0: ch 0 on 64 64", e.to_s)
- e.print_note_names = true
- assert_equal("0: ch 0 on E4 64", e.to_s)
- e.print_decimal_numbers = false
- assert_equal("0: ch 00 on E4 40", e.to_s)
- end
-
- def test_pitch_bend
- e = MIDI::PitchBend.new(0, 128)
- b = e.data_as_bytes
- assert_equal(0, b[1]) # lsb, 7 bits
- assert_equal(1, b[2]) # msb, 7 bits
-
- e.value = (3 << 7) + 42
- b = e.data_as_bytes
- assert_equal(42, b[1]) # lsb, 7 bits
- assert_equal(3, b[2]) # msb, 7 bits
- end
-
- def test_quantize_1
- e = MIDI::NoteOn.new
- e.quantize_to(4)
- assert_equal(0, e.time_from_start)
-
- # Each value in this array is the expected quantized value of
- # its index in the array.
-
- # Test with quantize_to(4)
- [0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12, 16].each_with_index do |after, before|
- e.time_from_start = before
- e.quantize_to(4)
- assert_equal(after, e.time_from_start)
- end
-
- # Test with quantize_to(6)
- [0, 0, 0, 6, 6, 6, 6, 6, 6, 12, 12, 12, 12, 12, 12,
- 18, 18, 18, 18, 18, 18, 24].each_with_index do |after, before|
- e.time_from_start = before
- e.quantize_to(6)
- assert_equal(after, e.time_from_start)
- end
- end
-
- def test_quantize_2
- e = MIDI::NoteOn.new(0, 64, 64, 0)
- e.quantize_to(80)
- assert_equal(0, e.time_from_start)
-
- e.time_from_start = 1
- e.quantize_to(80)
- assert_equal(0, e.time_from_start)
-
- e.time_from_start = 70
- e.quantize_to(80)
- assert_equal(80, e.time_from_start)
-
- e.time_from_start = 100
- e.quantize_to(80)
- assert_equal(80, e.time_from_start)
-
- e.time_from_start = 398
- e.quantize_to(80)
- assert_equal(400, e.time_from_start)
-
- e.time_from_start = 405
- e.quantize_to(80)
- assert_equal(400, e.time_from_start)
-
- e.time_from_start = 439
- e.quantize_to(80)
- assert_equal(400, e.time_from_start)
-
- e.time_from_start = 440
- e.quantize_to(80)
- assert_equal(480, e.time_from_start)
-
- e.time_from_start = 441
- e.quantize_to(80)
- assert_equal(480, e.time_from_start)
- end
-
- def test_meta_strings
- e = MIDI::MetaEvent.new(MIDI::META_TEXT, [97, 98, 99])
- assert_equal([97, 98, 99], e.data)
- assert_equal('abc', e.data_as_str)
-
- assert_equal([MIDI::META_EVENT, MIDI::META_TEXT, 3, 97, 98, 99], e.data_as_bytes)
- end
-
- def test_meta_event_string_in_ctor
- e = MIDI::MetaEvent.new(MIDI::META_TEXT, 'abc')
- assert_equal([97, 98, 99], e.data)
- assert_equal('abc', e.data_as_str)
- assert_equal([MIDI::META_EVENT, MIDI::META_TEXT, 3, 97, 98, 99], e.data_as_bytes)
- end
-
- def test_meta_event_data_assignment
- foobar_as_array = [102, 111, 111, 98, 97, 114]
-
- e = MIDI::MetaEvent.new(MIDI::META_TEXT, [97, 98, 99])
- e.data = 'foobar'
- assert_equal('foobar', e.data_as_str)
- assert_equal(foobar_as_array, e.data)
-
- e.data = nil
- e.data = foobar_as_array
- assert_equal('foobar', e.data_as_str)
- assert_equal(foobar_as_array, e.data)
- end
-
-end
50 app/server/vendor/midilib/test/test_io.rb
@@ -1,50 +0,0 @@
-# Start looking for MIDI classes in the directory above this one.
-# This forces us to use the local copy of MIDI, even if there is
-# a previously installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-# Add current directory so we can find event_equality
-$LOAD_PATH[0, 0] = File.dirname(__FILE__)
-
-require 'test/unit'
-require 'midilib'
-require 'event_equality'
-
-class IOTester < Test::Unit::TestCase
-
- SEQ_TEST_FILE = File.join(File.dirname(__FILE__), 'test.mid')
- OUTPUT_FILE = 'testout.mid'
-
- def compare_tracks(t0, t1)
- assert_equal(t0.name, t1.name, 'track names differ')
- assert_equal(t0.events.length, t1.events.length,
- 'number of track events differ')
- t0.each_with_index { |ev0, i| assert_equal(ev0, t1.events[i], 'events differ') }
- assert_equal(t0.instrument, t1.instrument)
- end
-
- def compare_sequences(s0, s1)
- assert_equal(s0.name, s1.name, 'sequence names differ')
- assert_equal(s0.tracks.length, s1.tracks.length,
- 'number of tracks differ')
- s0.each_with_index { |track0, i| compare_tracks(track0, s1.tracks[i]) }
- end
-
- def test_read_and_write
- seq0 = MIDI::Sequence.new()
- File.open(SEQ_TEST_FILE, 'rb') { |f| seq0.read(f) }
- File.open(OUTPUT_FILE, 'wb') { |f| seq0.write(f) }
- seq1 = MIDI::Sequence.new()
- File.open(OUTPUT_FILE, 'rb') { |f| seq1.read(f) }
- compare_sequences(seq0, seq1)
- ensure
- File.delete(OUTPUT_FILE) if File.exist?(OUTPUT_FILE)
- end
-
- def test_read_strings
- seq = MIDI::Sequence.new
- File.open(SEQ_TEST_FILE, 'rb') { |f| seq.read(f) }
- assert_equal('Sequence Name', seq.tracks[0].name)
- assert_equal(MIDI::GM_PATCH_NAMES[0], seq.tracks[1].instrument)
- end
-
-end
59 app/server/vendor/midilib/test/test_midifile.rb
@@ -1,59 +0,0 @@
-# Start looking for MIDI classes in the directory above this one.
-# This forces us to use the local copy of MIDI, even if there is
-# a previously installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'test/unit'
-require 'stringio'
-require 'midilib'
-
-class MIDI::IO::MIDIFile
- def io=(io)
- @io = io
- end
-end
-if RUBY_VERSION < '1.9'
- class StringIO
- def readbyte
- c = getc()
- raise 'unexpected EOF' unless c
- c
- end
- end
-end
-
-class MIDIFileTester < Test::Unit::TestCase
-
- def setup
- @m = MIDI::IO::MIDIFile.new
- end
-
- def test_msg_io
- io = StringIO.new
- io.write("abcdef")
- io.rewind()
- @m.io = io
- @m.msg_init
- @m.msg_read(6)
- assert_equal [97, 98, 99, 100, 101, 102], @m.msg
- end
-
- def test_read32
- io = StringIO.new
- io.write("\0\0\0\6")
- io.rewind()
- @m.io = io
- assert_equal 6, @m.read32()
- end
-
- def test_write32
- io = StringIO.new
- old_stdout = $stdout
- $stdout = io
- @m.write32(6)
- $stdout = old_stdout
- io.rewind()
- assert_equal "\0\0\0\6", io.string
- end
-
-end
79 app/server/vendor/midilib/test/test_sequence.rb
@@ -1,79 +0,0 @@
-# Start looking for MIDI classes in the directory above this one.
-# This forces us to use the local copy of MIDI, even if there is
-# a previously installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'test/unit'
-require 'midilib'
-
-class SequenceTester < Test::Unit::TestCase
-
- def setup
- @seq = MIDI::Sequence.new
- @track = MIDI::Track.new(@seq)
- @seq.tracks << @track
- 3.times { @track.events << MIDI::NoteOn.new(0, 64, 64, 100) }
- @track.recalc_times
- end
-
- def test_basics
- assert_equal(120, @seq.beats_per_minute)
- assert_equal(1, @seq.tracks.length)
- assert_equal(MIDI::Track::UNNAMED, @seq.name)
- assert_equal(MIDI::Sequence::DEFAULT_TEMPO, @seq.bpm)
- end
-
- def test_pulses_to_seconds
- # At a tempo of 120 BPM 480 pulses (one quarter note) should take 0.5 seconds
- assert_in_delta 0.5, @seq.pulses_to_seconds(480), 0.00001
-
- # A half note should take one second
- assert_in_delta 1.0, @seq.pulses_to_seconds(480*2), 0.00001
-
- # An eight note should take 0.25 seconds
- assert_in_delta 0.25, @seq.pulses_to_seconds(480/2), 0.00001
- end
-
- def test_length_to_delta
- assert_equal(480, @seq.ppqn)
- assert_equal(480, @seq.length_to_delta(1))
- assert_equal(240, @seq.length_to_delta(0.5))
-
- @seq.ppqn = 12
- assert_equal(12, @seq.ppqn)
- assert_equal(12, @seq.length_to_delta(1))
- assert_equal(6, @seq.length_to_delta(0.5))
- assert_equal(5, @seq.length_to_delta(0.49))
- end
-
- def test_note_to_length
- assert_equal(1, @seq.note_to_length('quarter'))
- assert_equal(4, @seq.note_to_length('whole'))
- assert_equal(1.5, @seq.note_to_length('dotted quarter'))
- assert_equal(1.0 / 3.0, @seq.note_to_length('quarter triplet'))
- assert_equal(0.5, @seq.note_to_length('dotted quarter triplet'))
- assert_equal(1.0 / 4, @seq.note_to_length('sixteenth'))
- assert_equal(1.0 / 4, @seq.note_to_length('16th'))
- assert_equal(1.0 / 8, @seq.note_to_length('thirty second'))
- assert_equal(1.0 / 8, @seq.note_to_length('32nd'))
- assert_equal(1.0 / 16, @seq.note_to_length('sixty fourth'))
- assert_equal(1.0 / 16, @seq.note_to_length('sixtyfourth'))
- assert_equal(1.0 / 16, @seq.note_to_length('64th'))
- end
-
- def test_note_to_delta
- assert_equal(480, @seq.note_to_delta('quarter'))
- assert_equal(480 * 4, @seq.note_to_delta('whole'))
- assert_equal(720, @seq.note_to_delta('dotted quarter'))
- assert_equal(480 / 3.0, @seq.note_to_delta('quarter triplet'))
- assert_equal((480 / 3.0) * 1.5,
- @seq.note_to_delta('dotted quarter triplet'))
- assert_equal(480 / 4, @seq.note_to_delta('sixteenth'))
- assert_equal(480 / 4, @seq.note_to_delta('16th'))
- assert_equal(480 / 8, @seq.note_to_delta('thirty second'))
- assert_equal(480 / 8, @seq.note_to_delta('32nd'))
- assert_equal(480 / 16, @seq.note_to_delta('sixty fourth'))
- assert_equal(480 / 16, @seq.note_to_delta('sixtyfourth'))
- assert_equal(480 / 16, @seq.note_to_delta('64th'))
- end
-end
172 app/server/vendor/midilib/test/test_track.rb
@@ -1,172 +0,0 @@
-# Start looking for MIDI classes in the directory above this one.
-# This forces us to use the local copy of MIDI, even if there is
-# a previously installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'test/unit'
-require 'midilib'
-
-class TrackTester < Test::Unit::TestCase
-
- def setup
- @seq = MIDI::Sequence.new
- @track = MIDI::Track.new(@seq)
- @seq.tracks << @track
- 3.times { @track.events << MIDI::NoteOn.new(0, 64, 64, 100) }
- @track.recalc_times
- end
-
- def test_basics
- assert_equal(3, @track.events.length)
- 3.times do |i|
- assert_equal(100, @track.events[i].delta_time)
- assert_equal((i+1) * 100, @track.events[i].time_from_start)
- end
- assert_equal(MIDI::Track::UNNAMED, @track.name)
- end
-
- def test_append_event
- @track.events << MIDI::NoteOn.new(0, 64, 64, 100)
- @track.recalc_times
- assert_equal(4, @track.events.length)
- 4.times do |i|
- assert_equal((i+1) * 100, @track.events[i].time_from_start)
- end
- end
-
- def test_append_list
- @track.events +=
- (1..12).collect { |i| MIDI::NoteOn.new(0, 64, 64, 3) }
- @track.recalc_times
-
- 3.times do |i|
- assert_equal(100, @track.events[i].delta_time)
- assert_equal((i+1) * 100, @track.events[i].time_from_start)
- end
- 12.times do |i|
- assert_equal(3, @track.events[3 + i].delta_time)
- assert_equal(300 + ((i+1) * 3),
- @track.events[3 + i].time_from_start)
- end
- end
-
- def test_insert
- @track.events[1,0] = MIDI::NoteOn.new(0, 64, 64, 3)
- @track.recalc_times
- assert_equal(100, @track.events[0].time_from_start)
- assert_equal(103, @track.events[1].time_from_start)
- assert_equal(203, @track.events[2].time_from_start)
- assert_equal(303, @track.events[3].time_from_start)
- end
-
- def test_merge
- list = (1..12).collect { |i| MIDI::NoteOn.new(0, 64, 64, 10) }
- @track.merge(list)
- assert_equal(15, @track.events.length)
- assert_equal(10, @track.events[0].time_from_start)
- assert_equal(10, @track.events[0].delta_time)
- assert_equal(20, @track.events[1].time_from_start)
- assert_equal(10, @track.events[1].delta_time)
- assert_equal(30, @track.events[2].time_from_start)
- assert_equal(40, @track.events[3].time_from_start)
- assert_equal(50, @track.events[4].time_from_start)
- assert_equal(60, @track.events[5].time_from_start)
- assert_equal(70, @track.events[6].time_from_start)
- assert_equal(80, @track.events[7].time_from_start)
- assert_equal(90, @track.events[8].time_from_start)
- assert_equal(100, @track.events[9].time_from_start)
- assert_equal(100, @track.events[10].time_from_start)
- assert_equal(110, @track.events[11].time_from_start)
- assert_equal(120, @track.events[12].time_from_start)
- assert_equal(200, @track.events[13].time_from_start)
- assert_equal(300, @track.events[14].time_from_start)
- end
-
- def test_recalc_delta_from_times
- @track.each { |event| event.delta_time = 0 }
- @track.recalc_delta_from_times
- @track.each { |event| assert_equal(100, event.delta_time) }
- end
-
- def test_recalc_delta_from_times_unsorted
- @track.events[0].time_from_start = 100
- @track.events[1].time_from_start = 50
- @track.events[2].time_from_start = 150
- @track.recalc_delta_from_times
- prev_start_time = 0
- @track.each do |event|
- assert(prev_start_time <= event.time_from_start)
- assert(event.delta_time > 0)
- prev_start_time = event.time_from_start
- end
- end
-
- def test_sort
- e = @track.events[0]
- e.time_from_start = 300
- e = @track.events[1]
- e.time_from_start = 100
- e = @track.events[2]
- e.time_from_start = 200
-
- @track.sort
-
- assert_equal(100, @track.events[0].time_from_start)
- assert_equal(100, @track.events[0].delta_time)
-
- assert_equal(200, @track.events[1].time_from_start)
- assert_equal(100, @track.events[1].delta_time)
-
- assert_equal(300, @track.events[2].time_from_start)
- assert_equal(100, @track.events[2].delta_time)
- end
-
- def test_quantize
- @seq.ppqn = 80
-
- @track.quantize(1) # Quantize to a quarter note
- assert_equal(80, @track.events[0].time_from_start) # was 100
- assert_equal(240, @track.events[1].time_from_start) # was 200
- assert_equal(320, @track.events[2].time_from_start) # was 300
- end
-
- def test_instrument
- @track.instrument = 'foo'
- assert_equal('foo', @track.instrument)
- end
-
- def test_old_note_class_names
- x = MIDI::NoteOn.new(0, 64, 64, 10)
- assert(x.kind_of?(MIDI::NoteOnEvent)) # old name
- x = MIDI::NoteOff.new(0, 64, 64, 10)
- assert(x.kind_of?(MIDI::NoteOffEvent)) # old name
- end
-
- def test_mergesort
- @track.events = []
-
- # Two events with later start times but earlier in the event list
- e2 = MIDI::NoteOff.new(0, 64, 64, 100)
- e2.time_from_start = 100
- @track.events << e2
-
- e3 = MIDI::NoteOn.new(0, 64, 64, 100)
- e3.time_from_start = 100
- @track.events << e3
-
- # Earliest start time, latest in the list of events
- e1 = MIDI::NoteOn.new(0, 64, 64, 100)
- e1.time_from_start = 0
- @track.events << e1
-
- # Recalc sorts. Make sure note off/note on pair at t 100 are in the
- # correct order.
- @track.recalc_delta_from_times
-
- # These tests would fail before we moved to mergesort.
- assert_equal(e1, @track.events[0])
- assert_equal(e2, @track.events[1])
- assert_equal(e3, @track.events[2])
-
- end
-end
38 app/server/vendor/midilib/test/test_varlen.rb
@@ -1,38 +0,0 @@
-# Start looking for MIDI classes in the directory above this one.
-# This forces us to use the local copy of MIDI, even if there is
-# a previously installed version out there somewhere.
-$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
-
-require 'test/unit'
-require 'midilib'
-
-class VarLenTester < Test::Unit::TestCase
-
- VAR_LEN_TEST_DATA = {
- 0x00000000 => 0x00,
- 0x00000040 => 0x40,
- 0x0000007F => 0x7F,
- 0x00000080 => 0x8100,
- 0x00002000 => 0xC000,
- 0x00003FFF => 0xFF7F,
- 0x00004000 => 0x818000,
- 0x00100000 => 0xC08000,
- 0x001FFFFF => 0xFFFF7F,
- 0x00200000 => 0x81808000,
- 0x08000000 => 0xC0808000,
- 0x0FFFFFFF => 0xFFFFFF7F,
- }
-
- def num_to_var_len(num, answer)
- varlen = MIDI::Utils.as_var_len(num)
- varlen.reverse.each do |b|
- assert_equal(answer & 0xff, b)
- answer = answer >> 8
- end
- end
-
- def test_num_to_var_len
- VAR_LEN_TEST_DATA.each { |varlen, answer| num_to_var_len(varlen, answer) }
- end
-
-end
13 app/server/vendor/unimidi/Gemfile
@@ -1,13 +0,0 @@
-source "https://rubygems.org"
-
-group :test do
- gem "minitest", "4.7.5"
- gem "mocha"
- gem "rake"
- gem "shoulda-context"
-end
-
-gem "alsa-rawmidi" # linux
-gem "ffi-coremidi" # osx
-gem "midi-jruby" # jruby
-gem "midi-winmm" # windows
13 app/server/vendor/unimidi/LICENSE
@@ -1,13 +0,0 @@
-Copyright 2010-2014 Ari Russo
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
87 app/server/vendor/unimidi/README.md
@@ -1,87 +0,0 @@
-# UniMIDI
-
-#### Platform independent realtime MIDI input and output for Ruby.
-
-Also see [MicroMIDI](http://github.com/arirusso/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
-
-Using Ruby 1.9.2 or JRuby 1.6.1 (or newer) is strongly recommended. JRuby should be run in 1.9 mode where applicable
-
-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
-
-* JRuby: [midi-jruby](http://github.com/arirusso/midi-jruby)
-* Linux: [alsa-rawmidi](http://github.com/arirusso/alsa-rawmidi)
-* OSX: [ffi-coremidi](http://github.com/arirusso/ffi-coremidi)
-* Windows/Cygwin: [midi-winmm](http://github.com/arirusso/midi-winmm)
-
-### Install
-
-If you're using Bundler, add this line to your application's Gemfile:
-
-`gem "unimidi"`
-
-Otherwise...
-
-`gem install unimidi`
-
-### Usage
-
-##### Blog Posts
-
-* [What is UniMIDI?](http://tx81z.blogspot.com/2011/06/unimidi-platform-independent-realtime.html)
-* [Selecting a device](http://tx81z.blogspot.com/2011/10/selecting-midi-device-with-unimidi.html)
-* [Internally patching in OSX](http://tx81z.blogspot.com/2011/06/osx-unimidi-and-midi-patch-bay.html)
-* [Using UniMIDI with MicroMIDI](http://tx81z.blogspot.com/2011/08/micromidi-ruby-dsl-for-midi.html)
-
-In addition, some examples are included with the library
-
-* [Selecting a device](http://github.com/arirusso/unimidi/blob/master/examples/select_a_device.rb)
-* [MIDI input](http://github.com/arirusso/unimidi/blob/master/examples/input.rb)
-* [MIDI output](http://github.com/arirusso/unimidi/blob/master/examples/output.rb)
-* [MIDI Sysex output](http://github.com/arirusso/unimidi/blob/master/examples/sysex_output.rb)
-
-### 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 test`
-
-See below for additional notes on testing with JRuby
-
-### Documentation
-
-[rdoc](http://rdoc.info/gems/unimidi)
-
-### Platform Specific Notes
-
-##### JRuby
-
-* You must be in 1.9 mode. This is normally accomplished by passing --1.9 to JRuby at the command line. For testing in 1.9 mode, use `jruby --1.9 -S rake test`
-* 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](http://github.com/arirusso)
-
-### License
-
-Apache 2.0, See the file LICENSE
-
-Copyright (c) 2010-2014 Ari Russo
32 app/server/vendor/unimidi/Rakefile
@@ -1,32 +0,0 @@
-$:.unshift File.join( File.dirname( __FILE__ ))
-$:.unshift File.join( File.dirname( __FILE__ ), 'lib')
-
-require 'rake'
-require 'rake/testtask'
-require 'unimidi'
-
-Rake::TestTask.new(:test) do |t|
- t.libs << "test"
- t.test_files = FileList["test/**/*_test.rb"]
- t.verbose = true
-end
-
-platforms = ["generic", "x86_64-darwin10.7.0", "i386-mingw32", "java", "i686-linux"]
-
-task :build do
- require "unimidi-gemspec"
- platforms.each do |platform|
- UniMIDI::Gemspec.new(platform)
- filename = "unimidi-#{platform}.gemspec"
- system "gem build #{filename}"
- system "rm #{filename}"
- end
-end
-
-task :release => :build do
- platforms.each do |platform|
- system "gem push unimidi-#{UniMIDI::VERSION}-#{platform}.gem"
- end
-end
-
-task :default => [:test]
11 app/server/vendor/unimidi/bin/unimidi
@@ -1,11 +0,0 @@
-#!/usr/bin/env ruby
-
-$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
-
-require "unimidi"
-
-opts = ARGV.length > 1 ? ARGV.slice(1, ARGV.length-1) : {}
-
-raise "No command specified" if ARGV.first.nil?
-
-UniMIDI::Command.exec(ARGV.first.to_sym, opts)
25 app/server/vendor/unimidi/examples/input.rb
@@ -1,25 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-require "unimidi"
-
-# Prompts the user to select a midi input
-# Sends an inspection of the first 10 messages messages that input receives to standard out
-
-num_messages = 10
-
-# Prompt the user
-input = UniMIDI::Input.gets
-
-# using their selection...
-
-puts "send some MIDI to your input now..."
-
-num_messages.times do
- m = input.gets
- puts(m)
-end
-
-puts "finished"
29 app/server/vendor/unimidi/examples/output.rb
@@ -1,29 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + "/../lib"
-
-require "unimidi"
-
-# Prompts the user to select a midi output
-# Sends some arpeggiated chords to the output
-
-notes = [36, 40, 43] # C E G
-octaves = 5
-duration = 0.1
-
-# Prompt the user to select an output
-output = UniMIDI::Output.gets
-
-# using their selection...
-(0..((octaves-1)*12)).step(12) do |oct|
-
- notes.each do |note|
-
- output.puts(0x90, note + oct, 100) # note on
- sleep(duration) # wait
- output.puts(0x80, note + oct, 100) # note off
-
- end
-
-end
54 app/server/vendor/unimidi/examples/select_a_device.rb
@@ -1,54 +0,0 @@
-#!/usr/bin/env ruby
-$:.unshift File.join( File.dirname( __FILE__ ), '../lib')
-
-require "unimidi"
-
-#
-# This is an example that explains how to select an output.
-# It's not really meant to be run.
-#
-
-# The simplest way to select an output is to prompt the user for selection in
-# the Ruby console
-
-output = UniMIDI::Output.gets
-
-# the user will see a list that represents their personal MIDI configuration like:
-
-# Select a MIDI output
-# 1) IAC Device
-# 2) Roland UM-2 (1)
-# 3) Roland UM-2 (2)
-# >
-
-# and be prompted to select a number
-
-# once they've selected, the device that corresponds with their selection is returned
-
-# and it's returned open so you don't need to call output.open ever
-
-# you can also hard code the selection like this
-
-output = UniMIDI::Output.use(:first)
-output = UniMIDI::Output.use(0)
-
-# or
-
-output = UniMIDI::Output.open(:first)
-output = UniMIDI::Output.open(0)
-
-# this also returns an open device
-
-# if you want to wait to open the device, you can select it with any of these "finder" methods
-
-output = UniMIDI::Output.first
-output = UniMIDI::Output[0]
-output = UniMIDI::Output.all[0]
-output = UniMIDI::Output.all.first
-output = UniMIDI::Device.all_by_type(:output)[0]
-output = UniMIDI::Device.all_by_type(:output).first
-
-# but again, you'll need to call open on it before you use it or you'll get an exception
-
-output.open
-
15 app/server/vendor/unimidi/examples/sysex_output.rb
@@ -1,15 +0,0 @@
-#!/usr/bin/env ruby
-
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require "unimidi"
-
-# Prompts the user to select a MIDI output
-# Sends a MIDI system exclusive message to that output
-
-sysex_msg = [0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7]
-
-output = UniMIDI::Output.gets
-
-output.puts(sysex_msg)
24 app/server/vendor/unimidi/lib/unimidi.rb
@@ -1,24 +0,0 @@
-#
-# Realtime MIDI IO for Ruby
-#
-# (c)2010-2014 Ari Russo and licensed under the Apache 2.0 License
-#
-
-# modules
-require "unimidi/command"
-require "unimidi/device"
-require "unimidi/loader"
-require "unimidi/platform"
-require "unimidi/type_conversion"
-
-# classes
-require "unimidi/input"
-require "unimidi/output"
-
-module UniMIDI
-
- VERSION = "0.4.5"
-
- Platform.bootstrap
-
-end
30 app/server/vendor/unimidi/lib/unimidi/adapter/alsa-rawmidi.rb
@@ -1,30 +0,0 @@
-require "alsa-rawmidi"
-
-module UniMIDI
-
- module Adapter
-
- # Load underlying devices using the alsa-rawmidi gem
- module AlsaRawMIDI
-
- module Loader
-
- extend self
-
- # @return [Array
- def inputs
- ::AlsaRawMIDI::Device.all_by_type[:input]
- end
-
- # @return [Array
- def outputs
- ::AlsaRawMIDI::Device.all_by_type[:output]
- end
-
- end
-
- end
-
- end
-
-end
30 app/server/vendor/unimidi/lib/unimidi/adapter/ffi-coremidi.rb
@@ -1,30 +0,0 @@
-require "coremidi"
-
-module UniMIDI
-
- module Adapter
-
- # Load underlying devices using the coremidi gem
- module CoreMIDI
-
- module Loader
-
- extend self
-
- # @return [Array
- def inputs
- ::CoreMIDI::Endpoint.all_by_type[:source]
- end
-
- # @return [Array
- def outputs
- ::CoreMIDI::Endpoint.all_by_type[:destination]
- end
-
- end
-
- end
-
- end
-
-end
30 app/server/vendor/unimidi/lib/unimidi/adapter/midi-jruby.rb
@@ -1,30 +0,0 @@
-require "midi-jruby"
-
-module UniMIDI
-
- module Adapter
-
- # Load underlying devices using the midi-jruby gem
- module MIDIJRuby
-
- module Loader
-
- extend self
-
- # @return [Array
- def inputs
- ::MIDIJRuby::Device.all_by_type[:input]
- end
-
- # @return [Array
- def outputs
- ::MIDIJRuby::Device.all_by_type[:output]
- end
-
- end
-
- end
-
- end
-
-end
30 app/server/vendor/unimidi/lib/unimidi/adapter/midi-winmm.rb
@@ -1,30 +0,0 @@
-require "midi-winmm"
-
-module UniMIDI
-
- module Adapter
-
- # Load underlying devices using the midi-winmm gem
- module MIDIWinMM
-
- module Loader
-
- extend self
-
- # @return [Array
- def inputs
- ::MIDIWinMM::Device.all_by_type[:input]
- end
-
- # @return [Array
- def outputs
- ::MIDIWinMM::Device.all_by_type[:output]
- end
-
- end
-
- end
-
- end
-
-end
26 app/server/vendor/unimidi/lib/unimidi/command.rb
@@ -1,26 +0,0 @@
-module UniMIDI
-
- # Module for command-line use of UniMIDI. Used by the bin/unimidi script
- module Command
-
- extend self
-
- # Execute a command
- # @param [Symbol] command
- # @param [Hash] options
- # @return [Boolean]
- def exec(command, options = {})
- if [:l, :list, :list_devices].include?(command)
- puts "input:"
- Input.list
- puts "output:"
- Output.list
- true
- else
- raise "Command #{command.to_s} not found"
- end
- end
-
- end
-
-end
190 app/server/vendor/unimidi/lib/unimidi/device.rb
@@ -1,190 +0,0 @@
-module UniMIDI
-
- # Common logic that is shared by both Input and Output devices
- module Device
-
- # Methods that are shared by both Input and Output classes
- module ClassMethods
-
- include Enumerable
-
- # Iterate over all devices of this direction (eg Input, Output)
- def each(&block)
- all.each { |device| yield(device) }
- end
-
- # Prints ids and names of each device to the console
- # @return [Array
- def list
- all.map do |device|
- name = device.pretty_name
- puts(name)
- name
- end
- end
-
- # Shortcut to select a device by its name
- # @param [String, Symbol] name
- # @return [Input, Output]
- def find_by_name(name)
- all.find { |device| name.to_s == device.name }
- end
-
- # Streamlined console prompt that asks the user to select a device
- # When their input is received, the device is selected and enabled
- def gets(&block)
- device = nil
- direction = get_direction
- puts ""
- puts "Select a MIDI #{direction}..."
- while device.nil?
- list
- print "> "
- selection = $stdin.gets.chomp
- if selection != ""
- selection = Integer(selection) rescue nil
- device = all.find { |d| d.id == selection } unless selection.nil?
- end
- end
- device.open(&block)
- device
- end
-
- # Select the first device and enable it
- # @return [Input, Output]
- def first(&block)
- use_device(all.first, &block)
- end
-
- # Select the last device and enable it
- # @return [Input, Output]
- def last(&block)
- use_device(all.last, &block)
- end
-
- # Select the device at the given index and enable it
- # @param [Fixnum] index
- # @return [Input, Output]
- def use(index, &block)
- index = case index
- when :first then 0
- when :last then all.size - 1
- else index
- end
- use_device(all[index], &block)
- end
- alias_method :open, :use
-
- # Select the device at the given index
- # @param [Fixnum] index
- # @return [Input, Output]
- def [](index)
- all[index]
- end
-
- private
-
- # The direction of the device eg "input", "output"
- # @return [String]
- def get_direction
- self.name.split("::").last.downcase
- end
-
- # Enable the given device
- # @param [Input, Output] device
- # @return [Input, Output]
- def use_device(device, &block)
- device.open(&block) unless device.enabled?
- device
- end
-
- end
-
- # Methods that are shared by both Input and Output instances
- module InstanceMethods
-
- # @param [AlsaRawMIDI::Input, AlsaRawMIDI::Output, CoreMIDI::Destination, CoreMIDI::Source, MIDIJRuby::Input, MIDIJRuby::Output, MIDIWinMM::Input, MIDIWinMM::Output] device
- def initialize(device)
- @device = device
- @enabled = false
-
- populate_from_device
- end
-
- # Enable the device for use
- # Params are passed to the underlying device object
- # Can be passed a block to which the device will be passed in as the yieldparam
- # @param [*Object] args
- # @return [Input, Output] self
- def open(*args, &block)
- unless @enabled
- @device.open(*args)
- @enabled = true
- end
- if block_given?
- begin
- yield(self)
- ensure
- close
- end
- else
- at_exit do
- close
- end
- end
- self
- end
-
- # A human readable display name for this device
- # @return [String]
- def pretty_name
- "#{id}) #{name}"
- end
-
- # Close the device
- # Params are passed to the underlying device object
- # @param [*Object] args
- # @return [Boolean]
- def close(*args)
- if @enabled
- @device.close(*args)
- @enabled = false
- true
- else
- false
- end
- end
-
- # Add attributes for the device instance
- # :direction, :id, :name
- def self.included(base)
- base.send(:attr_reader, :direction)
- base.send(:attr_reader, :enabled)
- base.send(:attr_reader, :id)
- base.send(:attr_reader, :name)
- base.send(:alias_method, :enabled?, :enabled)
- base.send(:alias_method, :type, :direction)
- end
-
- private
-
- # Populate the direction attribute
- def populate_direction
- @direction = case @device.type
- when :source, :input then :input
- when :destination, :output then :output
- end
- end
-
- # Populate attributes from the underlying device object
- def populate_from_device
- @id = @device.id
- @name = @device.name
- populate_direction
- end
-
- end
-
- end
-
-end
113 app/server/vendor/unimidi/lib/unimidi/input.rb
@@ -1,113 +0,0 @@
-module UniMIDI
-
- # A MIDI input device
- class Input
-
- extend Device::ClassMethods
- include Device::InstanceMethods
-
- # All MIDI input devices -- used to populate the class
- # @return [Array]
- def self.all
- Loader.devices(:direction => :input)
- end
-
- # The device buffer
- # @return [Array
- def buffer
- @device.buffer
- end
-
- #
- # Plucks data from the input buffer and returns it as array of MIDI event hashes as such:
- # [
- # { :data => [144, 60, 100], :timestamp => 1024 },
- # { :data => [128, 60, 100], :timestamp => 1100 },
- # { :data => [144, 40, 120], :timestamp => 1200 }
- # ]
- #
- # In this case, the data is an array of Numeric bytes
- # The timestamp is the number of millis since this input was enabled
- # Arguments are passed to the underlying device object
- #
- # @param [*Object] args
- # @return [Array
- def gets(*args)
- @device.gets(*args)
- rescue SystemExit, Interrupt
- exit
- end
-
- #
- # Plucks data from the input buffer and returns it as array of MIDI event hashes.
- # Similar to Input#gets except that the returned message data as string of hex digits eg:
- # [
- # { :data => "904060", :timestamp => 904 },
- # { :data => "804060", :timestamp => 1150 },
- # { :data => "90447F", :timestamp => 1300 }
- # ]
- #
- # @param [*Object] args
- # @return [Array
- def gets_s(*args)
- @device.gets_s(*args)
- rescue SystemExit, Interrupt
- exit
- end
- alias_method :gets_bytestr, :gets_s
- alias_method :gets_hex, :gets_s
-
- #
- # Plucks data from the input buffer and returns it as an array of data bytes such as
- # [144, 60, 100, 128, 60, 100, 144, 40, 120]
- #
- # @param [*Object] args
- # @return [Array
- def gets_data(*args)
- arr = gets(*args)
- arr.map { |msg| msg[:data] }.inject(:+)
- end
-
- #
- # Plucks data from the input buffer and returns it as a string of data such as
- # "90406080406090447F"
- #
- # @param [*Object] args
- # @return [String]
- def gets_data_s(*args)
- arr = gets_bytestr(*args)
- arr.map { |msg| msg[:data] }.join
- end
- alias_method :gets_data_bytestr, :gets_data_s
- alias_method :gets_data_hex, :gets_data_s
-
- # Clears the input buffer
- # @return [Array]
- def clear_buffer
- @device.buffer.clear
- end
-
- # Gets any messages in the buffer in the same format as Input#gets, without removing them from the buffer
- # @param [*Object] args
- # @return [Array
- def gets_buffer(*args)
- @device.buffer
- end
-
- # Gets any messages in the buffer in the same format as Input#gets_s, without removing them from the buffer
- # @param [*Object] args
- # @return [Array
- def gets_buffer_s(*args)
- @device.buffer.map { |msg| msg[:data] = TypeConversion.numeric_byte_array_to_hex_string(msg[:data]); msg }
- end
-
- # Gets any messages in the buffer in the same format as Input#gets_data without removing them from the buffer
- # @param [*Object] args
- # @return [Array
- def gets_buffer_data(*args)
- @device.buffer.map { |msg| msg[:data] }
- end
-
- end
-
-end
30 app/server/vendor/unimidi/lib/unimidi/loader.rb
@@ -1,30 +0,0 @@
-module UniMIDI
-
- # Populate UniMIDI devices using the underlying device objects from the platform-specific gems
- module Loader
-
- extend self
-
- # Use the given platform-specific adapter to load devices
- # @param [UniMIDI::Adapter::Loader] loader
- def use(loader)
- @loader = loader
- end
-
- # @param [Hash] options
- # @option options [Symbol] :direction Return only a particular direction of device eg :input, :output
- # @return [Array, Array
- should "count all of the inputs" do
- assert_equal @inputs.count, UniMIDI::Input.count
- end
-
- end
-
- context "Device.find_by_name" do
-
- setup do
- index = rand(0..(UniMIDI::Output.count-1))
- @output = UniMIDI::Output.all[index]
- end
-
- should "select the correct input" do
- result = UniMIDI::Output.find_by_name(@output.name)
- assert_equal @output, result
- end
-
- end
-
- context "Device.first" do
-
- setup do
- @output = UniMIDI::Output.all.first
- end
-
- should "open the output" do
- @output.expects(:open)
- output = UniMIDI::Output.first
- @output.unstub(:open)
- end
-
- should "return the correct output" do
- output = UniMIDI::Output.first
- assert_equal @output, output
- end
- end
-
- end
-end
95 app/server/vendor/unimidi/test/class_methods_test.rb
@@ -1,95 +0,0 @@
-require "helper"
-
-class UniMIDI::ClassMethodsTest < Test::Unit::TestCase
-
- context "ClassMethods" do
-
- context "#first" do
-
- context "no block given" do
- should "return first input" do
- i = UniMIDI::Input.first
- assert_equal(UniMIDI::Input.all.first, i)
- end
- end
-
- context "block given" do
- should "pass and return first input" do
- sleep(1)
- i = UniMIDI::Input.first do |i|
- assert_equal(true, i.enabled?)
- end
- assert_equal(UniMIDI::Input.all.first, i)
- end
-
- end
- end
-
- context "#last" do
-
- context "no block given" do
- should "return last input" do
- i = UniMIDI::Input.last
- assert_equal(UniMIDI::Input.all.last, i)
- end
- end
-
- context "block given" do
- should "pass and return last input" do
- sleep(1)
- i = UniMIDI::Input.last do |i|
- assert_equal(true, i.enabled?)
- end
- assert_equal(UniMIDI::Input.all.last, i)
- end
-
- end
- end
-
- context "#[]" do
-
- should "return correct input" do
- i = UniMIDI::Input[0]
- assert_equal(UniMIDI::Input.first, i)
- assert_equal(UniMIDI::Input.all.first, i)
- end
-
- end
-
- context "#use" do
-
- context "block given" do
- should "return and enable an input" do
- sleep(1)
- i = UniMIDI::Input.use(0) do |i|
- assert_equal(true, i.enabled?)
- end
- assert_equal(UniMIDI::Input.first, i)
- assert_equal(UniMIDI::Input.all.first, i)
- end
-
- end
-
- context "with symbol" do
-
- should "return an enabled input" do
- sleep(1)
- input = UniMIDI::Input.use(:first)
- assert_equal(true, input.enabled?)
- assert_equal(UniMIDI::Input.first, input)
- assert_equal(UniMIDI::Input.all.first, input)
- end
-
- end
-
- end
-
- context "#all" do
- should "return all devices" do
- assert_equal(UniMIDI::Loader.devices(:direction => :input), UniMIDI::Input.all)
- end
- end
-
- end
-
-end
113 app/server/vendor/unimidi/test/functional_test.rb
@@ -1,113 +0,0 @@
-require "helper"
-
-class UniMIDI::FunctionalTest < Test::Unit::TestCase
-
- # ** these tests assume that TestOutput is connected to TestInput
- context "UniMIDI" do
-
- setup do
- @input = TestHelper.devices[:input].open
- @output = TestHelper.devices[:output].open
- end
-
- teardown do
- @input.close
- @output.close
- end
-
- context "full IO" do
-
- context "using numeric bytes" do
-
- setup do
- @messages = TestHelper.numeric_messages
- @messages_arr = @messages.inject(&:+).flatten
- @received_arr = []
- @pointer = 0
- end
-
- should "do IO" do
-
- @messages.each do |message|
- p "sending: #{message}"
-
- @output.puts(message)
- sleep(1)
- received = @input.gets.map { |m| m[:data] }.flatten
-
- p "received: #{received}"
-
- assert_equal(@messages_arr.slice(@pointer, received.length), received)
- @pointer += received.length
- @received_arr += received
- end
- assert_equal(@messages_arr.length, @received_arr.length)
- end
- end
-
- context "using byte Strings" do
-
- setup do
- @messages = TestHelper.string_messages
- @messages_str = @messages.join
- @received_str = ""
- @pointer = 0
- end
-
- should "do IO" do
-
- @messages.each do |message|
-
- p "sending: #{message}"
-
- @output.puts(message)
- sleep(1)
- received = @input.gets_bytestr.map { |m| m[:data] }.flatten.join
- p "received: #{received}"
-
- assert_equal(@messages_str.slice(@pointer, received.length), received)
- @pointer += received.length
- @received_str += received
- end
- assert_equal(@messages_str, @received_str)
-
- end
-
- end
-
- context "using MIDIMessages" do
-
- setup do
- @messages = TestHelper.message_objects
- @messages_arr = @messages.map(&:to_bytes).flatten
- @received_arr = []
- @pointer = 0
- end
-
- should "do IO" do
-
- @messages.each do |message|
-
- p "sending: #{message}"
-
- @output.puts(message)
- sleep(1)
- received = @input.gets.map { |m| m[:data] }.flatten
-
- p "received: #{received}"
-
- assert_equal(@messages_arr.slice(@pointer, received.length), received)
- @pointer += received.length
- @received_arr += received
- end
- assert_equal(@messages_arr.length, @received_arr.length)
-
- end
-
- end
-
- end
-
- end
-
-end
74 app/server/vendor/unimidi/test/helper.rb
@@ -1,74 +0,0 @@
-dir = File.dirname(File.expand_path(__FILE__))
-$LOAD_PATH.unshift dir + '/../lib'
-
-require "test/unit"
-require "mocha/test_unit"
-require "shoulda-context"
-require "unimidi"
-
-module TestHelper
-
- extend self
-
- def sysex_ok?
- ENV["_system_name"] != "OSX" || !RUBY_PLATFORM.include?("java")
- end
-
- def devices
- if @devices.nil?
- @devices = {}
- { :input => UniMIDI::Input, :output => UniMIDI::Output }.each do |type, klass|
- @devices[type] = klass.gets
- end
- end
- @devices
- end
-
- def bytestrs_to_ints(arr)
- data = arr.map { |m| m[:data] }.join
- output = []
- until (bytestr = data.slice!(0,2)).eql?("")
- output << bytestr.hex
- end
- output
- end
-
- class MIDIObj
- def initialize(*bytes)
- @bytes = bytes
- end
- def to_bytes
- @bytes
- end
- end
-
- def message_objects
- numeric_messages.map { |message| MIDIObj.new(*message) }
- end
-
- def numeric_messages
- messages = [
- [0x90, 100, 100], # note on
- [0x90, 43, 100], # note on
- [0x90, 76, 100], # note on
- [0x90, 60, 100], # note on
- [0x80, 100, 100] # note off
- ]
- if sysex_ok?
- messages << [0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7]
- end
- messages
- end
-
- def string_messages
- messages = [
- "906440", # note on
- "804340" # note off
- ]
- if sysex_ok?
- messages << "F04110421240007F0041F7"
- end
- messages
- end
-
-end
44 app/server/vendor/unimidi/test/input_test.rb
@@ -1,44 +0,0 @@
-require 'helper'
-
-class UniMIDI::InputTest < Test::Unit::TestCase
-
- context "Input" do
-
- context "#buffer" do
-
- setup do
- sleep(1)
- @input = TestHelper.devices[:input].open
- @output = TestHelper.devices[:output].open
- @messages = TestHelper.numeric_messages
- @bytes = []
- end
-
- teardown do
- @input.close
- @output.close
- end
-
- should "add received messages to the buffer" do
-
- @input.buffer.clear
-
- @messages.each do |message|
-
- p "sending: #{message}"
- @output.puts(message)
- @bytes += message
- sleep(1)
- buffer = @input.buffer.map { |m| m[:data] }.flatten
- p "received: #{buffer}"
- assert_equal(@bytes, buffer)
-
- end
-
- assert_equal(@bytes.length, @input.buffer.map { |m| m[:data] }.flatten.length)
-
- end
-
- end
- end
-end
47 app/server/vendor/unimidi/test/platform_test.rb
@@ -1,47 +0,0 @@
-require 'helper'
-
-class UniMIDI::PlatformTest < Test::Unit::TestCase
-
- def platform_test(adapter, mod, device_class = nil, input_class = nil, output_class = nil)
- device_class ||= mod::Device
- input_class ||= mod::Input
- output_class ||= mod::Output
- assert_not_same(input_class, UniMIDI::Input)
- assert_not_same(output_class, UniMIDI::Output)
- assert_not_same(device_class, UniMIDI::Device)
- assert_equal(input_class.first.name, UniMIDI::Input.first.name)
- assert_equal(input_class.first.id, UniMIDI::Input.first.id)
- assert_not_same(output_class.first, UniMIDI::Output.first)
- assert_equal(output_class.first.name, UniMIDI::Output.first.name)
- assert_equal(output_class.first.id, UniMIDI::Output.first.id)
- end
-
- context "Platform" do
-
- should "recognize java" do
- if RUBY_PLATFORM.include?("java")
- platform_test(UniMIDI::Adapter::MIDIJRuby, ::MIDIJRuby)
- end
- end
-
- should "recognize linux" do
- if RUBY_PLATFORM.include?("linux")
- platform_test(UniMIDI::Adapter::AlsaRawMIDI, ::AlsaRawMIDI)
- end
- end
-
- should "recognize osx" do
- if RUBY_PLATFORM.include?("darwin")
- platform_test(UniMIDI::Adapter::CoreMIDI, ::CoreMIDI, ::CoreMIDI::Endpoint, ::CoreMIDI::Source, ::CoreMIDI::Destination)
- end
- end
-
- should "recognize windows" do
- if RUBY_PLATFORM.include?("mingw")
- platform_test(UniMIDI::Adapter::MIDIWinMM, ::MIDIWinMM)
- end
- end
-
- end
-
-end
18 app/server/vendor/unimidi/test/type_conversion_test.rb
@@ -1,18 +0,0 @@
-require 'helper'
-
-class UniMIDI::TypeConversionTest < Test::Unit::TestCase
-
- context "TypeConversion" do
-
- context "#numeric_byte_array_to_hex_string" do
-
- should "convert byte array to hex string" do
- result = UniMIDI::TypeConversion.numeric_byte_array_to_hex_string([0x90, 0x40, 0x40])
- assert "904040", result
- end
-
- end
-
- end
-
-end
Keine Kommentare:
Kommentar veröffentlichen
Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.