If stereo WAV file's both channels are identical, change format to mono for all files recursively
Raseliarison nirinA
nirina at mail.blueline.mg
Mon Jul 21 00:45:27 EDT 2003
the first attempt does not work well if the channels are not identical.
here is a revisited version.it works with wave files supported by wave
module
i have two questions:
- how to handle correctly the exceptions raised by wave, chunck and
other modules? is there a 'right way' to do this?
- Python seems to work fine when the '\' to pass a new line is missing.
when the backslash ought to be used to break a long line in several
one?
best regards
--
nirinA
--
#-----stereo2mono.py revisited----------
'''stereo2mono.py
convert recursively all stereo wave file to mono
if both channels are identical
http://www.faqts.com/knowledge_base/view.phtml/aid/12121/fid/538
usage : python stereo2mono.py wave_directory
'''
import wave, os, sys
FORMAT = {'11':'1b','12':'1h','21':'2b','22':'2h'}
# format for wave files encoded in 8 and 16 bits
SAMPLING = 128
class CompareError(Exception):
def __init__(self, message):
self.message = message
class Stereo2Mono:
'''open the wave file and get its parameters
compare the channels
it will be done in two steps.
samples are first compared,
then if the samples are identical
further comparison is performed
and the mono wave file created
'''
def __init__(self, name):
self.name = name
self.w = wave.open(self.name)
def isStereo(self):
if self.w.getnchannels() == 2:
return 1
else:
return 0
def format_in(self):
self.fmt = ''.join((str(self.w.getnchannels()),
str(self.w.getsampwidth())))
return FORMAT.get(self.fmt)
def format_out(self):
self.fmt = ''.join(('1',
str(self.w.getsampwidth())))
return FORMAT.get(self.fmt)
def Parameters(self):
return self.w.getparams()
def Compare(self, amplitude):
if amplitude[0] == amplitude[1]:
return 1
else:
return 0
def CompareSampling(self):
for i in range(1, self.Parameters()[3],SAMPLING):
if self.Compare(wave.struct.unpack(
self.format_in(),self.w.readframes(1))):
pass
else:
raise CompareError('Test fail at %i!'%i)
def CompareAndSave(self):
'''Compare all and save to mono'''
self.w.rewind()
self.chars = '/-\\|'
self.Save = wave.open(self.name.split('.')[0]+
'-mono'+'.wav','w')
self.newparams = (1,
self.Parameters()[1],
self.Parameters()[2],
self.Parameters()[3],
self.Parameters()[4],
self.Parameters()[5])
self.Save.setparams(self.newparams)
for i in range(1, self.Parameters()[3]+1):
self.UnPack = wave.struct.unpack(
self.format_in(), self.w.readframes(1))
if self.Compare(self.UnPack) == 1:
self.Save.writeframes(wave.struct.pack(
self.format_out(), self.UnPack[0]))
sys.stdout.write(chr(13))
sys.stdout.write('%s %i/%i ' % (
self.chars[i % 4], i, self.Parameters()[3]))
sys.stdout.flush()
else:
raise CompareError('save fail at %i!'%i)
self.w.close()
self.Save.close()
def main():
directory = sys.argv[1]
os.chdir(directory)
for name in os.listdir('.'):
if name.lower().endswith('.wav'):
try:
print name
w = Stereo2Mono(name)
if w.isStereo():
try:
w.CompareSampling()
except CompareError, e:
print 'channel not identical;', e.message
else:
w.CompareAndSave()
print 'Done'
else:
print '%s already in mono'%name
except wave.Error:
print 'this wave file is not supported'
print sys.exc_info()[1]
else:
pass
if __name__ == '__main__':
main()
#nirinA
More information about the Python-list
mailing list