Contact: david.ogborn@utoronto.ca
Project hosted by: sourceForge.net
module Csound

The module Csound is a text-based pseudo-binding to the Csound 4 executable.


{- Csound pseudo-binding for Allegory
   by David Ogborn, david.ogborn@utoronto.ca
   (c) 2004
-}

module Csound where

import Allegory
import Sndfile
import IO
import IOExts
import System
import Hugs.Quote

-- Paths and settings (edit as required for your project):
csoundPath = "csound"
csoundOptions = "-d -s -W"
--

The function 'csound' takes as its argument an entire Csound score and orchestra combination (CSD format) and returns a Sound computation that when executed will realize this score and orchestra combination. For examples of how to use this idiom, see the module Generators.


csound :: String -> Sound
csound x = M (\s -> let f = tempsDir ++ "/tempsound-" ++ (show s) ++ ".wav"
                    in (s+1, (\n -> csoundIO x n), f))
 where csoundIO csdStr outFile =
         do let orchPath = tempsDir ++ "/temp.csd"
            h <- openFile orchPath WriteMode
            hPutStr h csdStr
            hClose h
            system (csoundPath ++ " " ++ csoundOptions ++ " -o " ++ outFile ++ " " ++ orchPath)
            return ()

The function csdImportFilter is a convenient mechanism for "importing" simple filter behaviour (etc) from csound.
Take the csound opcode 'butterlp' as an example.

this is used in the following way:
aout butterlp ain,kfreq

our function below will provide the output variable
so the 'prefix' argument will contain everything after that but preceding the input variable's name
and the 'suffix' argument will contain everything after that
(csdImportFilter "butterlp," ",300")
...therefore will be of type FilePath -> Sound
...and will be a computation that given a sound, applies a 300 Hz low-pass filter to each channel separately
the final step:
butterlp :: Double -> FilePath -> Sound
butterlp f = applyModifier "butterlp," (","++(show f))


csoundImportFilter :: String -> String -> Filter
csoundImportFilter prefix suffix inputTarget = csound csdStr
 where duration = sfDuration inputTarget
       nchnls = sfChannels inputTarget
       diskin
        | nchnls == 1 = "a1"
        | nchnls == 2 = "a1,a2"
        | nchnls == 4 = "a1,a2,a3,a4"
       filters = concat [ "af" ++ (show n) ++ " " ++ prefix ++ "a" ++ (show n) ++ suffix ++ "\n" | n <- [1..nchnls]]
       out
        | nchnls == 1 = "out af1"
        | nchnls == 2 = "outs af1,af2"
        | nchnls == 4 = "outq af1,af2,af3,af4"
       csdStr = ``<CsoundSynthesizer>
<CsInstruments>
sr=44100
kr=441
ksmps=100
nchnls=$(nchnls)
instr 1
           $(diskin) diskin "$(inputTarget)", 1
    $(filters)
           $(out)
endin
</CsInstruments>
<CsScore>
i1 0 $(duration)
</CsScore>
</CsoundSynthesizer>''