Creating Signals - Quefumas/gensound GitHub Wiki

Aliasing an existing signal

Mostly useful to try out different oscillators which are reused in many places.

MySignal = Triangle
MySignal("A4", 1e3).play()

Using a function

This method is simple and flexible, and does not require understanding how Gensound is built - any user can do it. See the following examples:

def MySignal(frequency, duration):
  # Square wave with ADSR envelope and filter
  return Square(frequency, duration)*ADSR(...)*Filter(...)

def MySignal2(frequency, duration):
  # mix between sine, octave square and noise
  return 0.5*Sine(frequency, duration) + 0.3*Square(frequency*2, duration) + 0.2*WhiteNoise(duration)

s = MySignal("A G F# E", 1e3) + MySignal2("F3 E3 Ab3 G3", 1e3)
s.play()

TODO consider how this interacts with future feature shorthand melodic notation

Subclassing Signal

When you need to create the signal "by hand", it is easy to subclass Signal. This involves overriding __init__, which mostly just saves instance variables, and generate, which returns the actual signal as numpy.ndarray. While the former is called on object construction, generate is only called when calling play or export on some Signal containing the new signal.

class MySignal(Signal):
  def __init__(self, ...):
    super().__init__()
    # do something with arguments if needed
    ...

  def generate(self, sample_rate):
    # user code here, should return np.ndarray object with shape of length two (?): (num channels, num samples)
    # data type should be np.float64
    ...

Subclassing Oscillator

If the new signal behaves like an oscillator - that is, it is identified by a single main frequency - it is recommended to subclass Oscillator instead. This is both shorter and will likely carry other benefits (like phase inference). All that is needed is defining a single class member, and the rest is taken care of:

class MyOsc(Oscillator):
  wave = lambda phase: ... # a function receiving phases (np.ndarray) and returning amplitudes

TODO change from lambda to class function