Skip to content

Instantly share code, notes, and snippets.

@alexholcombe
Created August 13, 2012 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexholcombe/3344671 to your computer and use it in GitHub Desktop.
Save alexholcombe/3344671 to your computer and use it in GitHub Desktop.
some sound processing of wav files
#!/usr/bin/env python
"""
by Alex Holcombe
license: CC-ZERO
This code is a mess and a melange of sound processing, but was
uploaded because booradleyboo asked about sound processing on the google groups.
"""
import sys,os
import math
from os import path
from psychopy import sound,core, visual
import pygame
import numpy, numpy as np
#import scipy
#import wave, struct
def printAllFilesAllSubdirs():
#print all files in subdirectories
for dirname, dirnames, filenames in os.walk('.'):
for subdirname in dirnames:
print os.path.join(dirname, subdirname)
for filename in filenames:
print os.path.join(dirname, filename)
#highA = sound.Sound('A',octave=3, sampleRate=22050, secs=0.8, bits=8)
#highA.setVolume(0.8)
#tick = sound.Sound(800,secs=0.01,sampleRate=44100, bits=8)#sample rate ignored because already set
#tock = sound.Sound('600',secs=0.01)
#
#highA.play()
#core.wait(0.8)
#tick.play()
#core.wait(0.4)
#tock.play()
#core.wait(0.2)
filePath='./sound_files/'
fileName='20dtest1.wav' #'tada.wav' #seems to use directory that this codefile is in. So need to ensure sound file is in that directory
fnameWithPath = path.join(filePath,fileName)
checkSoundFileWorks = False
if checkSoundFileWorks:
print 'file to try to get, with path is =', fnameWithPath
print 'Is file =', path.isfile(fnameWithPath)
tada=sound.Sound(fnameWithPath)
print 'tada Sound object=',tada
tada.setVolume(1)
tada.play()
core.wait(2)
#try importing as array
pathWav= './importWavfile/'
#print 'files=', os.listdir(pathWav)
sys.path.append(pathWav)
import wavfile
#rateAndArray= wavfile.read(fnameWithPath)
#print 'rateAndArray type=',type(rateAndArray),
#print ' Expected tuple length of 2, with first entry sampleRate, and length is =',len(rateAndArray)
#wavSampleRate = rateAndArray[0]
#wf = rateAndArray[1]
#print 'sampleRate=', wavSampleRate, 'wf type=',type(wf),' len=',len(wf),' shape=',numpy.shape(wf)
#print 'rateAndArray shape = ',numpy.shape(rateAndArray)
#
#print 'wf type=',type(wf),' len=',len(wf),' shape=',numpy.shape(wf)
#print 'wf channel 0=',np.around(wf[:,0],1), 'max=',np.max(wf),' min=',np.min(wf)
#print 'wf middle = ',np.around( wf[ len(wf)/2:len(wf)/2+10, 0 ] ,1)
#may reveal that sound file is of integers rather than going from -1 to 1
#
#ampMax = np.max( np.abs(wf) )
#bring into range -1 to 1, by dividing everything by the maximum amplitude
#wf = wf / (1.0*ampMax)
#print 'wf channel 0=',np.around(wf[:,0],1), 'max=',np.max(wf),' min=',np.min(wf)
#
#play the sound
#arraySnd=sound.SoundPygame(value=wf, sampleRate=wavSampleRate, bits=16, name='', autoLog=True)
#arraySnd.play()
#core.wait( len(wf) / wavSampleRate )
#####################################
#Try to import a large file
fileName='babbleds.wav' #'tada.wav' #seems to use directory that this codefile is in. So need to ensure sound file is in that directory
fnameWithPath = path.join(filePath,fileName)
rateAndArray= wavfile.read(fnameWithPath)
print 'rateAndArray type=',type(rateAndArray),
print ' Expected tuple length of 2, with first entry sampleRate, and length is =',len(rateAndArray)
wavSampleRate = rateAndArray[0]
wf = rateAndArray[1]
ampMax = np.max( np.abs(wf) )
#bring into range -1 to 1, by dividing everything by the maximum amplitude
wf = wf / (1.0*ampMax)
print 'wf channel 0=',np.around(wf[:,0],1), 'max=',np.max(wf),' min=',np.min(wf)
#trim clip
durDesired = 5
wf = wf[0:durDesired*wavSampleRate,:]
#play the sound
playClip = False
if playClip:
arraySnd=sound.SoundPygame(value=wf, sampleRate=wavSampleRate, bits=16, name='', autoLog=True)
arraySnd.play()
soundDur = len(wf) *1.0 / wavSampleRate
print 'soundDur = ',soundDur
core.wait( soundDur )
###################################################
#Try to add two sounds together
#get first sound
fileName='babbleds.wav' #'tada.wav' #seems to use directory that this codefile is in. So need to ensure sound file is in that directory
fnameWithPath = path.join(filePath,fileName)
rateAndArray= wavfile.read(fnameWithPath)
wavSampleRate = rateAndArray[0]
wf = rateAndArray[1]
#bring into range -1 to 1, by dividing everything by the maximum amplitude
ampMax = np.max( np.abs(wf) )
wf = wf / (1.0*ampMax)
wfBabble = wf
#trim clip
durDesired = 2
wfBabble = wfBabble[0:durDesired*wavSampleRate,:]
def loadWavIntoArray(fname,expectedSampleRate):
#fnameWithPath = path.join(path,fname)
#fnameWithPath = path.join(path,filename)
rateAndArray= wavfile.read(fname)
wavSampleRate = rateAndArray[0]
if wavSampleRate != expectedSampleRate:
print 'sampling rate of word (',wavSampleRate,') does not equal that expected of ', expectedSampleRate
wf = rateAndArray[1]
#bring into range -1 to 1, by dividing everything by the maximum amplitude
ampMax = np.max( np.abs(wf) )
wf = wf / (1.0*ampMax)
return (wavSampleRate, wf)
#get second sound
wordsPath = './sound_files/male_words'
fileName = 'blush.wav'
wavSampleRateWord,wfWord = loadWavIntoArray(path.join(wordsPath,fileName),22050)
#normalize to some particular amp
ampDesired = .5
#bring into range -1 to 1, by dividing everything by the maximum amplitude
wfWord *= ampDesired
wfBabble *= 0.4
#add Word to the babble
lenWord = len(wfWord)
lenBabble = len(wfBabble)
print 'shape word =',np.shape(wfWord), 'max=',np.max(wf),' min=',np.min(wf)
#wfBabble[ int(lenBabble/2): int(lenBabble/2)+lenWord, : ] = wfWord
wfBabble[ int(lenBabble/2): int(lenBabble/2)+lenWord, 0 ] += wfWord[:]
wfBabble[ int(lenBabble/2): int(lenBabble/2)+lenWord, 1 ] += wfWord[:]
arraySnd=sound.SoundPygame(value=wfBabble, sampleRate=wavSampleRate, bits=16, name='', autoLog=True)
arraySnd.play()
core.wait( len(wfBabble) *1.0 / wavSampleRate )
#What do I set each amp to, to get desired relative level?
#get a dialogue box, see if it works after a trial or if full screen window is incompatible with it
from psychopy import gui
#create a window to draw in
myWin = visual.Window(monitor='testMonitor', allowGUI=True, units ='deg', screen=0, fullscr=0)
rotating = visual.TextStim(myWin,text="Fonts \nrotate!",pos=(0, 0),#and can have line breaks
color=[-1.0,-1,1],
units='deg',
ori=0, height = 1.0,
font='Comic Sans MS' )
fpsText = visual.TextStim(myWin,
units='norm',height = 0.1,
pos=(-0.98, -0.98), text='starting...',
font='Gill Sans MT',
alignHoriz = 'left',alignVert='bottom',
color='BlanchedAlmond')
trialClock = core.Clock()
t=lastFPSupdate=0;
while t<1:#quits after 1 secs
t=trialClock.getTime()
rotating.setOri(1,"+")
rotating.draw()
if t-lastFPSupdate>1:#update the fps every second
fpsText.setText("%i fps" %myWin.fps())
lastFPSupdate+=1
fpsText.draw()
myWin.flip()
myDlg = gui.Dlg(title="RSVP experiment", pos=(200,400))
myDlg.addField('word (default="dunno"):', tip='or subject code')
myDlg.addText('Note: during the experiment, press ESC at response screen to quit', color='DimGrey')
myDlg.show()
if myDlg.OK:
thisInfo = myDlg.data #this will be a list of data returned from each field added in order
trialsField = 1
name=thisInfo[0]
if len(name) > 0: #if entered something
word = name #change subject default name to what user entered
print 'user entered word: ',word
else:
print 'user cancelled'
logging.flush()
core.quit()
print 'done'
core.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment