#   Copyright (C) 2002-2003 Yannick Gingras <ygingras@ygingras.net>
#   Copyright (C) 2002-2003 Vincent Barbin <vbarbin@openbeatbox.org>

#   This file is part of Open Beat Box.

#   Open Beat Box is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.

#   Open Beat Box is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.

#   You should have received a copy of the GNU General Public License
#   along with Open Beat Box; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

from qt import QObject
from sndhdr import what
from pygame import mixer
from soundPath import *
from OBBConstants import *
from OBBFuncts import *

import OBBUtils.OBBSignals as sigs

class SoundDevice(QObject):
    def __init__(self, freq=44100):
        apply(QObject.__init__, (self,))
        mixer.pre_init(freq, -16, 2)
        mixer.init()

        self.sampleFile = None
        self.volume = 100
        self.nbChannels = mixer.get_num_channels()
        self.hitsPerLoad = 2
        mixer.set_reserved(self.nbChannels)
        if self.nbChannels < 2:
            raise Exception("Insuficient number of available channels.")
#       In every man's life comes a time of
#       confusion and then comes redemption
#                               --VBarbin

    def setVolume(self, volume):
        self.volume = volume
        for channelId in range(self.nbChannels):
            channel = mixer.Channel(channelId)
            if channel.get_busy():
                channel.get_sound().set_volume(self.volume*1.0/100)
        self.emit(sigs.volumeChanged, (volume,))
        

    def play(self, sampleName, times = 0):
        if what(sampleName) != None:
            sampleChannel = mixer.find_channel()
            sampleChannel.set_volume(1)
            sample = mixer.Sound(sampleName)
            sample.set_volume(self.volume*1.0/100)
            sampleChannel.play(sample, times)
        else:
            raise Exception("wav file %s not found." % (sample))

    def playLoadedSample(self, times = 0):
        #self.printDevice()
        if self.sampleFile != None:
            self.sampleFile.set_volume(self.volume*1.0/100)
            channel = mixer.find_channel()
            channel.set_volume(1)
            channel.play(self.sampleFile, times)
            self.sampleFile = None
            return 1
        else:
            debug("no sample loaded")
            return 0

    def load(self, songDoc):
        if what(songDoc.samplePath) != None:
            self.sampleFile = mixer.Sound(songDoc.samplePath)
        else:
            raise Exception("wav file %s not found." % (songDoc.samplePath))

    def stop(self, duration = 500):
        if duration == 0:
            mixer.stop()
        else:
            mixer.fadeout(duration)

    def handleHit(self, hitId):
        #debug("hit on %d" % hitId)
        if hitId % self.hitsPerLoad == 0:
            self.playLoadedSample()

    def handleLoadSample(self, songDoc):
        debug("Load")
        self.load(songDoc)
        songDoc.removeSample()

    def printDevice(self):
        for channelId in range(self.nbChannels):
            debug("Channel#%d: %d" % (channelId, mixer.Channel(channelId).get_busy()))

if __name__ == "__main__":
    import time
    print "sound check"
    SD = SoundDevice()
    for i in range(2):
        SD.play("../../sounds/hat03.wav", times = 10)
    time.sleep(1)

