Class: Reight::Sound

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/reight/sound.rb

Defined Under Namespace

Classes: Note

Constant Summary collapse

BPM_MAX =
999

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bpm = 120) ⇒ Sound

Returns a new instance of Sound.



10
11
12
13
# File 'lib/reight/sound.rb', line 10

def initialize(bpm = 120)
  @bpm      = bpm
  @sequence = [[]]
end

Instance Attribute Details

#bpmObject

Returns the value of attribute bpm.



15
16
17
# File 'lib/reight/sound.rb', line 15

def bpm
  @bpm
end

Class Method Details

.restore(hash) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/reight/sound.rb', line 95

def self.restore(hash)
  bpm, sequence = hash.values_at :bpm, :sequence
  #hash => {bpm:, sequence:}
  new(bpm).tap do |obj|
    obj.instance_eval do
      @sequence = sequence.map do |notes|
        notes&.map {Note.restore _1}
      end
    end
  end
end

Instance Method Details

#add_note(time_index, note_index, tone) ⇒ Object Also known as: add



48
49
50
51
# File 'lib/reight/sound.rb', line 48

def add_note(time_index, note_index, tone)
  raise 'The note already exists' if note_at time_index, note_index
  (@sequence[time_index] ||= []) << Note.new(note_index, tone)
end

#clearObject



44
45
46
# File 'lib/reight/sound.rb', line 44

def clear()
  @sequence = [[]]
end

#each_note(time_index: nil, &block) ⇒ Object Also known as: each



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/reight/sound.rb', line 61

def each_note(time_index: nil, &block)
  return enum_for :each_note, time_index: time_index unless block
  if time_index
    @sequence[time_index]&.each do |note|
      block.call note, time_index
    end
  else
    @sequence.each.with_index do |notes, time_i|
      notes&.each do |note|
        block.call note, time_i
      end
    end
  end
end

#empty?Boolean

Returns:

  • (Boolean)


86
# File 'lib/reight/sound.rb', line 86

def empty? = @sequence.all? {!_1 || _1.empty?}

#note_at(time_index, note_index) ⇒ Object Also known as: at



57
58
59
# File 'lib/reight/sound.rb', line 57

def note_at(time_index, note_index)
  @sequence[time_index]&.find {_1.index == note_index}
end

#play(gain: 1.0, &block) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/reight/sound.rb', line 23

def play(gain: 1.0, &block)
  return block&.call false if empty?
  stop
  @playing = sound = to_sound
  sound.play gain: gain

  if block
    id = "__sound_playing_check_#{sound.object_id}"
    set_interval 0.1, id: id do
      next if sound.playing? == true
      block.call true
      clear_interval id
    end
  end
end

#playing?Boolean

Returns:

  • (Boolean)


81
82
83
84
# File 'lib/reight/sound.rb', line 81

def playing?()
  @playing = nil if @playing&.playing? == false
  !!@playing
end

#remove_note(time_index, note_index) ⇒ Object Also known as: remove



53
54
55
# File 'lib/reight/sound.rb', line 53

def remove_note(time_index, note_index)
  @sequence[time_index]&.delete_if {_1.index == note_index}
end

#stopObject



39
40
41
42
# File 'lib/reight/sound.rb', line 39

def stop()
  @playing&.stop
  @playing = nil
end

#to_hashObject



88
89
90
91
92
93
# File 'lib/reight/sound.rb', line 88

def to_hash()
  {
    bpm:      @bpm,
    sequence: @sequence.map {|notes| notes&.map {_1.to_hash}}
  }
end