#!/usr/bin/python
# -*- mode: python -*-

import os
import threading

import pygst
pygst.require('0.10')
import gst

class Converter:
    def __init__(self, pathname, formats=['sln', 'ulaw', 'alaw', 'gsm']):
        
        self.pathname = pathname
        self.formats = formats
        
        self.pipeline = None

        self.pipeline = gst.Pipeline()

        wavsource = gst.element_factory_make('filesrc')
        wavsource.set_property('location', pathname)
        self.pipeline.add(wavsource)
        
        wavparse = gst.element_factory_make('wavparse')
        wavparse.connect('pad-added', self.pad_added_cb)
        self.pipeline.add(wavparse)

        wavsource.link(wavparse)
        
        res = self.pipeline.set_state(gst.STATE_PLAYING);
        if res == gst.STATE_CHANGE_FAILURE:
            print self.pathname, 'unable to set playing'
            return
        
        bus = self.pipeline.get_bus()

        while 1:
            msg = bus.poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR | gst.MESSAGE_APPLICATION, gst.SECOND)
            if msg:
                break

        res = self.pipeline.set_state(gst.STATE_NULL)
        assert res

    def pad_added_cb(self, element, pad):
        caps = pad.get_caps()
        bus = self.pipeline.get_bus()
        
        if len(caps) != 1:
            bus.post(gst.message_new_application(element, gst.Structure('More than one capability!!!')))
            return
        
        if caps[0].get_name() != 'audio/x-raw-int':
            bus.post(gst.message_new_application(element, gst.Structure('Ack! Can\'t deal with anything but audio/x-raw-int yet!')))
            return
        
        if caps[0]['channels'] > 1:
            audioconvert = gst.element_factory_make('audioconvert')
            self.pipeline.add(audioconvert)
            
            pad.link(audioconvert.get_pad('sink'))
            pad = audioconvert.get_pad('src')

        if caps[0]['rate'] != 8000:
            audioresample = gst.element_factory_make('audioresample')
            self.pipeline.add(audioresample)

            pad.link(audioresample.get_pad('sink'))
            pad = audioresample.get_pad('src')
            
        capsfilter = gst.element_factory_make('capsfilter')
        capsfilter.set_property('caps', gst.caps_from_string('audio/x-raw-int,rate=8000,channels=1'))
        self.pipeline.add(capsfilter)

        pad.link(capsfilter.get_pad('sink'))

        progressreport = gst.element_factory_make('progressreport', self.pathname)
        progressreport.set_property('update-freq', 1)
        self.pipeline.add(progressreport)
        capsfilter.link(progressreport)
        
        tee = gst.element_factory_make('tee')
        self.pipeline.add(tee)
        progressreport.link(tee)

        if 'sln' in self.formats:
            slinear_queue = gst.element_factory_make('queue')
            self.pipeline.add(slinear_queue)

            slinear_caps = gst.element_factory_make('capsfilter')
            slinear_caps.set_property('caps', gst.caps_from_string('audio/x-raw-int,rate=8000,channels=1'))
            self.pipeline.add(slinear_caps)
            
            slinear_sink = gst.element_factory_make('filesink')
            slinear_sink.set_property('location', self.pathname[:-4] + '.sln')
            self.pipeline.add(slinear_sink)

            pad = tee.get_request_pad('src%d')
            pad.link(slinear_queue.get_pad('sink'))

            slinear_queue.link(slinear_caps)
            slinear_caps.link(slinear_sink)

        if 'ulaw' in self.formats:
            ulaw_queue = gst.element_factory_make('queue')
            self.pipeline.add(ulaw_queue)

            ulaw_encoder = gst.element_factory_make('mulawenc')
            self.pipeline.add(ulaw_encoder)

            ulaw_caps = gst.element_factory_make('capsfilter')
            ulaw_caps.set_property('caps', gst.caps_from_string('audio/x-mulaw,rate=8000,channels=1'))
            self.pipeline.add(ulaw_caps)
            
            ulaw_sink = gst.element_factory_make('filesink')
            ulaw_sink.set_property('location', self.pathname[:-3] + '.ulaw')
            self.pipeline.add(ulaw_sink)

            pad = tee.get_request_pad('src%d')
            pad.link(ulaw_queue.get_pad('sink'))

            ulaw_queue.link(ulaw_encoder)
            ulaw_encoder.link(ulaw_caps)
            ulaw_caps.link(ulaw_sink)

        if 'alaw' in self.formats:
            alaw_queue = gst.element_factory_make('queue')
            self.pipeline.add(alaw_queue)

            alaw_encoder = gst.element_factory_make('alawenc')
            self.pipeline.add(alaw_encoder)

            alaw_caps = gst.element_factory_make('capsfilter')
            alaw_caps.set_property('caps', gst.caps_from_string('audio/x-alaw,rate=8000,channels=1'))
            self.pipeline.add(alaw_caps)
            
            alaw_sink = gst.element_factory_make('filesink')
            alaw_sink.set_property('location', self.pathname[:-3] + '.alaw')
            self.pipeline.add(alaw_sink)

            pad = tee.get_request_pad('src%d')
            pad.link(alaw_queue.get_pad('sink'))

            alaw_queue.link(alaw_encoder)
            alaw_encoder.link(alaw_caps)
            alaw_caps.link(alaw_sink)

        if 'gsm' in self.formats:
            gsm_queue = gst.element_factory_make('queue')
            self.pipeline.add(gsm_queue)

            gsm_encoder = gst.element_factory_make('gsmenc')
            self.pipeline.add(gsm_encoder)

            gsm_caps = gst.element_factory_make('capsfilter')
            gsm_caps.set_property('caps', gst.caps_from_string('audio/x-gsm,rate=8000,channels=1'))
            self.pipeline.add(gsm_caps)
            
            gsm_sink = gst.element_factory_make('filesink')
            gsm_sink.set_property('location', self.pathname[:-3] + '.gsm')
            self.pipeline.add(gsm_sink)

            pad = tee.get_request_pad('src%d')
            pad.link(gsm_queue.get_pad('sink'))

            gsm_queue.link(gsm_encoder)
            gsm_encoder.link(gsm_caps)
            gsm_caps.link(gsm_sink)

        self.pipeline.set_state(gst.STATE_PLAYING)

directories = ['.']

while directories:
    directory = directories.pop()
    filenames = os.listdir(directory)
    for filename in filenames:
        pathname = os.path.join(directory, filename)
        if os.path.isdir(pathname):
            directories.append(pathname)
        elif filename.endswith('.wav'):
            pathname = os.path.join(directory, filename)
            converter = Converter(pathname)
