Write a function to input a sound, then create a canvas sound of the same length
ID: 3861103 • Letter: W
Question
Write a function to input a sound, then create a canvas sound of the same length. Copy samples from the input into the canvas every third position, i.e., copy from index 0 in the input into the canvas at index 0, then copy from index 3 (skipping index 1 and 2) in the input into the canvas at index 3. What do you hear in the canvas sound? Same sound? Faster? Slower?
Explanation / Answer
#Composing sounds via addition #this function assumes that first and second sound #are of the same length def addSounds(firstSound, secondSound): target = makeEmptySound(getLength(firstSound)) for index in range (0, getLength(firstSound)): first = getSampleValueAt(firstSound, index) second = getSampleValueAt(secondSound, index) setSampleValueAt(target, index, first + second) play (target) return target #Blending Sounds #This function copies the first half of ahh.wav into the canvas or target #then it blends then it blends the second half of ahh with the first half #of bass and finally it copies the second half of bass into the target sound def blendSounds(): bass = makeSound(getMediaPath("bassoon-c4.wav")) aah = makeSound(getMediaPath("aah.wav")) #explore (bass) #explore(aah) newSoundSize = getLength(aah) + getLength(bass)/2 canvas = makeEmptySound(newSoundSize) #copy the first half of aah.wav into the target sound halfAahLength = getLength(aah)/2 for index in range (0, halfAahLength): setSampleValueAt(canvas, index, getSampleValueAt(aah, index)) #Blend the second half of aah.wav with the first half of bassoon-c4.wav #at 50% of their amplitudes and copy the blended sound in the target count = halfAahLength #keep track of how many samples are in canvas for index in range (0, halfAahLength): aahSample = getSampleValueAt(aah, index + halfAahLength) bassSample = getSampleValueAt (bass, index) newSample = (0.5 * aahSample) + (0.5 * bassSample) setSampleValueAt (canvas, index + halfAahLength, newSample) count = count + 1 #copy the second half of bassoon-c4.wav in the target sound for index in range (getLength(bass)/2, getLength(bass)): setSampleValueAt(canvas, count, getSampleValueAt(bass, index)) count = count + 1 #here we use count as the index for canvas play(canvas) return canvas #Creating an echo: add samples from a delay number of samples away #into the sound def echo(delay, sound): sound2 = sound for index in range (delay, getLength(sound)): echoSample = 0.6 * getSampleValueAt(sound, index - delay) comboSample = getSampleValueAt(sound2, index) + echoSample setSampleValueAt(sound2, index, comboSample) play (sound2) return sound2 #creating multiple echoes #this function creates a new sound that echoes the input sound file #'num' number of echoes, each with 'delay' delay apart def echoes(soundFile, delay, num): s1 = makeSound (soundFile) endS1 = getLength (s1) endS2 = endS1 + (delay * num) #length in samples of s2 len = 1 + int(endS2/getSamplingRate(s1)) #length in seconds of s2 s2 = makeEmptySound(len) echoAmplitude = 1.0 for echoCount in range (1, num): echoAmplitude = echoAmplitude * 0.60 for posns1 in range (0, endS1): posns2 = posns1 + (delay * echoCount) values1 = getSampleValueAt(s1, posns1) * echoAmplitude values2 = getSampleValueAt(s2, posns2) setSampleValueAt (s2, posns2, values1 + values2) play(s2) return (s2) #Creating a Chord: add the values of C E and G at the same index def createChord(): c = makeSound(getMediaPath("bassoon-c4.wav")) e = makeSound(getMediaPath("bassoon-e4.wav")) g = makeSound(getMediaPath("bassoon-g4.wav")) chordLength = getLength(c) chord = makeEmptySound (chordLength) for index in range (0, chordLength): cValue = getSampleValueAt(c, index) eValue = getSampleValueAt(e, index) gValue = getSampleValueAt(g, index) total = cValue + eValue + gValue setSampleValueAt(chord, index, total) return chord #changing the frequency of a sound #Double the frequency: the sound will have the same amount of cycles #in half the amount of time def double(source): len = getLength(source) / 2 + 1 #resulting sound will be half as long as the source target = makeEmptySound(len) targetIndex = 0 for sourceIndex in range (0, getLength(source), 2): #we take every other sample sourceValue = getSampleValueAt(source, sourceIndex) setSampleValueAt (target, targetIndex, sourceValue) targetIndex = targetIndex + 1 play(target) return target #halve the frequency: the sound will have the same amount of cycles #in double the amount of time def halve(source): len = getLength(source) * 2 #resulting sound will be twice as long as the source target = makeEmptySound(len) sourceIndex = 0 for targetIndex in range (0, getLength(target)): value = getSampleValueAt(source, int(sourceIndex)) setSampleValueAt(target, targetIndex, value) sourceIndex = sourceIndex + 0.5 #we sample the source sound twice each time play(target) return(target) #A more general function to change the frequence (increase it or decrease it) def shift (source, factor): len = getLength(source) target = makeEmptySound(len) sourceIndex = 0 for targetIndex in range (0, len): sourceValue = getSampleValueAt(source,sourceIndex) setSampleValueAt(target, targetIndex, sourceValue) sourceIndex = sourceIndex + factor if (sourceIndex >= len): sourceIndex = 0 play(target) return (target) #example of calling a function from inside another function #This exmaple plays a sound 5 times, increasing the frequency each time #The function playASequence makes use of the function shift() def playASequence (file): for factor in range (1, 6): sound = makeSound (file) target = shift(sound, factor) blockingPlay(target) #Generating a sine wave at a given frequency and amplitude #This example uses the formulas on page 195 in the textbook def sineWave(freq, amplitude): soundFile = getMediaPath('sec1silence.wav') #a 1-second blank sound file buildSine = makeSound(soundFile) samplingRate = getSamplingRate(buildSine) #sampling rate interval = 1.0 / freq samplesPerCycle = interval * samplingRate maxCycle = 2 * pi #pi = 3.14259 constant defined already in Python for pos in range (0, getLength(buildSine)): rawSample = sin((pos/samplesPerCycle) * maxCycle) sampleVal = int (amplitude * rawSample) setSampleValueAt(buildSine, pos, sampleVal) return buildSine #Generating square waves given a frequency and amplitude def squareWave (freq, amplitude): #create a blank sound mySoundFile = getMediaPath("sec1silence.wav") square = makeSound (mySoundFile) #set music constants samplingRage = getSamplingRate(square) #sampling rate seconds = 1 #play for 1 second interval = 1.0 * seconds /freq #seconds per cycle samplesPerCycle = interval * samplingRage samplesPerHalfCycle = int (samplesPerCycle / 2) sampleVal = amplitude i = 1 #half cycle counter for s in range (0, getLength(square)): if (i > samplesPerHalfCycle) : #have we reach the end of the half cycle? sampleVal = sampleVal * -1 #reverse the amplitude every half cycle i = 0 #re-initialize the half cycle counter setSampleValueAt (square, s, sampleVal) i = i + 1 return square #Creating a triangular wave def triangleWave (freq, theAmplitude): #create a blank sound mySoundFile = getMediaPath("sec1silence.wav") triangle = makeSound (mySoundFile) #set music constants amplitude = theAmplitude samplingRate = 22050 #sampling rate seconds = 1 #play for 1 second interval = 1.0 * seconds /freq #seconds per cycle samplesPerCycle = interval * samplingRate samplesPerHalfCycle = int (samplesPerCycle / 2) increment = int (amplitude / samplesPerHalfCycle) sampleVal = -amplitude i = 1 #half cycle counter for s in range (0, samplingRate): if (i == samplesPerHalfCycle) : #have we reach the end of the half cycle? increment = increment * -1 #reverse the amplitude every half cycle i = 0 #re-initialize the half cycle counter sampleVal = sampleVal + increment setSampleValueAt (triangle, s, sampleVal) i = i + 1 return triangle #JES function: playNote(MIDI Note, duration, intensity) # duration in milliseconds, intensity is a value between 0 and 127 #This function plays a sound in MIDI format #Useful url: http://www.phys.unsw.edu.au/jw/notes.html def song(): playNote(60, 400, 127) playNote(60, 400, 127) playNote(67, 400, 127) playNote(67, 400, 127) playNote(69, 400, 127) playNote(69, 400, 127) playNote(67, 800, 127)
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.