Sample Project Walkthrough
Using PyAudio
Here are the basic record and play functions you need!
#audio lecture
#pyaudio demo
#Code modified from https://people.csail.mit.edu/hubert/pyaudio/
###########################################################################
######################### Playing a WAV file ##############################
###########################################################################
"""PyAudio Example: Play a WAVE file."""
import pyaudio
import wave
from array import array
from struct import pack
def play(file):
CHUNK = 1024 #measured in bytes
wf = wave.open(file, 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while len(data) > 0:
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
p.terminate()
###########################################################################
######################### Recording a WAV file ############################
###########################################################################
def record(outputFile):
CHUNK = 1024 #measured in bytes
FORMAT = pyaudio.paInt16
CHANNELS = 2 #stereo
RATE = 44100 #common sampling frequency
RECORD_SECONDS = 5 #change this record for longer or shorter!
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(outputFile, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
Using Pydub: AudioSegment
This is useful for combining, modifying, and concatenating sounds.
#audio segment demo
#Modified from https://github.com/jiaaro/pydub
#Wrappers around methods written by Tara Stentz
from pydub import AudioSegment
def soundFromFile(file):
return AudioSegment.from_wav(file)
def getLen(file):
return len(soundFromFile(file))
def changeVolume(file, amount):
sound = soundFromFile(file)
loudSound = sound + amount
exportToFile(loudSound, "loudSound.wav")
return "loudSound.wav"
def exportToFile(sound, file):
sound.export(file, format="wav")
return file
def concatNotes(sound1, sound2, filename):
return exportToFile(sound1 + sound2, filename)
def repeatSound(file, amount):
sound = soundFromFile(file)
return exportToFile(sound * amount, "repeat.wav")
def getSection(file, start, end):
sound = soundFromFile(file)
newSound = sound[start:end]
return exportToFile(newSound, "slice.wav")
#basic code frame work inspired by http://pydub.com
#and http://stackoverflow.com/questions/4039158/mixing-two-audio-files-together-with-python
#(*args) means you can put in as many arguments as you like
def mixNotes(*args):
if(len(args) > 1):
currentFile = args[0]
for index in xrange(1, len(args)):
sound1 = AudioSegment.from_wav(currentFile)
sound2 = AudioSegment.from_wav(args[index])
combined = sound1.overlay(sound2)
name = str(currentFile) + str(args[index])
combined.export(name, format='wav')
currentFile = name
chord = AudioSegment.from_wav(currentFile)
chord.export(currentFile, format="wav")
return currentFile
Aubio Demo
This does simple pitch detection. Feel free to modify it, I certainly did for my project!
import aubio
#modified from https://github.com/aubio/aubio/blob/master/python/demos/demo_pitch.py
def detect(filename):
downsample = 8
samplerate = 44100 / downsample
win_s = 4096 / downsample # fft size
hop_s = 512 / downsample # hop size
s = aubio.source(filename, samplerate, hop_s)
samplerate = s.samplerate
tolerance = 0.8
pitch_o = aubio.pitch("yin", win_s, hop_s, samplerate)
pitch_o.set_unit("freq")
pitch_o.set_tolerance(tolerance)
pitches = []
confidences = []
# total number of frames read
total_frames = 0
counter = 0
while True:
samples, read = s()
pitch = pitch_o(samples)[0]
confidence = pitch_o.get_confidence()
if confidence < 0.8: pitch = 0.
print "%f %f %f" % (total_frames / float(samplerate), pitch, confidence)
pitches += [pitch]
confidences += [confidence]
total_frames += read
if read < hop_s: break
return pitches