Class: SynthBlocks::Core::Sound

Inherits:
Object
  • Object
show all
Defined in:
lib/synth_blocks/core/sound.rb

Overview

Base class for all sound generators and the mixer channels Handles events (note on / off) and automation Has two modes, polyphonic and monophonic

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sfreq, mode: :polyphonic) ⇒ Sound

create new sound generator instance

super(sfreq, mode: $mode) should be called from the sound generator implementation initializer.



43
44
45
46
47
48
49
50
51
52
# File 'lib/synth_blocks/core/sound.rb', line 43

def initialize(sfreq, mode: :polyphonic)
  @mode = mode
  @sampling_frequency = sfreq.to_f
  @parameters = {}
  @events = []
  @active_events = {}
  initialize_live_params
  @prepared = false
  @sample_duration = 1.0 / @sampling_frequency
end

Instance Attribute Details

#modeObject

Mode, either :monophonic or :polyphonic



9
10
11
# File 'lib/synth_blocks/core/sound.rb', line 9

def mode
  @mode
end

Instance Method Details

#active_events(t) ⇒ Object

returns active events at time t



71
72
73
74
75
76
77
# File 'lib/synth_blocks/core/sound.rb', line 71

def active_events(t)
  if mode == :polyphonic
    active_polyphonic_events(t)
  else
    active_monophonic_events(t)
  end
end

#duration(t = 0) ⇒ Object

this + start time makes it possible to delete events from list

define this in your generator implementation if your generator has fixed note lengths not dependent on the note off event (for example one shot drum hits)



25
26
27
# File 'lib/synth_blocks/core/sound.rb', line 25

def duration(t=0)
  nil
end

#get(parameter, time) ⇒ Object

get the exact parameter value including interpolation

parameter

parameter name

time

time of from where you want the value



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/synth_blocks/core/sound.rb', line 101

def get(parameter, time)
  return nil if @parameters[parameter].nil?
  return nil if @parameters[parameter].first.first > time
  reverse_list = @parameters[parameter].reverse
  reverse_list.each_with_index do |entry, index|
    return entry[1] if entry.first <= time
    if entry.first >= time && entry[2] == :linear
      if reverse_list[index + 1].nil?
        return nil
      end
      lin_time_start = reverse_list[index + 1][0]
      lin_value_start = reverse_list[index + 1][1]
      value_diff = entry[1] - lin_value_start
      time_diff = entry[0] - lin_time_start
      return value_diff / time_diff * (time - lin_time_start)
    end
  end
end

#live_paramsObject

:nodoc:



16
17
18
# File 'lib/synth_blocks/core/sound.rb', line 16

def live_params # :nodoc:
  []
end

#release(t = 0) ⇒ Object

this + end time makes it possible to delete events from list

define this in your generator implementation if your generator is dependent on note off events



33
34
35
# File 'lib/synth_blocks/core/sound.rb', line 33

def release(t=0)
  nil
end

#run(offset) ⇒ Object

run the generator at offset (samples from song start)



12
13
14
# File 'lib/synth_blocks/core/sound.rb', line 12

def run(offset)
  raise "Base Class, should not be called"
end

#set(parameter, time, value, type: :set) ⇒ Object

sets a parameter to a specific value at a given time. you can interpolate linearly between two points by setting to value A then setting value B at a later point in time with type: linear TODO: implement quadratic interpolation

Note: this does no sanity checking, so please make sure you set events in the correct order etc.

parameter

parameter name

time

time in seconds from song start

value

value of the parameter you want to get to

type

either :set or :linear



92
93
94
95
96
# File 'lib/synth_blocks/core/sound.rb', line 92

def set(parameter, time, value, type: :set)
  @parameters[parameter] ||= []
  @parameters[parameter] << [time, value, type]
  @parameters[parameter].sort_by! { |item| item.first }
end

#start(t, note = 36, velocity = 1.0) ⇒ Object

create a note on event at time t with note and velocity

t

time in seconds from song start

note

MIDI note

velocity

velocity of note from 0 to 1.0



58
59
60
# File 'lib/synth_blocks/core/sound.rb', line 58

def start(t, note = 36, velocity = 1.0)
  @events << [t.to_f, :start, note, velocity]
end

#stop(t, note = 36) ⇒ Object

create a note off event at time t with note

t

time in seconds from song start

note

MIDI note



65
66
67
# File 'lib/synth_blocks/core/sound.rb', line 65

def stop(t, note = 36)
  @events << [t.to_f, :stop, note, 0]
end