#!/usr/bin/python

import socket
import Queue
import threading

try:
    import ossaudiodev
except ImportError:
    ossaudiodev = None

class AudioOutput(object):
    """
    @ivar rate: The bitrate of the audio that is to be processed.
    """
    rate = 8000

    def __init__(self):
        try:
            self.p = self.createPipe()
        except (IOError, AttributeError):
            self.p = file('/dev/null', 'w')
        
        # store 100 fragments of data max.
        self.q = Queue.Queue(maxsize=100)
        
    def createPipe(self):
        p = ossaudiodev.open('w')
        p.setfmt(ossaudiodev.AFMT_U8)
        p.speed(self.rate) 
        p.channels(1)
        return p
        
    def feed(self, data):
    	"""
    	@param data: raw audio data from the network to be played on the audio
    	             device.
    	"""
        try:
            self.q.put(data, block=False)
        except Queue.Full:
            pass
        
    def runForever(self):
        while 1:
            data = self.q.get(block=True)
            self.p.write(data)
            
    def close(self):
        self.p.close()

class UDPListener(object):

    def __init__(self, port):
        self.s = self.createSocket(port)
        
    def createSocket(self, port):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.bind(('', port))
        return s

    def listenForever(self, output):
        while 1:
        	data, addr = self.s.recvfrom(output.rate/10)
        	output.feed(data)
        	
    def close(self):
        self.s.close()

def main():
    port = 8051
    host = '224.0.0.1'

    output = AudioOutput()
    listener = UDPListener(port)
    audio_thread = threading.Thread(target=output.runForever)
    audio_thread.setDaemon(True)
    audio_thread.start()
    try:
        listener.listenForever(output)
    except (KeyboardInterrupt, SystemExit):
        pass
    listener.close()
    output.close()
    
if __name__ == '__main__':
    main()
