Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Channel voice messages
- data T
- get :: C parser => Int -> Int -> Fragile parser T
- putWithStatus :: C writer => (Int -> T compress writer) -> T -> T compress writer
- type ControllerValue = Value
- type PitchBendRange = Int
- type Pressure = Int
- isNote :: T -> Bool
- isNoteOn :: T -> Bool
- isNoteOff :: T -> Bool
- zeroKey :: Pitch
- explicitNoteOff :: T -> T
- implicitNoteOff :: T -> T
- realFromControllerValue :: (Integral a, Fractional b) => a -> b
- bankSelect :: T
- modulation :: T
- breathControl :: T
- footControl :: T
- portamentoTime :: T
- dataEntry :: T
- mainVolume :: T
- balance :: T
- panorama :: T
- expression :: T
- generalPurpose1 :: T
- generalPurpose2 :: T
- generalPurpose3 :: T
- generalPurpose4 :: T
- vectorX :: T
- vectorY :: T
- bankSelectMSB :: T
- modulationMSB :: T
- breathControlMSB :: T
- footControlMSB :: T
- portamentoTimeMSB :: T
- dataEntryMSB :: T
- mainVolumeMSB :: T
- balanceMSB :: T
- panoramaMSB :: T
- expressionMSB :: T
- generalPurpose1MSB :: T
- generalPurpose2MSB :: T
- generalPurpose3MSB :: T
- generalPurpose4MSB :: T
- bankSelectLSB :: T
- modulationLSB :: T
- breathControlLSB :: T
- footControlLSB :: T
- portamentoTimeLSB :: T
- dataEntryLSB :: T
- mainVolumeLSB :: T
- balanceLSB :: T
- panoramaLSB :: T
- expressionLSB :: T
- generalPurpose1LSB :: T
- generalPurpose2LSB :: T
- generalPurpose3LSB :: T
- generalPurpose4LSB :: T
- sustain :: T
- porta :: T
- sustenuto :: T
- softPedal :: T
- hold2 :: T
- generalPurpose5 :: T
- generalPurpose6 :: T
- generalPurpose7 :: T
- generalPurpose8 :: T
- extDepth :: T
- tremoloDepth :: T
- chorusDepth :: T
- celesteDepth :: T
- phaserDepth :: T
- dataIncrement :: T
- dataDecrement :: T
- nonRegisteredParameterLSB :: T
- nonRegisteredParameterMSB :: T
- registeredParameterLSB :: T
- registeredParameterMSB :: T
- data Pitch
- fromPitch :: Pitch -> Int
- toPitch :: Int -> Pitch
- data Velocity
- fromVelocity :: Velocity -> Int
- toVelocity :: Int -> Velocity
- data Program
- fromProgram :: Program -> Int
- toProgram :: Int -> Program
- data Controller
- fromController :: Controller -> Int
- toController :: Int -> Controller
- increasePitch :: Int -> Pitch -> Pitch
- subtractPitch :: Pitch -> Pitch -> Int
- frequencyFromPitch :: Floating a => Pitch -> a
- maximumVelocity :: Velocity
- normalVelocity :: Velocity
- realFromVelocity :: Fractional b => Velocity -> b
Documentation
putWithStatus :: C writer => (Int -> T compress writer) -> T -> T compress writer Source
type ControllerValue = Value Source
type PitchBendRange = Int Source
NoteOn with zero velocity is considered NoteOff according to MIDI specification.
NoteOn with zero velocity is considered NoteOff according to MIDI specification.
A MIDI problem is that one cannot uniquely map a MIDI key to a frequency. The frequency depends on the instrument. I don't know if the deviations are defined for General MIDI. If this applies one could add transposition information to the use patch map. For now I have chosen a value that leads to the right frequency for some piano sound in my setup.
explicitNoteOff :: T -> T Source
Convert all NoteOn p 0
to NoteOff p 64
.
The latter one is easier to process.
implicitNoteOff :: T -> T Source
Convert all NoteOff p 64
to NoteOn p 0
.
The latter one can be encoded more efficiently using the running status.
realFromControllerValue :: (Integral a, Fractional b) => a -> b Source
Map integral MIDI controller value to floating point value. Maximum integral MIDI controller value 127 is mapped to 1. Minimum integral MIDI controller value 0 is mapped to 0.
bankSelect :: T Source
modulation :: T Source
breathControl :: T Source
footControl :: T Source
mainVolume :: T Source
expression :: T Source
bankSelectMSB :: T Source
modulationMSB :: T Source
dataEntryMSB :: T Source
mainVolumeMSB :: T Source
balanceMSB :: T Source
panoramaMSB :: T Source
expressionMSB :: T Source
bankSelectLSB :: T Source
modulationLSB :: T Source
dataEntryLSB :: T Source
mainVolumeLSB :: T Source
balanceLSB :: T Source
panoramaLSB :: T Source
expressionLSB :: T Source
tremoloDepth :: T Source
chorusDepth :: T Source
celesteDepth :: T Source
phaserDepth :: T Source
dataIncrement :: T Source
dataDecrement :: T Source
Bounded Velocity Source | ToDo: We have defined minBound = Velocity 0, but strictly spoken the minimum Velocity is 1, since Velocity zero means NoteOff. One can at least think of NoteOff with (Velocity 0), but I have never seen that. |
Eq Velocity Source | |
Ord Velocity Source | |
Show Velocity Source | |
Arbitrary Velocity Source | |
Random Velocity Source |
fromVelocity :: Velocity -> Int Source
toVelocity :: Int -> Velocity Source
fromProgram :: Program -> Int Source
data Controller Source
We do not define Controller
as enumeration with many constructors,
because some controllers have multiple names and some are undefined.
It is also more efficient this way.
Thus you cannot use case
for processing controller types,
but you can use lookup
instead.
maybe (putStrLn "unsupported controller") putStrLn $ lookup ctrl $ (portamento, "portamento") : (modulation, "modulation") : []
fromController :: Controller -> Int Source
toController :: Int -> Controller Source
increasePitch :: Int -> Pitch -> Pitch Source
subtractPitch :: Pitch -> Pitch -> Int Source
frequencyFromPitch :: Floating a => Pitch -> a Source
Convert pitch to frequency according to the default tuning given in MIDI 1.0 Detailed Specification.
maximumVelocity :: Velocity Source
The velocity of an ordinary key stroke and the maximum possible velocity.
normalVelocity :: Velocity Source
The velocity of an ordinary key stroke and the maximum possible velocity.
realFromVelocity :: Fractional b => Velocity -> b Source
MIDI specification says,
if velocity is simply mapped to amplitude,
then this should be done by an exponential function.
Thus we map normalVelocity
(64) to 0,
maximumVelocity
(127) to 1,
and minimumVelocity
(1) to -1.
That is, normally you should write something like
amplitude = 2 ** realFromVelocity vel
or 3 ** realFromVelocity vel
.