# Template file for Homework 7, CS 151, Fall 2010, ISU
# Name: (put your name here)
# Collaborators: (put list of collaborators here, none if none).
# ** Note on collaboration: You should not turn in work that is not your own.
#    To make sure you are not violating this, if you work with someone, 
#    you should destroy the file once you are done working together, go 
#    your separate ways, and then you should be able to recreate the file
#    on your own, then turn that in.  If you cannot recreate the file on your
#    own, then it is not your work, and you should not turn it in.
# ** Note on sources: if you use some other source, the web or whatever, you
#    better cite it!  Not doing so is plagiarism.

# Problem 1 (10 Points)
#
# This function is supposed to compute the number of times
# the sound wave goes from negative to positive.
#
# If the function were correct, it would behave like this:
# >>> sound = note(300, 1, 20000)
# >>> negToPos = numNegToPos(sound)
#  Number of times wave goes from negative to positive is 299
# >>> sound = note(4, 1, 100)
#  Number of times wave goes from negative to positive is 3
#
# You need to fill in the missing blanks _____ with what 
# should go there.  After you do this, you should uncomment the
# code to make sure it works!
#
#def numNegToPos(sound):
#  numNegToPos = 0
#  lastValue = 0
#  for i in range(0, getLength(sound)):
#    value = getSampleValueAt(_____, _____)
#    if (value >= 0 and lastValue < 0):
#      numNegToPos = _____ + 1
#    lastValue = value
#  print "Number of times wave goes from negative to positive is", _____
#  return numNegToPos
  

# Problem 2 (10 Points)
#
# This function is supposed to compute the frequency of 
# a sound wave.
#
# If the function were correct, it would behave like this:
# >>> sound = note(300, 1, 20000)
# >>> freq = computeFrequency(sound)
#  Number of times wave goes from negative to positive is 299
#  Frequency of the sound wave is about 299.0
# >>> sound = note(4, 1, 100)
# >>> freq = computeFrequency(sound)
#  Number of times wave goes from negative to positive is 3
#  Frequency of the sound wave is about 3.0
#
# You need to fill in the missing blanks _____ with what 
# should go there.  After you do this, you should uncomment the
# code to make sure it works!
#
#def computeFrequency(sound):
#  negToPos = numNegToPos(_____)
#  samplingRate = getSamplingRate(_____)
#  numSamples = _____(sound)
#  seconds = float(numSamples)/samplingRate
#  freq = float(negToPos)/seconds
#  print "Frequency of the sound wave is about", _____
#  return freq
 
   
   
# Problem 3, Extra Credit (5 Points)
#
# Since this is extra credit, I will grade it a bit more strictly than
# the regular problems.
#
# For this problem, you should make this function create
# a new sound object that copies samples from the one that 
# is input.  The new sound should be one with a reduced
# sampling rate from the old one.  This could be nice because
# then the new sound will have fewer samples and will not 
# take up as many bytes.  Of course, if the sampling rate is 
# made too small, the sound won't really sound like anything
# anymore.
#
# You could call the function like this from the command window.
# >>> sound = note(300, 1, 10000)
# >>> play(sound)
# >>> sound = reduceSamplingRate(sound, 2)
# >>> play(sound)
# And the sound will sound pretty much the same.  You can
# try it also on sound with people talking and see if it 
# sounds the same.
def reduceSamplingRate(sound, factor):
  print "remove this and put your code here..."


# The rest of this file has a few of the functions
# we have done in class that you might like to use to 
# play around with sounds while working on this homework.

# This is a function that will create a sound for 
# you that is a note of a given frequencey.  You don't
# have to understand it right now, but you can play around with it.
# hertz is the frequency of the sound you want.
# seconds is the number of seconds you want the sound to last.
# sampleRate is the sampling rate of the sound file to be created.
# You can call it like this in the command window.
# >>> snd = note(261.626, 1, 22050)
# >>> play(snd)
def note(hertz, seconds, sampleRate):
  sound = makeEmptySoundBySeconds(seconds, sampleRate)
  samplesPerCycle = (sampleRate + 0.0)/hertz
  maxAmplitude = pow(2,15)-1
  for i in range(0, seconds*sampleRate):
    t = i % samplesPerCycle
    scaledT = t * (2*pi/samplesPerCycle)
    value = sin(scaledT)*maxAmplitude
    setSampleValueAt(sound, i, value)
  return sound


# normalizes a sound.
def normalize(sound):
  largest = 0
  for i in range(0, getLength(sound)):
    value = getSampleValueAt(sound, i)
    if (value > largest):
      largest = value
#  print "The largest value is", largest
  
  multiplier = (32767 + 0.0)/largest
#  print "Each sample value will be multiplied by", multiplier
  
  for i in range(0, getLength(sound)):
    value = getSampleValueAt(sound, i)
    setSampleValueAt(sound, i, value*multiplier)
#  blockingPlay(sound)

# function to increase or decrease the volume of a sound.
# sound sound be a sound that has been loaded with makeSound
# multBy should be a number we want to multiply all the samples by.
def changeVolume(sound, multBy):
  # for loop that will make s go over all the samples in the sound
  for s in getSamples(sound):
    # get the value of the sample in the sample object
    value = getSampleValue(s)
    # change the value of the sample in the sample object
    setSampleValue(s, value*multBy)
  # go ahead and play the new sound.  use blockingPlay to make sure
  # we wait for any other sounds to finish before playing this one.
#  blockingPlay(sound)  


# function to change the volume only on the first half.
# it uses getSampleValueAt and setSampleValueAt instead of 
# getSampleValue and setSampleValue to do this...
def changeVolume1stHalf(sound, multBy):
  for i in range(0, getLength(sound)/2):
    # get the value of the i-th sample
    value = getSampleValueAt(sound, i)
    # change the value of the i-th sample
    setSampleValueAt(sound, i, value*multBy)
  # go ahead and play the new sound.  use blockingPlay to make sure
  # we wait for any other sounds to finish before playing this one.
#  blockingPlay(sound)  
