Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > media > main-release > by-pkgid > 8e9e4cda16218950f2429bda60c8d306 > files > 15

python-musicbrainz-2.1.5-3mdv2008.1.x86_64.rpm

#!/usr/bin/env python

import sys, os, getopt
import musicbrainz
import ogg.vorbis   # get this from http://www.andrewchatham.com/pyogg/
import ao           # get this from http://www.andrewchatham.com/pyogg/
import mad          # get this from http://spacepants.org/src/pymad/
import wave         # should come with python

def getSignature(filename, playWhileReading = None): 
    (path, ext) = os.path.splitext(filename)
    if ext.lower() == '.ogg':
        ff = ogg.vorbis.VorbisFile(filename)
    elif ext.lower() == '.mp3':
        ff = MadWrapper(filename)
    elif ext.lower() == '.wav':
        ff = WavWrapper(filename)
    else:
        raise SystemError, "Unsupported audio file."

    if playWhileReading:
        device = 'esd'
        id = ao.driver_id(device)
        aodev = ao.AudioDevice(id)

    info = ff.info()
    trm = musicbrainz.trm()
    trm.SetPCMDataInfo(info.rate, info.channels, 16)
    while 1:
        (buff, bytes, bit) = ff.read()
        if bytes == 0:
            break
        if trm.GenerateSignature(buff):
            break
        if playWhileReading:
            aodev.play(buff, bytes)

    sig = trm.FinalizeSignature()

    return sig

class WavWrapper:
    """
    Make the wave module act more like ogg.vorbis.VorbisFile
    """
    def __init__(self, filename):
        self.ff = wave.open(filename, 'r')
    
    def read(self):
        """
        These docs are from ogg.vorbis.VorbisFile.read()
        
        @returns: Returns a tuple: (x,y,y) where x is a buffer object of the
            data read, y is the number of bytes read, and z is whatever the
            bitstream value means (no clue).
        @returntype: tuple
        """
        buff = self.ff.readframes(4096)
        return (buff, len(buff), None)

    def info(self):
        return AudioInfo(self.ff.getframerate(), self.ff.getnchannels())

class MadWrapper:
    """
    Make the mad module act more like ogg.vorbis.VorbisFile
    """
    def __init__(self, filename):
        self.ff = mad.MadFile(filename)
    
    def read(self):
        """
        These docs are from ogg.vorbis.VorbisFile.read()
        
        @returns: Returns a tuple: (x,y,y) where x is a buffer object of the
            data read, y is the number of bytes read, and z is whatever the
            bitstream value means (no clue).
        @returntype: tuple
        """
        buff = self.ff.read()
        if buff:
            return (buff, len(buff), None)
        else:
            return ('', 0, None)
            
    def info(self):
        if self.ff.mode() == mad.MODE_SINGLE_CHANNEL:
            channels = 1
        else:
            channels = 2
        return AudioInfo(self.ff.samplerate(), channels)


class AudioInfo:
    def __init__(self, rate, channels):
        self.rate = rate
        self.channels = channels

def usage():
    print "%s: generate a MusicBrainz TRM signature" % sys.argv[0]
    print "     --play      play the file while decoding"
    print "     --help      show this message"
    
    
def main():
    playWhileReading = None

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hp", ["help", "play"])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-p", "--play"):
            playWhileReading = 1

    for filename in args:
        print getSignature(filename, playWhileReading)

if __name__ == '__main__':
    main()