Class: Music::Performance::NoteTimeConverter

Inherits:
Object
  • Object
show all
Defined in:
lib/music-performance/conversion/note_time_converter.rb

Overview

Convert note duration to time duration.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tempo_computer, beat_duration_computer, sample_rate) ⇒ NoteTimeConverter

Returns a new instance of NoteTimeConverter.



7
8
9
10
11
# File 'lib/music-performance/conversion/note_time_converter.rb', line 7

def initialize tempo_computer, beat_duration_computer, sample_rate
  @tempo_computer = tempo_computer
  @beat_duration_computer = beat_duration_computer
  @sample_period = Rational(1,sample_rate)
end

Class Method Details

.notes_per_second(tempo, beat_duration) ⇒ Object



13
14
15
# File 'lib/music-performance/conversion/note_time_converter.rb', line 13

def self.notes_per_second tempo, beat_duration
  (tempo * beat_duration) * Rational(1,60)
end

Instance Method Details

#map_note_offsets_to_time_offsets(note_offsets) ⇒ Object

map absolute note offsets to relative time offsets



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/music-performance/conversion/note_time_converter.rb', line 60

def map_note_offsets_to_time_offsets note_offsets
  time_counter = 0.0
  sorted_offsets = note_offsets.sort
  note_time_map = { sorted_offsets.first => time_counter }
  
  for i in 1...sorted_offsets.count do
    time_counter += time_elapsed(sorted_offsets[i-1], sorted_offsets[i])
    note_time_map[sorted_offsets[i]] = time_counter
  end
  
  return note_time_map
end

#notes_per_second_at(offset) ⇒ Object



17
18
19
20
21
# File 'lib/music-performance/conversion/note_time_converter.rb', line 17

def notes_per_second_at offset
  tempo = @tempo_computer.value_at offset
  beat_duration = @beat_duration_computer.value_at offset
  return NoteTimeConverter.notes_per_second(tempo,beat_duration)
end

#time_elapsed(note_begin, note_end) ⇒ Object

Convert the given note duration to a time duration. Using the tempo computer and beat duration computer, figure the current notes-per-second relationship depending on the current note offset. Using this, note duration for each sample is known and accumulated as samples are taken. When accumulated note duration passes the given desired duration (note_end - note_begin), the number of samples take will indicated the corresponding time duration. There is adjustment for last sample taken, which likely goes past the desired note duration.

Parameters:

  • note_begin (Numeric)

    the starting note offset.

  • note_end (Numeric)

    the ending note offset.

Raises:

  • (ArgumentError)

    if note end is less than note begin.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/music-performance/conversion/note_time_converter.rb', line 35

def time_elapsed note_begin, note_end
  raise ArgumentError "note end is less than note begin" if note_end < note_begin
  
  time = 0.to_r
  note = note_begin
  
  while note < note_end
    notes_per_sec = notes_per_second_at note
    notes_per_sample = notes_per_sec * @sample_period
    
    if (note + notes_per_sample) > note_end
      #interpolate between note and note_end
      perc = (note_end - note) / notes_per_sample
      time += @sample_period * perc
      note = note_end
    else
      time += @sample_period
      note += notes_per_sample
    end
  end
  
  return time
end