streamed-0.2: Programmatically edit MIDI event streams via ALSA

Safe HaskellSafe-Infered





outputEventBundles :: T Time EventDataBundle -> ReaderT Handle IO ()Source

Sends (drain) each event individually since the events in the bundle might be created in a lazy manner.

outputTriggerEvents :: T Time EventDataTrigger -> ReaderT Handle IO ()Source

This function distinguishes between events from portIn and events that are generated by us. Our generated events must also send an echo to the input port in order to break event_input and thus trigger their delivery.

mergeGeneratedAtoms :: (Time -> a) -> T Time a -> T Time a -> T Time aSource

patternPolyTempo :: PatternPoly i -> ((Channel, Controller), (Time, Time, Time)) -> T Time Data -> T Time EventDataTriggerSource

This allows more complex patterns including pauses, notes of different lengths and simultaneous notes.

sweep :: Channel -> Time -> (Controller, (Time, Time)) -> Controller -> Controller -> (Double -> Double) -> T Time Data -> T Time EventDataTriggerSource

Automatically changes the value of a MIDI controller every period seconds according to a periodic wave. The wave function is a mapping from the phase in [0,1) to a controller value in the range (-1,1). The generation of the wave is controlled by a speed controller (minSpeed and maxSpeed are in waves per second), the modulation depth and the center value. The center controller is also the one where we emit our wave. That is, when modulation depth is zero then this effect is almost the same as forwarding the controller without modification. The small difference is, that we emit a controller value at a regular patternMono, whereas direct control would mean that only controller value changes are transfered.

 sweep channel
    period (speedCtrl, (minSpeed, maxSpeed)) depthCtrl centerCtrl
    (ctrlRange (-1,1) (sin . (2*pi*)))

We could use the nice Wave abstraction from the synthesizer package, but that's a heavy dependency because of multi-parameter type classes.


filter :: (a -> Bool) -> State (T Time (Bundle a)) (T Time (Bundle a))Source

The function maintains empty bundles in order to maintain laziness breaks. These breaks are import for later merging of the streams.

filterSimple :: (a -> Bool) -> T Time (Bundle a) -> T Time (Bundle a)Source

merge :: T Time (Bundle a) -> T Time (Bundle a) -> T Time (Bundle a)Source

run filters

runCyclePrograms :: [Program] -> ReaderT Handle IO ()Source

 runCyclePrograms (map VoiceMsg.toProgram [8..12])

runProgramsAsBanks :: [Int32] -> ReaderT Handle IO ()Source

 runProgramsAsBanks [8,4,4]

runPattern :: Time -> PatternMono i -> ReaderT Handle IO ()Source

 runPattern 0.12 (cycleUp 4)

runPatternTempo :: Pattern pat => Time -> pat -> ReaderT Handle IO ()Source

 runPatternTempo 0.12 (cycleUp 4)
 runPatternTempo 0.2 (PatternMono selectFromOctaveChord (cycle [0,1,2,0,1,2,0,1]))
 runPatternTempo 0.1 (PatternPoly selectFromLimittedChord (let pat = [item 0 1] ./ 1 /. [item 1 1] ./ 2 /. [item 1 1] ./ 1 /. [item 0 1] ./ 2 /. pat in 0 /. pat))