Skip to content

Instantly share code, notes, and snippets.

@zeimusu
Last active December 31, 2015 14:49
Show Gist options
  • Save zeimusu/8002708 to your computer and use it in GitHub Desktop.
Save zeimusu/8002708 to your computer and use it in GitHub Desktop.
Simulate church bell changes ringing. It requires six .wav files representing six bells. They should be less than five seconds long. You might try for bells pitched at C,D,E,G,A,C. The output is written to changes.wav
#!/usr/bin/env python3
# Simulate church bell changes ringing.
# It requires six .wav files representing six bells.
# They should be less than five seconds long.
# You might try for bells pitched at C,D,E,G,A,C.
#
# The output is written to changes.wav
import random
import wave
import numpy
rate = 22050
# the sample files: bell-01..06.wav had better be this rate.
bell1=wave.open("bell-01.wav","r")
bell1length = bell1.getnframes()
bell1samples = numpy.fromstring(bell1.readframes(bell1length),dtype=numpy.int16)
bell1samples.resize(rate*5)
bell1.close()
bell2=wave.open("bell-02.wav","r")
bell2length = bell2.getnframes()
bell2samples = numpy.fromstring(bell2.readframes(bell2length),dtype=numpy.int16)
bell2samples.resize(rate*5)
bell2.close()
bell3=wave.open("bell-03.wav","r")
bell3length = bell3.getnframes()
bell3samples = numpy.fromstring(bell3.readframes(bell3length),dtype=numpy.int16)
bell3samples.resize(rate*5)
bell3.close()
bell4=wave.open("bell-04.wav","r")
bell4length = bell4.getnframes()
bell4samples = numpy.fromstring(bell4.readframes(bell4length),dtype=numpy.int16)
bell4samples.resize(rate*5)
bell4.close()
bell5=wave.open("bell-05.wav","r")
bell5length = bell5.getnframes()
bell5samples = numpy.fromstring(bell5.readframes(bell5length),dtype=numpy.int16)
bell5samples.resize(rate*5)
bell5.close()
bell6=wave.open("bell-06.wav","r")
bell6length = bell6.getnframes()
bell6samples = numpy.fromstring(bell6.readframes(bell6length),dtype=numpy.int16)
bell6samples.resize(rate*5)
bell6.close()
pitches = [bell1samples,bell2samples,bell3samples,bell4samples,bell5samples,bell6samples]
changeswav = wave.open("changes.wav","w")
changeswav.setframerate(rate)
changeswav.setsampwidth(2)
changeswav.setnchannels(1)
soundbuffer = numpy.zeros(rate*5,dtype=numpy.int16)
def play(pitch):
'''pitch is a np array.
it is added to the soundbuffer (in a dumb way), and then half a second of
sound is taken off the buffer and written to the output file.
'''
global soundbuffer
soundbuffer = (soundbuffer//2 + pitch//2) #mix the pitch file into the sound
#buffer
samples = bytes(soundbuffer[:rate//2]) #extract half a second of sound
changeswav.writeframes(samples) #and write to output
soundbuffer = numpy.roll(soundbuffer,-rate//2)
soundbuffer[-rate//2:] = 0 #roll the soundbuffer and zero the tail
def flush():
'''Flush the soundbuffer and close'''
samples = bytes(soundbuffer)
changeswav.writeframes(samples)
changeswav.close()
def playchange(change):
for bell in change:
play(pitches[bell])
def randchanges():
change = [5,4,3,2,1,0]
while True:
playchange(change)
n = random.randint(0,4)
print(change[n],"to",change[n+1],change)
change[n],change[n+1] = change[n+1],change[n]
if change == [5,4,3,2,1,0] : break
playchange(change)
flush()
def testplay():
play(fsamples)
def dingdong(changing_pattern):
change = [5,4,3,2,1,0]
i=0
l=len(changing_pattern)
while True:
playchange(change)
n=changing_pattern[i%l]
print(change[n],"to",change[n+1],change)
change[n],change[n+1] = change[n+1],change[n]
if change == [5,4,3,2,1,0] : break
i += 1
playchange(change)
flush()
#randchanges()
#dingdong([0,2,4,1,3])
dingdong([0,1,3,4,2])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment