Class: MIDI::Sequence

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/midilib/sequence.rb

Overview

A MIDI::Sequence contains MIDI::Track objects.

Constant Summary collapse

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
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSequence

Returns a new instance of Sequence.



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/midilib/sequence.rb', line 39

def initialize
	@tracks = Array.new()
	@ppqn = 480

	# Time signature
	@numer = 4		# Numer + denom = 4/4 time default
	@denom = 2
	@clocks = @ppqn
	@qnotes = 8

	@reader_class = IO::SeqReader
	@writer_class = IO::SeqWriter
end

Instance Attribute Details

#clocksObject

Returns the value of attribute clocks.



31
32
33
# File 'lib/midilib/sequence.rb', line 31

def clocks
  @clocks
end

#denomObject

Returns the value of attribute denom.



31
32
33
# File 'lib/midilib/sequence.rb', line 31

def denom
  @denom
end

#formatObject

Returns the value of attribute format.



30
31
32
# File 'lib/midilib/sequence.rb', line 30

def format
  @format
end

#numerObject

Returns the value of attribute numer.



31
32
33
# File 'lib/midilib/sequence.rb', line 31

def numer
  @numer
end

#ppqnObject

Returns the value of attribute ppqn.



30
31
32
# File 'lib/midilib/sequence.rb', line 30

def ppqn
  @ppqn
end

#qnotesObject

Returns the value of attribute qnotes.



31
32
33
# File 'lib/midilib/sequence.rb', line 31

def qnotes
  @qnotes
end

#reader_classObject

The class to use for reading MIDI from a stream. The default is MIDI::IO::SeqReader. You can change this at any time.



34
35
36
# File 'lib/midilib/sequence.rb', line 34

def reader_class
  @reader_class
end

#tracksObject

Returns the value of attribute tracks.



30
31
32
# File 'lib/midilib/sequence.rb', line 30

def tracks
  @tracks
end

#writer_classObject

The class to use for writeing MIDI from a stream. The default is MIDI::IO::SeqWriter. You can change this at any time.



37
38
39
# File 'lib/midilib/sequence.rb', line 37

def writer_class
  @writer_class
end

Instance Method Details

#beats_per_minuteObject Also known as: bpm, tempo

Returns the song tempo in beats per minute.



62
63
64
65
66
67
68
# File 'lib/midilib/sequence.rb', line 62

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

#eachObject

Iterates over the tracks.



139
140
141
# File 'lib/midilib/sequence.rb', line 139

def each			# :yields: track
	@tracks.each { | track | yield track }
end

#length_to_delta(length) ⇒ Object

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.



108
109
110
# File 'lib/midilib/sequence.rb', line 108

def length_to_delta(length)
  return (@ppqn * length).to_i
end

#nameObject

Returns the name of the first track (track zero). If there are no tracks, returns UNNAMED.



114
115
116
117
# File 'lib/midilib/sequence.rb', line 114

def name
	return UNNAMED if @tracks.empty?
	return @tracks.first.name()
end

#name=(name) ⇒ Object

Hands the name to the first track. Does nothing if there are no tracks.



120
121
122
123
# File 'lib/midilib/sequence.rb', line 120

def name=(name)
	return if @tracks.empty?
	@tracks.first.name = name
end

#note_to_delta(name) ⇒ Object

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.



75
76
77
# File 'lib/midilib/sequence.rb', line 75

def note_to_delta(name)
  return length_to_delta(note_to_length(name))
end

#note_to_length(name) ⇒ Object

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.



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/midilib/sequence.rb', line 88

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

#read(io, proc = nil) ⇒ Object

Reads a MIDI stream.



126
127
128
129
130
# File 'lib/midilib/sequence.rb', line 126

def read(io, proc = nil)	# :yields: track, num_tracks, index
	@tracks = Array.new()
	reader = @reader_class.new(self, block_given?() ? Proc.new() : proc)
	reader.read_from(io)
end

#time_signature(numer, denom, clocks, qnotes) ⇒ Object

Sets the time signature.



54
55
56
57
58
59
# File 'lib/midilib/sequence.rb', line 54

def time_signature(numer, denom, clocks, qnotes)
	@numer = numer
	@denom = denom
	@clocks = clocks
	@qnotes = qnotes
end

#write(io, proc = nil) ⇒ Object

Writes to a MIDI stream.



133
134
135
136
# File 'lib/midilib/sequence.rb', line 133

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