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