# Based on recipes 70, 72 and 73

def sineWave(freq,amplitude):

  # Make an empty sound of one second
  mySound = makeEmptySound(1)

  # Get sampling rate
  sr = getSamplingRate(mySound)

  interval = 1.0/freq  # Make sure floating point

  samplesPerCycle = interval * sr  # Samples per cycle

  maxCycle = 2*pi

  for pos in range(1,getLength(mySound)+1): #loop for all sound samples
    rawSample = sin((pos / samplesPerCycle) * maxCycle)
    sampleVal = int(amplitude*rawSample)
    setSampleValueAt(mySound, pos, sampleVal)

  return mySound

# ------------------------------------------------------------

def squareWave(freq,amplitude):

  # Make an empty sound of one second
  mySound = makeEmptySound(1)

  # Get sampling rate
  sr = getSamplingRate(mySound)
  seconds = 1  # One second sound duration

  # Build tools for this wave
  interval = 1.0 * seconds / freq  # Make sure floating point

  # Creates floating point since interval is floating point
  samplesPerCycle = interval * sr  # Samples per cycle

  # We need to switch every half-cycle
  samplesPerHalfCycle = int(samplesPerCycle / 2)
  sampleVal = amplitude

  i = 1

  for pos in range(1,getLength(mySound)+1): #loop for all sound samples
    # if end of a half-cycle
    if (i > samplesPerHalfCycle):
      # Reverse the amplitude
      sampleVal = sampleVal * -1
      # And reinitialise the half-cycle counter
      i = 0
    setSampleValueAt(mySound, pos, sampleVal)

    i = i + 1

  return mySound

# ------------------------------------------------------------

def triangleWave(freq,amplitude):

  # Make an empty sound of one second
  mySound = makeEmptySound(1)

  # Get sampling rate
  sr = getSamplingRate(mySound)
  seconds = 1  # One second sound duration

  # Build tools for this wave
  interval = 1.0 * seconds / freq  # Make sure floating point

  # Creates floating point since interval is floating point
  samplesPerCycle = interval * sr  # Samples per cycle

  # We need to switch every half-cycle
  samplesPerHalfCycle = int(samplesPerCycle / 2)

  # Value to add for each subsequent sample: Must be integer
  increment = int(2*amplitude/samplesPerHalfCycle)

  # Start at bottom and increment or decrement as needed
  sampleVal = -amplitude
  i = 1

  for pos in range(1,getLength(mySound)+1): #loop for all sound samples
    # if end of a half-cycle
    if (i > samplesPerHalfCycle):
      # Reverse the amplitude
      increment = increment * -1
      # And reinitialise the half-cycle counter
      i = 0
    sampleVal = sampleVal + increment
    setSampleValueAt(mySound, pos, sampleVal)

    i = i + 1

  return mySound


# ------------------------------------------------------------

def sawtoothWave(freq,amplitude):

  # Make an empty sound of one second
  mySound = makeEmptySound(1)

  # Get sampling rate
  sr = getSamplingRate(mySound)
  seconds = 1  # One second sound duration

  # Build tools for this wave
  interval = 1.0 * seconds / freq  # Make sure floating point

  # Creates floating point since interval is floating point
  samplesPerCycle = interval * sr  # Samples per cycle

  # Value to subtract for each subsequent sample: Must be integer
  decrement = int(2*amplitude/samplesPerCycle)

  # Start at top and decrement as needed
  sampleVal = amplitude + decrement

  for pos in range(1,getLength(mySound)+1): #loop for all sound samples
    sampleVal = sampleVal - decrement #calculate the sample value
    setSampleValueAt(mySound, pos, sampleVal) #set the sample value
    if sampleVal == -amplitude: #if the sample has reach the bottom of the sound wave
      sampleVal = amplitude + decrement  #set the new sample to be at the top of the wave

  return mySound


# ------------------------------------------------------------

def addSounds(sound1, sound2):

  for index in range(1, getLength(sound1)+1):
    S1sample = getSampleValueAt(sound1, index)
    S2sample = getSampleValueAt(sound2, index)
    setSampleValueAt(sound2, index, (S1sample + S2sample)/2)
