#   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 tempfile import *
import tempfile
from os import *
from wave import *
from OBBFuncts import *

class OBBCSoundTorturer:
    def __init__(self, filePrefix = mktemp()):
        self.fileName = filePrefix

    def createOrchestraFile(self, songDoc):
        inputText = "; Orchestra file"
        inputText += "\n    sr=44100"
        inputText += "\n    kr=4410"
        inputText += "\n    ksmps=10"
        inputText += "\n    nchnls=2\n"  #stereo
        inputText += "\n    ga1  init 0\n"

        for i in songDoc.songOrchestra.get():
            inputText += "\n    instr %d" % (i+1)
            inputText += "\n        asource1, asource2 diskin     "
            inputText += "\"" \
            + songDoc.songOrchestra.get()[i].getPlayFilePath() + "\", 1, 0, 1"
            inputText += "\n                outs         asource1, asource2"
            inputText += "\n                endin\n"

        file(self.fileName + ".orc", 'w+').write(inputText)
        debug(inputText)

    def createScoreFile(self, songDoc, start, length):
        returnValue = 0
        inputText = "; Score file\n;%s%8s%11s" % ( "p1", "p2", "p3" )
        songDoc.songScore.printScore()
        instrs = songDoc.songScore.Get()
        beat = 60.0/songDoc.getTempo()
        formatstring = "\n%s %10.3f %10.3f"
        for i in instrs:
            for j in instrs[i]:
                if start+length > j >= start:
                    returnValue = 1
                    inputText += formatstring % \
                        (" i%d" %(i + 1), \
                        (j - start) * beat, \
                        songDoc.getInstrument(i).duration)

        file(self.fileName + ".sco", 'w+').write(inputText + "\n")
        debug(inputText)
        return returnValue

    def createWaveFile(self, orchestraFile = None, scoreFile = None):
        if orchestraFile == None:
            orchestraFile = self.fileName
        if scoreFile == None:
            scoreFile = self.fileName
        # TODO : plug a big random value in sufix
        targetWave = tempfile.mktemp() + ".wav"

        cmd = "csound -o '%s' -W '%s.orc' '%s.sco' 2>/dev/null 1>&2"
        cmd = cmd  % ( targetWave, orchestraFile, scoreFile )
        debug(cmd)
        system(cmd)
        self.purgeFiles(orchestraFile, scoreFile)
        if access(targetWave, R_OK):
            return targetWave
        else:
            raise Exception("wav file %s was not created." % (targetWave))


    def createModifiedSampleFile(self, instrument):
        orchestraFile = tempfile.mktemp()
        inputText = "; Orchestra file"
        inputText += "\n    sr=44100"
        inputText += "\n    kr=4410"
        inputText += "\n    ksmps=10"
        inputText += "\n    nchnls=2\n"
        inputText += "\n    ga1  init 0"
        inputText += "\n\n    instr 1"
        inputText += "\n        asig    soundin     "
        inputText += "\"" + instrument.getFilePath() + "\""
        inputText += "\n        aout  = asig"
        inputText += "\n        a1      alpass aout, 100, %3.1f" \
            % (100.1-instrument.leftVolume)
        inputText += "\n        a2      alpass aout, 100, %3.1f" \
            % (100.1-instrument.rightVolume)
        inputText += "\n                outs         a1, a2"
        inputText += "\n                endin\n"
        file(orchestraFile + ".orc", 'w+').write(inputText)
        if not access(orchestraFile + ".orc" , R_OK):
            raise Exception("file %s was not created." % (orchestraFile))

        scoreFile = tempfile.mktemp()
        inputText = "; Score file\n;p1      p2         p3"
        wavefile = open(instrument.getFilePath(), 'r')
        duration = (1.0*wavefile.getnframes())\
            /(1.0*wavefile.getframerate())
        wavefile.close()
        inputText += "\n i1      0.000%10.3f" %( duration )
        file(scoreFile + ".sco", 'w+').write(inputText + "\n")
        if not access(scoreFile + ".sco", R_OK):
            raise Exception("file %s was not created." % (scoreFile))

        return self.createWaveFile(orchestraFile, scoreFile)

    def purgeFiles(self, orcFilePath = None, scoFilePath = None):
        if access(orcFilePath + ".orc", R_OK):
            remove(orcFilePath + ".orc")

        if access(scoFilePath + ".sco", R_OK):
            remove(scoFilePath + ".sco")
