Class: Webmidi::SMF::Sequence

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(format: 1, ppqn: 480) ⇒ Sequence

Returns a new instance of Sequence.



10
11
12
13
14
# File 'lib/webmidi/smf/sequence.rb', line 10

def initialize(format: 1, ppqn: 480)
  @tracks = []
  self.format = format
  self.ppqn = ppqn
end

Instance Attribute Details

#formatObject

Returns the value of attribute format.



8
9
10
# File 'lib/webmidi/smf/sequence.rb', line 8

def format
  @format
end

#ppqnObject

Returns the value of attribute ppqn.



8
9
10
# File 'lib/webmidi/smf/sequence.rb', line 8

def ppqn
  @ppqn
end

Class Method Details

.parse(binary) ⇒ Object



107
108
109
# File 'lib/webmidi/smf/sequence.rb', line 107

def self.parse(binary)
  Reader.parse(binary)
end

.read(path_or_io) ⇒ Object



103
104
105
# File 'lib/webmidi/smf/sequence.rb', line 103

def self.read(path_or_io)
  Reader.read(path_or_io)
end

Instance Method Details

#[](index) ⇒ Object



29
30
31
# File 'lib/webmidi/smf/sequence.rb', line 29

def [](index)
  @tracks[index]
end

#add_track(track) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/webmidi/smf/sequence.rb', line 20

def add_track(track)
  if @format == 0 && @tracks.any?
    raise InvalidSMFError, "SMF format 0 supports exactly one track"
  end

  @tracks << track
  self
end

#durationObject



41
42
43
44
45
46
47
# File 'lib/webmidi/smf/sequence.rb', line 41

def duration
  return 0.0 if @tracks.empty?

  tempo_map = tempo_map()
  max_ticks = @tracks.map { |t| t.events.sum(&:delta_time) }.max || 0
  tempo_map.ticks_to_seconds(max_ticks)
end

#each(&block) ⇒ Object



33
34
35
# File 'lib/webmidi/smf/sequence.rb', line 33

def each(&block)
  @tracks.each(&block)
end

#sizeObject



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

def size
  @tracks.size
end

#tempo_mapObject



68
69
70
# File 'lib/webmidi/smf/sequence.rb', line 68

def tempo_map
  TempoMap.from_sequence(self)
end

#to_binary(**options) ⇒ Object



115
116
117
# File 'lib/webmidi/smf/sequence.rb', line 115

def to_binary(**options)
  Writer.to_binary(self, **options)
end

#to_format0Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/webmidi/smf/sequence.rb', line 72

def to_format0
  sequence = self.class.new(format: 0, ppqn: @ppqn)
  merged = Track.new
  events_with_time = @tracks.flat_map do |track|
    absolute = 0
    track.events.map do |event|
      absolute += event.delta_time
      [absolute, event]
    end
  end.sort_by(&:first)

  previous = 0
  events_with_time.each do |absolute, event|
    merged << duplicate_event(event, delta_time: absolute - previous, absolute_time: absolute)
    previous = absolute
  end
  sequence.add_track(merged)
end

#to_format1Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/webmidi/smf/sequence.rb', line 91

def to_format1
  sequence = self.class.new(format: 1, ppqn: @ppqn)
  @tracks.each do |track|
    copy = Track.new(name: track.name, channel: track.channel)
    track.each do |event|
      copy << duplicate_event(event, delta_time: event.delta_time, absolute_time: event.absolute_time)
    end
    sequence.add_track(copy)
  end
  sequence
end

#tracksObject



16
17
18
# File 'lib/webmidi/smf/sequence.rb', line 16

def tracks
  @tracks.dup
end

#write(path_or_io) ⇒ Object



111
112
113
# File 'lib/webmidi/smf/sequence.rb', line 111

def write(path_or_io)
  Writer.write(self, path_or_io)
end