csound-expression 3.3.2 → 4.0.0
raw patch · 12 files changed
+226/−64 lines, 12 filesdep ~csound-expression-typedPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: csound-expression-typed
API changes (from Hackage documentation)
- Csound.Control.Gui.Widget: value :: String -> Double -> Sink Sig
+ Csound.Air: Float32 :: SampleFormat
+ Csound.Air: Float64 :: SampleFormat
+ Csound.Air: HeaderInt16 :: SampleFormat
+ Csound.Air: Int16 :: SampleFormat
+ Csound.Air: Int24 :: SampleFormat
+ Csound.Air: Int32 :: SampleFormat
+ Csound.Air: NoHeaderFloat32 :: SampleFormat
+ Csound.Air: NoHeaderInt16 :: SampleFormat
+ Csound.Air: Uint8 :: SampleFormat
+ Csound.Air: UlawSamples :: SampleFormat
+ Csound.Air: data SampleFormat
+ Csound.Air: instance Enum SampleFormat
+ Csound.Air: instance Eq SampleFormat
+ Csound.Air: instance Ord SampleFormat
+ Csound.Air: writeAiff :: String -> (Sig, Sig) -> SE ()
+ Csound.Air: writeAiff1 :: String -> Sig -> SE ()
+ Csound.Air: writeSigs :: FormatType -> SampleFormat -> String -> [Sig] -> SE ()
+ Csound.Air: writeWav :: String -> (Sig, Sig) -> SE ()
+ Csound.Air: writeWav1 :: String -> Sig -> SE ()
+ Csound.Control.Evt: devt :: D -> Evt a -> Evt D
+ Csound.Control.Evt: type Rnds a = [(D, a)]
+ Csound.Control.Gui: mapSource :: (a -> b) -> Source a -> Source b
+ Csound.Control.Gui.Widget: setNumeric :: String -> ValDiap -> ValStep -> Double -> Sink Sig
+ Csound.Control.Instr: ctrl7 :: D -> D -> D -> D -> Sig
+ Csound.Control.Instr: holdMsg :: D -> SE (Sig, Sig)
+ Csound.Control.Instr: holdMsgn :: Channel -> D -> SE (Sig, Sig)
+ Csound.Control.Instr: initOsc :: OscPort -> SE OscRef
+ Csound.Control.Instr: initc7 :: D -> D -> D -> SE ()
+ Csound.Control.Instr: listenOsc :: Tuple a => OscRef -> OscAddress -> OscType -> Evt a
+ Csound.Control.Instr: midiCtrl :: D -> D -> D -> SE Sig
+ Csound.Control.Instr: midiCtrl7 :: D -> D -> D -> D -> D -> SE Sig
+ Csound.Control.Instr: monoMsg :: D -> D -> SE (Sig, Sig)
+ Csound.Control.Instr: monoMsgn :: Channel -> D -> D -> SE (Sig, Sig)
+ Csound.Control.Instr: pgholdMsg :: Maybe Int -> Channel -> D -> SE (Sig, Sig)
+ Csound.Control.Instr: pgmonoMsg :: Maybe Int -> Channel -> D -> D -> SE (Sig, Sig)
+ Csound.Control.Instr: sendOsc :: Tuple a => OscHost -> OscPort -> OscAddress -> OscType -> Evt a -> SE ()
+ Csound.Control.Instr: umidiCtrl :: D -> D -> D -> SE Sig
+ Csound.Control.SE: globalSensorsSE :: Tuple a => a -> SE (SE a, a -> SE ())
+ Csound.Control.SE: newGlobalSERef :: Tuple a => a -> SE (SERef a)
+ Csound.Options: setSilent :: Options
+ Csound.Types: untilDo :: BoolSig -> SE () -> SE ()
+ Csound.Types: whileDo :: BoolSig -> SE () -> SE ()
Files
- csound-expression.cabal +11/−53
- examples/Events.hs +1/−1
- src/Csound/Air.hs +52/−0
- src/Csound/Base.hs +1/−1
- src/Csound/Control/Evt.hs +7/−1
- src/Csound/Control/Gui.hs +7/−0
- src/Csound/Control/Gui/Widget.hs +1/−2
- src/Csound/Control/Instr.hs +133/−2
- src/Csound/Control/SE.hs +1/−1
- src/Csound/IO.hs +6/−2
- src/Csound/Options.hs +5/−0
- src/Csound/Types.hs +1/−1
csound-expression.cabal view
@@ -1,5 +1,5 @@ Name: csound-expression-Version: 3.3.2+Version: 4.0.0 Cabal-Version: >= 1.6 License: BSD3 License-file: LICENSE@@ -12,66 +12,24 @@ Maintainer: <anton.kholomiov@gmail.com> Description: - Let's make music with text! We can use Csound to describe our music. Csound has so many fantastic sound generators.- It's very efficient. But sometimes Csound is too low level. So many details: integer identifiers for instruments - and arrays, should I use control rate or audio rate signals, lack of abstractions, no nested expressions and it has limited set of types. - This library embeds Csound in Haskell. We can use powerful Csound's primitives and glue them- together with Haskell abstractions. The module "Csound.Base" exports all types and functions.- .- Tutorials:- .- * Quickstart guide <http://github.com/anton-k/csound-expression/blob/master/tutorial/QuickStart.markdown>- .- * Overview of the library <http://github.com/anton-k/csound-expression/blob/master/tutorial/Overview.markdown>- .- * Introduction to Csound and library for Haskell users <http://github.com/anton-k/csound-expression/blob/master/tutorial/CsoundInstro.markdown>- .- * Basics of sound synthesis with csound-expression <https://github.com/anton-k/csound-expression/blob/master/tutorial/SynthTutorial.md>- .- * There are examples in the source code archive <http://github.com/anton-k/csound-expression/tree/master/examples>. - .- Key principles- .- * Keep it simple and compact (as functional as possible).- .- * Make it open (No dependency on Score-generation libraries. Score (or list of events) - is represented with type class. You can use your favorite Score-generation library - if you provide an instance for the CsdSco type class. - Currently there is support for temporal-music-notation library (see temporal-csound package). - .- How to install (for Csound and Haskell users)- .- To use the library we need:- .- * GHC - haskell compiler. This library uses GHC-specific features (<www.haskell.org/ghc>).- .- * cabal-install to install haskell packages (<www.haskell.org/cabal>).- .- * Csound compiler (version 5.13 or higher). You must get it installed on your system.- Since we are going to generate the csound code we need to compile it to sound somehow.- We can find out how to install the Csound on <www.csounds.com>. - To test whether csound is installed open the command line and type:- .- > csound+ Welcome to the simplest textual synthesizer. .- It should print a long message with version and available flags and libraries.+ > dac $ osc 440 .- If everything is installed to install the library we can open the command line terminal and type:+ Csound-expression is a Haskell framework for computer music.+ With the help of the library we can create our instruments on the fly. + A few lines in the interpreter is enough to get the cool sound going+ out of your speakers. It can be used for simple daily sound-file processing + or for a full-blown live performances. .- > cabal install csound-expression+ Got interested? Check out the guide: <https://github.com/anton-k/csound-expression/blob/master/tutorial/Index.md> . Acknowledgements (I'd like to mention those who supported me a lot with their music and ideas): .- * music: entertainment for the braindead, ann's'annat & alizbar, toe, iamthemorning, atoms for piece / radiohead, loscil, boards of canada,+ * music: entertainment for the braindead, three pandas and the moon, odno no, ann's'annat & alizbar, toe, iamthemorning, atoms for piece / radiohead, loscil, boards of canada, Hozan Yamamoto, Tony Scott and Shinichi Yuize. . * ideas: Conal Elliott, Oleg Kiselyov, Paul Hudak, Gabriel Gonzalez, Rich Hickey and Csound's community.- .- WARNING: the library works best within ghci. The real-time sound rendering function dac spawns- a child process in the background which may continue to execute after you stop the main process that runs the programm.- It's not so in vim but it happens in the Sublime Editor and when you invoke runhaskell. So the best- is to write you program in the separate file and then load it in the ghci and invoke the function main (which- runs the sound rendering with the function dac). Extra-Source-Files : examples/README.txt@@ -109,7 +67,7 @@ Ghc-Options: -Wall Build-Depends: base >= 4, base < 5, process, data-default, Boolean >= 0.1.0,- csound-expression-typed >= 0.0.5.2, csound-expression-opcodes+ csound-expression-typed >= 0.0.5.3, csound-expression-opcodes Hs-Source-Dirs: src/ Exposed-Modules: Csound.Base
examples/Events.hs view
@@ -1,7 +1,7 @@ -- | Test for different types of events. module Main where -import Csound.Base+import Csound.Base hiding (echo) import Data.Monoid -- | Outputs the drummy sound.
src/Csound/Air.hs view
@@ -49,6 +49,10 @@ readSnd1, loopSnd1, loopSndBy1, readWav1, loopWav1, + -- * Writing sound files+ SampleFormat(..),+ writeSigs, writeWav, writeAiff, writeWav1, writeAiff1,+ -- ** Utility lengthSnd, segments, @@ -472,6 +476,54 @@ -- | The mono variant of the function @loopWav@. loopWav1 :: Sig -> String -> Sig loopWav1 speed fileName = flip withDs [0, 1] $ diskin2 (text fileName) speed++--------------------------------------------------------------------------+-- writing sound files++-- | The sample format.+data SampleFormat + = NoHeaderFloat32 -- ^ 32-bit floating point samples without header+ | NoHeaderInt16 -- ^ 16-bit integers without header+ | HeaderInt16 -- ^ 16-bit integers with a header. The header type depends on the render (-o) format+ | UlawSamples -- ^ u-law samples with a header+ | Int16 -- ^ 16-bit integers with a header+ | Int32 -- ^ 32-bit integers with a header + | Float32 -- ^ 32-bit floats with a header+ | Uint8 -- ^ 8-bit unsigned integers with a header+ | Int24 -- ^ 24-bit integers with a header+ | Float64 -- ^ 64-bit floats with a header+ deriving (Eq, Ord, Enum)++-- | Writes a sound signal to the file with the given format.+-- It supports only four formats: Wav, Aiff, Raw and Ircam.+writeSigs :: FormatType -> SampleFormat -> String -> [Sig] -> SE ()+writeSigs fmt sample file = fout (text file) formatToInt + where + formatToInt = int $ formatTypeToInt fmt * 10 + fromEnum sample++ formatTypeToInt :: FormatType -> Int+ formatTypeToInt x = case x of+ Wav -> 1+ Aiff -> 2+ Raw -> 3+ Ircam -> 4+ _ -> error $ "Format " ++ (show x) ++ " is not supported in the writeSnd."++-- | Writes wav files.+writeWav :: String -> (Sig, Sig) -> SE ()+writeWav file = writeSigs Wav Int16 file . \(a, b) -> [a, b]++-- | Writes aiff files.+writeAiff :: String -> (Sig, Sig) -> SE ()+writeAiff file = writeSigs Aiff Int16 file . \(a, b) -> [a, b]++-- | Writes mono signals to wav files.+writeWav1 :: String -> Sig -> SE ()+writeWav1 file = writeWav file . \x -> (x, x)++-- | Writes mono signals to aiff files.+writeAiff1 :: String -> Sig -> SE ()+writeAiff1 file = writeAiff file . \x -> (x, x) -------------------------------------------------------------------------- -- spectral functions
src/Csound/Base.hs view
@@ -35,5 +35,5 @@ import Data.Default import Data.Monoid -import Csound.Typed.Opcode hiding (button, display, space, lfo)+import Csound.Typed.Opcode hiding (button, display, space, lfo, initc7, ctrl7, oscInit, oscListen, oscSend)
src/Csound/Control/Evt.hs view
@@ -12,8 +12,9 @@ metroE, impulseE, changedE, triggerE, loadbang, impulse, -- * Higher-level event functions- eventList,+ devt, eventList, cycleE, iterateE, repeatE, appendE, mappendE, partitionE, splitToggle,+ Rnds, oneOf, freqOf, freqAccum, randDs, randInts, randSkip, randSkipBy, range, listAt, @@ -27,6 +28,11 @@ import Csound.Typed import Csound.Typed.Opcode++-- | Constant event stream. It produces the same value (the first argument)+-- all the time.+devt :: D -> Evt a -> Evt D+devt d = fmap (const d) -- | Behaves like 'Csound.Opcode.Basic.metro', but returns an event stream. metroE :: Sig -> Evt Unit
src/Csound/Control/Gui.hs view
@@ -51,6 +51,7 @@ Widget, Input, Output, Inner, Sink, Source, Display, widget, sink, source, display,+ mapSource, -- * Panels panel, panels, panelBy,@@ -62,9 +63,15 @@ module Csound.Control.Gui.Widget ) where +import Control.Arrow(second)+ import Csound.Typed.Gui import Csound.Control.Gui.Layout import Csound.Control.Gui.Props import Csound.Control.Gui.Widget ++-- | Maps over the value of the source-widget.+mapSource :: (a -> b) -> Source a -> Source b+mapSource f = fmap (second f)
src/Csound/Control/Gui/Widget.hs view
@@ -20,7 +20,7 @@ toggle, butBank, toggleSig, butBankSig, butBank1, butBankSig1, radioButton, matrixButton, funnyRadio, funnyMatrix,- value, meter,+ setNumeric, meter, -- * Transformers setTitle, -- * Keyboard@@ -96,5 +96,4 @@ -- | Shortcut for release 'CharKey' events. charOff :: Char -> Evt Unit charOff = keyIn . Release . CharKey-
src/Csound/Control/Instr.hs view
@@ -79,8 +79,13 @@ -- * Midi Msg, Channel, midi, midin, pgmidi, ampCps, midi_, midin_, pgmidi_,+ -- ** Mono-midi synth+ monoMsg, holdMsg, monoMsgn, holdMsgn, pgmonoMsg, pgholdMsg, -- ** Reading midi note parameters- cpsmidi, ampmidi,+ cpsmidi, ampmidi, initc7, ctrl7, midiCtrl7, midiCtrl, umidiCtrl,+ + -- * OSC+ initOsc, listenOsc, sendOsc, -- * Evt @@ -101,8 +106,10 @@ Outs(..), onArg, MidiInstr(..), AmpInstr(..), CpsInstr(..) ) where +import Data.Boolean+ import Csound.Typed-import Csound.Typed.Opcode+import Csound.Typed.Opcode hiding (initc7, oscInit, oscListen, oscSend) import Csound.Control.Overload import Csound.Control.Evt(metroE, repeatE, splitToggle)@@ -228,5 +235,129 @@ -- | A closure to trigger an instrument inside the body of another instrument. schedHarpBy :: (Arg a, Sigs b, Arg c) => D -> (a -> SE b) -> (c -> Evt a) -> c -> b schedHarpBy dt f = fromPluralBy $ schedHarpsBy dt f++-----------------------------------------------------------------------+-- Midi addons++-- mono midi++-- | Produces midi amplitude and frequency as a signal.+-- The signal fades out when nothing is pressed.+-- It can be used in mono-synths. Arguments are portamento time+-- and release time. A portamento time is time it takes for transition+-- from one note to another.+--+-- > monoMsg portamentoTime releaseTime+monoMsg :: D -> D -> SE (Sig, Sig)+monoMsg portTime relTime = do+ (amp, cps, status) <- genAmpCpsSig midi+ return (port amp portTime * port status relTime, port cps portTime)++-- | Produces midi amplitude and frequency as a signal and holds the +-- last value till the next one is present.+-- It can be used in mono-synths. Arguments are portamento time+-- and release time. A portamento time is time it takes for transition+-- from one note to another.+--+-- > holdMsg portamentoTime+holdMsg :: D -> SE (Sig, Sig)+holdMsg portTime = do+ (amp, cps) <- genHoldAmpCpsSig midi_+ return (port amp portTime, port cps portTime)+++-- | Produces midi amplitude and frequency as a signal.+-- The signal fades out when nothing is pressed. We can specify a channel.+-- It can be used in mono-synths. Arguments are portamento time+-- and release time. A portamento time is time it takes for transition+-- from one note to another.+--+-- > monoMsgn chnNumber portamentoTime releaseTime+monoMsgn :: Channel -> D -> D -> SE (Sig, Sig)+monoMsgn n portTime relTime = do+ (amp, cps, status) <- genAmpCpsSig (midin n)+ return (port amp portTime * port status relTime, port cps portTime)++-- | Produces midi amplitude and frequency as a signal and holds the +-- last value till the next one is present. We can specify a channel.+-- It can be used in mono-synths. Arguments are portamento time+-- and release time. A portamento time is time it takes for transition+-- from one note to another.+--+-- > holdMsgn chnNumber portamentoTime+holdMsgn :: Channel -> D -> SE (Sig, Sig)+holdMsgn n portTime = do+ (amp, cps) <- genHoldAmpCpsSig (midin_ n)+ return (port amp portTime, port cps portTime)+++-- | Produces midi amplitude and frequency as a signal.+-- The signal fades out when nothing is pressed. We can specify a programm number and channel.+-- It can be used in mono-synths. Arguments are portamento time+-- and release time. A portamento time is time it takes for transition+-- from one note to another.+--+-- > pgmonoMsg chnNumber portamentoTime releaseTime+pgmonoMsg :: Maybe Int -> Channel -> D -> D -> SE (Sig, Sig)+pgmonoMsg pg n portTime relTime = do+ (amp, cps, status) <- genAmpCpsSig (pgmidi pg n)+ return (port amp portTime * port status relTime, port cps portTime)++-- | Produces midi amplitude and frequency as a signal and holds the +-- last value till the next one is present. We can specify a programm number and channel.+-- It can be used in mono-synths. Arguments are portamento time+-- and release time. A portamento time is time it takes for transition+-- from one note to another.+--+-- > pgholdMsg portamentoTime+pgholdMsg :: Maybe Int -> Channel -> D -> SE (Sig, Sig)+pgholdMsg pg n portTime = do+ (amp, cps) <- genHoldAmpCpsSig (pgmidi_ pg n)+ return (port amp portTime, port cps portTime)+++genAmpCpsSig :: ((Msg -> SE Sig) -> Sig) -> SE (Sig, Sig, Sig)+genAmpCpsSig midiFun = do+ ref <- newGlobalSERef ((0, 0) :: (Sig, Sig))+ let status = midiFun (instr ref)+ let resStatus = ifB (downsamp status ==* 0) 0 1+ (amp, cps) <- readSERef ref+ return (downsamp amp, downsamp cps, resStatus)+ where + instr :: SERef (Sig, Sig) -> Msg -> SE Sig+ instr hNote msg = do+ writeSERef hNote (sig $ ampmidi msg 1, sig $ cpsmidi msg)+ return 1 ++genHoldAmpCpsSig :: ((Msg -> SE ()) -> SE ()) -> SE (Sig, Sig)+genHoldAmpCpsSig midiFun = do+ ref <- newGlobalSERef ((0, 0) :: (Sig, Sig))+ midiFun (instr ref) + (amp, cps) <- readSERef ref+ return (downsamp amp, downsamp cps)+ where + instr :: SERef (Sig, Sig) -> Msg -> SE ()+ instr hNote msg = do+ writeSERef hNote (sig $ ampmidi msg 1, sig $ cpsmidi msg) ++--------------------------------------------------------------++-- | Initialization of the midi control-messages.+initc7 :: D -> D -> D -> SE ()+initc7 = initMidiCtrl ++-- | Initializes midi control and get the value in the specified range.+midiCtrl7 :: D -> D -> D -> D -> D -> SE Sig+midiCtrl7 chno ctrlno ival imin imax = do+ initc7 chno ctrlno ival+ return $ ctrl7 chno ctrlno imin imax+ +-- | Initializes midi control and get the value in the range (-1) to 1.+midiCtrl :: D -> D -> D -> SE Sig+midiCtrl chno ctrlno ival = midiCtrl7 chno ctrlno ival (-1) 1+ +-- | Unipolar midiCtrl. Initializes midi control and get the value in the range 0 to 1.+umidiCtrl :: D -> D -> D -> SE Sig+umidiCtrl chno ctrlno ival = midiCtrl7 chno ctrlno ival (-1) 1
src/Csound/Control/SE.hs view
@@ -1,5 +1,5 @@ module Csound.Control.SE(- SE, SERef(..), newSERef, sensorsSE + SE, SERef(..), newSERef, sensorsSE, newGlobalSERef, globalSensorsSE ) where import Csound.Typed.Control
src/Csound/IO.hs view
@@ -41,9 +41,12 @@ import System.Process import Control.Exception +import Data.Monoid import Data.Default import Csound.Typed +import Csound.Options(setSilent)+ render :: Sigs a => Options -> SE a -> IO String render = renderOutBy @@ -189,13 +192,14 @@ -- | Renders to file @tmp.csd@ and invokes the csound on it. csd :: (RenderCsd a) => a -> IO ()-csd = csdBy def+csd = csdBy setSilent -- | Renders to file @tmp.csd@ and invokes the csound on it. csdBy :: (RenderCsd a) => Options -> a -> IO () csdBy options a = do- writeCsdBy options "tmp.csd" a+ writeCsdBy (setSilent <> options) "tmp.csd" a runWithUserInterrupt $ "csound tmp.csd" + ---------------------------------------------------------- -- players
src/Csound/Options.hs view
@@ -6,6 +6,7 @@ setRates, setBufs, setGain, setJack, setOutput, setInput, setDac, setAdc, setDacBy, setAdcBy, setThru,+ setSilent, -- * Flags -- | Csound's command line flags. See original documentation for @@ -85,4 +86,8 @@ setThru :: Options setThru = mappend setDac setAdc++-- | Sets the output to nosound.+setSilent :: Options+setSilent = (def { csdFlags = def { audioFileOutput = def { nosound = True } } })
src/Csound/Types.hs view
@@ -41,7 +41,7 @@ quot', rem', div', mod', ceil', floor', round', int', frac', -- ** Logic functions- boolSig, when1, whens, + boolSig, when1, whens, whileDo, untilDo, -- ** Aliases -- | Handy for functions that return tuples to specify the utput type