hamid 0.9 → 0.10
raw patch · 10 files changed
+88/−88 lines, 10 files
Files
- hamid.cabal +1/−1
- src/System/MacOSX/CoreAudio.hs +1/−1
- src/System/MacOSX/CoreFoundation.hs +1/−1
- src/System/MacOSX/CoreMidi.hs +11/−11
- src/System/Midi.hs +24/−24
- src/System/Midi/Base.hs +9/−9
- src/System/Midi/MacOSX.hs +16/−16
- src/System/Midi/Placeholder.hs +5/−5
- src/System/Midi/Win32.hs +18/−18
- src/System/Win32/Midi.hs +2/−2
hamid.cabal view
@@ -1,6 +1,6 @@ name: hamid-version: 0.9+version: 0.10 cabal-version: >= 1.6 synopsis: Binding to the OS level Midi services (fork of system-midi).
src/System/MacOSX/CoreAudio.hs view
@@ -1,5 +1,5 @@ --- |Partial binding to CoreAudio, as required for `System.MIDI`. +-- |Partial binding to CoreAudio, as required for `System.Midi`. -- At the moment only HostTime is supported. -- In the future this module should grow into a separate entity.
src/System/MacOSX/CoreFoundation.hs view
@@ -1,5 +1,5 @@ --- |Partial binding to CoreFoundation, as required for `System.MIDI`. +-- |Partial binding to CoreFoundation, as required for `System.Midi`. -- At the moment only CFString is supported. -- In the future this module should grow into a separate entity.
src/System/MacOSX/CoreMidi.hs view
@@ -1,15 +1,15 @@ --- |Low-level binding to the CoreMIDI services present in Mac OS X.+-- |Low-level binding to the CoreMidi services present in Mac OS X. -- Error handling is via `fail`-s in the IO monad. {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-} {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}-module System.MacOSX.CoreMIDI +module System.MacOSX.CoreMidi ( enumerateDevices , enumerateSources , enumerateDestinations- , MIDIHasName(..)+ , MidiHasName(..) -- , getName -- , getModel -- , getManufacturer@@ -64,7 +64,7 @@ import Foreign.Marshal import System.IO.Unsafe -import System.MIDI.Base+import System.Midi.Base import System.MacOSX.CoreFoundation data OpaqueMIDIClient@@ -252,7 +252,7 @@ instance MIDIObject Destination where midiObject (Destination dst) = castPtr dst -- |MIDI objects which can have a name, model name and manufacturer-class MIDIObject a => MIDIHasName a where+class MIDIObject a => MidiHasName a where getName :: a -> IO String getModel :: a -> IO String getManufacturer :: a -> IO String@@ -261,12 +261,12 @@ getModel = genericGetModel . midiObject getManufacturer = genericGetManufacturer . midiObject -instance MIDIHasName MIDIDeviceRef-instance MIDIHasName MIDIEntityRef-instance MIDIHasName MIDIPortRef-instance MIDIHasName MIDIEndpointRef-instance MIDIHasName Source-instance MIDIHasName Destination+instance MidiHasName MIDIDeviceRef+instance MidiHasName MIDIEntityRef+instance MidiHasName MIDIPortRef+instance MidiHasName MIDIEndpointRef+instance MidiHasName Source+instance MidiHasName Destination genericGetName obj = midiObjectGetStringProperty obj kMIDIPropertyName genericGetModel obj = midiObjectGetStringProperty obj kMIDIPropertyModel
src/System/Midi.hs view
@@ -3,7 +3,7 @@ ----- Module : System.MIDI+-- Module : System.Midi -- Version : 0.1 -- License : BSD3 -- Author : Balazs Komuves@@ -13,10 +13,10 @@ -- Tested with : GHC 6.8.2 -- --- | A lowest common denominator interface to the Win32 and MacOSX MIDI bindings. +-- | A lowest common denominator interface to the Win32 and MacOSX Midi bindings. -- Error handling is via `fail`-s in the IO monad. -module System.MIDI (+module System.Midi ( -- * Messages MidiTime, MidiMessage,@@ -52,24 +52,24 @@ ) where import Data.Word (Word8,Word32)-import System.MIDI.Base hiding (MidiEvent, MidiMessage)+import System.Midi.Base hiding (MidiEvent, MidiMessage) import System.IO.Unsafe (unsafePerformIO) import qualified Codec.Midi as C #ifdef mingw32_HOST_OS-import qualified System.MIDI.Win32 as S-#define HMIDI_SUPPORTED_OS+import qualified System.Midi.Win32 as S+#define HMidi_SUPPORTED_OS #endif #ifdef darwin_HOST_OS-import qualified System.MIDI.MacOSX as S-#define HMIDI_SUPPORTED_OS+import qualified System.Midi.MacOSX as S+#define HMidi_SUPPORTED_OS #endif -- this is just to be able to produce a Haddock documentation on a not supported system (eg. Linux)-#ifndef HMIDI_SUPPORTED_OS-import qualified System.MIDI.Placeholder as S+#ifndef HMidi_SUPPORTED_OS+import qualified System.Midi.Placeholder as S #endif type MidiTime = Word32@@ -91,11 +91,11 @@ -- for a platform-specific module while being on an a different platform (probably not at all possible -- at present?) --- | The opaque data type representing a MIDI source.+-- | The opaque data type representing a Midi source. newtype Source = Source { getSource :: S.Source } deriving (Eq) --- | The opaque data type representing a MIDI destination.+-- | The opaque data type representing a Midi destination. newtype Destination = Destination { getDestination :: S.Destination } deriving (Eq) @@ -105,30 +105,30 @@ instance Show Destination where show = (\n -> "<Destination: "++n++">") . unsafePerformIO . name --- | The opaque data type representing a MIDI connection.+-- | The opaque data type representing a Midi connection. newtype Stream = Stream { getStream :: S.Connection } --- | Enumerates the MIDI sources present in the system.+-- | Enumerates the Midi sources present in the system. sources :: IO [Source] sources = fmap (fmap Source) S.enumerateSources --- | Enumerates the MIDI destinations present in the system.+-- | Enumerates the Midi destinations present in the system. destinations :: IO [Destination] destinations = fmap (fmap Destination) S.enumerateDestinations --- | These functions return the name, model and manufacturer of a MIDI source \/ destination.+-- | These functions return the name, model and manufacturer of a Midi source \/ destination. -- -- Note: On Win32, only `getName` returns a somewhat meaningful string at the moment.-getName :: S.MIDIHasName a => a -> IO String-getModel :: S.MIDIHasName a => a -> IO String-getManufacturer :: S.MIDIHasName a => a -> IO String+getName :: S.MidiHasName a => a -> IO String+getModel :: S.MidiHasName a => a -> IO String+getManufacturer :: S.MidiHasName a => a -> IO String getName = S.getName getModel = S.getModel getManufacturer = S.getManufacturer --- | Opens a MIDI Source.--- There are two possibilites to receive MIDI messages. The user can either support a callback function,+-- | Opens a Midi Source.+-- There are two possibilites to receive Midi messages. The user can either support a callback function, -- or get the messages from an asynchronous buffer. However, mixing the two approaches is not allowed. openSource :: Source -> Maybe (MidiTime -> C.Message -> IO ()) -> IO Stream @@ -137,7 +137,7 @@ mkCb f (S.MidiEvent ts msg) = f ts (expMsg msg) --- | Opens a MIDI Destination.+-- | Opens a Midi Destination. openDestination :: Destination -> IO Stream openDestination = fmap Stream . S.openDestination . getDestination @@ -166,7 +166,7 @@ sendSysEx = S.sendSysEx -} --- | Starts a connection. This is required for receiving MIDI messages, and also for starting the clock.+-- | Starts a connection. This is required for receiving Midi messages, and also for starting the clock. start :: Stream -> IO () start = S.start . getStream @@ -174,7 +174,7 @@ stop :: Stream -> IO () stop = S.stop . getStream --- | Closes a MIDI Stream.+-- | Closes a Midi Stream. close :: Stream -> IO () close = S.close . getStream
src/System/Midi/Base.hs view
@@ -1,8 +1,8 @@ --- |The hardware-independent part of the MIDI binding.+-- |The hardware-independent part of the Midi binding. {-# LANGUAGE CPP #-}-module System.MIDI.Base +module System.Midi.Base ( TimeStamp , MidiMessage'(..) , MidiMessage(..)@@ -19,10 +19,10 @@ type TimeStamp = Word32 --- |A \"regular\" MIDI message.+-- |A \"regular\" Midi message. -- -- Remark: `NoteOff` not having a velocity field is a design decision, and a questionable one. According to the--- MIDI standard, NoteOff also has a velocity. However, most keyboards do not use this feature (send the default+-- Midi standard, NoteOff also has a velocity. However, most keyboards do not use this feature (send the default -- value 64), and there are keyboards which do not send NoteOff messages at all, but send NoteOn messages with -- zero velocity instead (for example the EMU Xboard series). I don't know what would be a good solution. -- At the moment, the code auto-translates NoteOn messages with zero velocity to NoteOff messages, and the@@ -37,9 +37,9 @@ | PitchWheel !Int -- ^ Pitch wheel (value, from -8192..+8191) deriving (Show,Eq) --- |The type representing a MIDI message. +-- |The type representing a Midi message. data MidiMessage - = MidiMessage !Int !MidiMessage' -- ^ first argument is the MIDI channel (1..16)+ = MidiMessage !Int !MidiMessage' -- ^ first argument is the Midi channel (1..16) | SysEx [Word8] -- ^ not including the bytes 0xf0, 0xf7 | SongPosition !Int | SongSelect !Int @@ -53,8 +53,8 @@ | Undefined deriving (Show,Eq) --- |The type representing a timestamped MIDI message. --- Time is measured in milisecs elapsed since the last call to `System.MIDI.start`.+-- |The type representing a timestamped Midi message. +-- Time is measured in milisecs elapsed since the last call to `System.Midi.start`. data MidiEvent = MidiEvent !TimeStamp !MidiMessage deriving (Show,Eq) -- |Type of the user callback function. @@ -70,7 +70,7 @@ v = fromIntegral bt2 translate' msg k v = case msg of-#ifdef HMIDI_NO_NOTEOFF+#ifdef HMidi_NO_NOTEOFF 8 -> NoteOn k 0 9 -> NoteOn k v #else
src/System/Midi/MacOSX.hs view
@@ -1,8 +1,8 @@ --- |A lowest common denominator interface to the Win32 and MacOSX MIDI bindings, MacOSX part.+-- |A lowest common denominator interface to the Win32 and MacOSX Midi bindings, MacOSX part. -module System.MIDI.MacOSX- ( module System.MIDI.Base+module System.Midi.MacOSX+ ( module System.Midi.Base , Source , Destination@@ -11,7 +11,7 @@ , enumerateSources , enumerateDestinations - , MIDIHasName(..) + , MidiHasName(..) , openSource , openDestination@@ -27,7 +27,7 @@ ) where -import System.MIDI.Base+import System.Midi.Base import Control.Monad import Control.Concurrent.MVar@@ -39,7 +39,7 @@ import System.MacOSX.CoreFoundation import System.MacOSX.CoreAudio-import System.MacOSX.CoreMIDI+import System.MacOSX.CoreMidi -- |Gets all the events from the buffer. getEvents :: Connection -> IO [MidiEvent]@@ -67,7 +67,7 @@ type Device = MIDIDeviceRef type Port = MIDIPortRef --- |The opaque data type representing a MIDI connection+-- |The opaque data type representing a Midi connection data Connection = Connection { cn_isInput :: Bool , cn_port :: MIDIPortRef@@ -97,7 +97,7 @@ b <- isEmptyMVar client if b then do- x <- newClient "HaskellMidi" + x <- newClient "HaskellMIDI" putMVar client x {- #ifdef __GLASGOW_HASKELL__@@ -122,8 +122,8 @@ ts <- audioConvertHostTimeToNanos ts' return $ MidiEvent (nanoToMili $ ts-t0) (translateShortMessage $ decodeShortMessage bytes) -myMIDIReadProc :: Ptr MIDIPacket -> Ptr () -> Ptr () -> IO ()-myMIDIReadProc packets myptr _ = do+myMidiReadProc :: Ptr MIDIPacket -> Ptr () -> Ptr () -> IO ()+myMidiReadProc packets myptr _ = do let stabptr = castPtrToStablePtr myptr :: StablePtr (MVar Connection) mv <- deRefStablePtr stabptr :: IO (MVar Connection) mconn <- tryTakeMVar mv -- we are also "blocking" (handling) further callbacks this way@@ -143,8 +143,8 @@ Right call -> mapM_ call events putMVar mv conn -- do not forget to put it back! --- |Opens a MIDI Source.--- There are two possibilites to receive MIDI messages. The user can either support a callback function,+-- |Opens a Midi Source.+-- There are two possibilites to receive Midi messages. The user can either support a callback function, -- or get the messages from an asynchronous buffer. However, mixing the two approaches is not allowed. openSource :: Source -> Maybe ClientCallback -> IO Connection openSource src@(Source endpoint) mcallback = do@@ -153,7 +153,7 @@ myData <- newEmptyMVar :: IO (MVar Connection) sp <- newStablePtr myData - the_callback <- mkMIDIReadProc myMIDIReadProc+ the_callback <- mkMIDIReadProc myMidiReadProc time <- newEmptyMVar alive <- newMVar True@@ -168,7 +168,7 @@ putMVar myData conn return conn --- |Opens a MIDI Destination.+-- |Opens a Midi Destination. openDestination :: Destination -> IO Connection openDestination dst@(Destination endpoint) = do @@ -193,7 +193,7 @@ sendSysEx :: Connection -> [Word8] -> IO () sendSysEx conn dat = midiSendSysEx (cn_endpoint conn) dat --- |Starts a connection. This is required for receiving MIDI messages, and also for starting the clock.+-- |Starts a connection. This is required for receiving Midi messages, and also for starting the clock. start :: Connection -> IO () start conn = do b <- isEmptyMVar (cn_time conn)@@ -218,7 +218,7 @@ False -> return () else putStrLn "warning: you shouldn't call stop twice" --- |Closes a MIDI Connection+-- |Closes a Midi Connection close conn = do when (cn_isInput conn) $ do b <- isEmptyMVar (cn_time conn)
src/System/Midi/Placeholder.hs view
@@ -1,8 +1,8 @@ -- | This is just to be able to produce a Haddock documentation on a Linux system -module System.MIDI.Placeholder- ( module System.MIDI.Base+module System.Midi.Placeholder+ ( module System.Midi.Base , Source , Destination@@ -11,7 +11,7 @@ , enumerateSources , enumerateDestinations - , MIDIHasName+ , MidiHasName , getName , getModel , getManufacturer@@ -30,7 +30,7 @@ ) where -import System.MIDI.Base+import System.Midi.Base data Source = Source deriving (Eq, Ord, Show) data Destination = Destination deriving (Eq, Ord, Show)@@ -39,7 +39,7 @@ enumerateSources = noImpl enumerateDestinations = noImpl -class MIDIHasName a where+class MidiHasName a where getName = noImpl getManufacturer = noImpl getModel = noImpl
src/System/Midi/Win32.hs view
@@ -1,8 +1,8 @@ --- |A lowest common denominator interface to the Win32 and MacOSX MIDI bindings, Win32 part. +-- |A lowest common denominator interface to the Win32 and MacOSX Midi bindings, Win32 part. -module System.MIDI.Win32 - ( module System.MIDI.Base+module System.Midi.Win32 + ( module System.Midi.Base , Source , Destination@@ -11,7 +11,7 @@ , enumerateSources , enumerateDestinations - , MIDIHasName+ , MidiHasName , getName , getModel , getManufacturer@@ -38,9 +38,9 @@ import System.IO.Unsafe import System.Win32.Types-import System.Win32.MIDI +import System.Win32.Midi -import System.MIDI.Base+import System.Midi.Base -- |Gets all the events from the buffer. getEvents :: Connection -> IO [MidiEvent]@@ -69,15 +69,15 @@ b <- check unless b $ waitFor check --- |The opaque data type representing a MIDI connection.+-- |The opaque data type representing a Midi connection. data Connection = Connection { cn_isInput :: Bool- , cn_handle :: HMIDI+ , cn_handle :: HMidi , cn_time :: MVar Word32 -- measured in milisecs , cn_fifo_cb :: Either (Chan MidiEvent) ClientCallback- , cn_midiproc :: FunPtr (MIDIINPROC ())+ , cn_midiproc :: FunPtr (MidiINPROC ()) , cn_mydata :: StablePtr (MVar Connection)- , cn_inbuf :: MVar (Ptr MIDIHDR)+ , cn_inbuf :: MVar (Ptr MidiHDR) , cn_sysex :: Chan Word8 -- channel for temporarily storing sysex messages (they can be arbritrary long, but the buffer has fixed size) , cn_alive :: MVar Bool } @@ -89,7 +89,7 @@ t0 <- readMVar (cn_time conn) return (t-t0) -myMidiCallback :: HMIDIIN -> UINT -> Ptr () -> DWORD -> DWORD -> IO ()+myMidiCallback :: HMidiIN -> UINT -> Ptr () -> DWORD -> DWORD -> IO () myMidiCallback hmidi msg' myptr param1 param2 = do let stabptr = castPtrToStablePtr myptr :: StablePtr (MVar Connection) mv <- deRefStablePtr stabptr :: IO (MVar Connection)@@ -108,7 +108,7 @@ Right call -> call event MIM_LONGDATA -> do- let ptr = wordPtrToPtr (fromIntegral param1) :: Ptr MIDIHDR+ let ptr = wordPtrToPtr (fromIntegral param1) :: Ptr MidiHDR q <- peek (castPtr ptr ) :: IO (Ptr Word8) n <- peek (castPtr ptr `plusPtr` 8) :: IO DWORD dat <- peekArray (fromIntegral n) q @@ -167,14 +167,14 @@ midiInBufferSize = 64 --- |Opens a MIDI source.--- There are two possibilites to receive MIDI messages. The user can either support a callback function,+-- |Opens a Midi source.+-- There are two possibilites to receive Midi messages. The user can either support a callback function, -- or get the messages from an asynchronous buffer. However, mixing the two approaches is not allowed. openSource :: Source -> Maybe ClientCallback -> IO Connection openSource src mcallback = do myData <- newEmptyMVar :: IO (MVar Connection) sp <- newStablePtr myData - the_callback <- mkMIDIPROC myMidiCallback+ the_callback <- mkMidiPROC myMidiCallback alive <- newMVar True fifo_cb <- case mcallback of Just cb -> return $ Right cb@@ -187,7 +187,7 @@ putMVar myData conn return conn --- |Opens a MIDI destination.+-- |Opens a Midi destination. openDestination :: Destination -> IO Connection openDestination dst = do alive <- newMVar True@@ -213,7 +213,7 @@ True -> fail "sending SysEx messages to midi sources is not supported under Win32" False -> midiOutSendSysEx handle msg --- |Starts a connection. This is required for receiving MIDI messages, and also for starting the clock.+-- |Starts a connection. This is required for receiving Midi messages, and also for starting the clock. start :: Connection -> IO () start conn = do let handle = cn_handle conn@@ -230,7 +230,7 @@ False -> return () else putStrLn "warning: you shouldn't call start twice" --- |Starts a connection. This is required for receiving MIDI messages, and also for starting the clock.+-- |Starts a connection. This is required for receiving Midi messages, and also for starting the clock. stop :: Connection -> IO () stop conn = do let handle = cn_handle conn
src/System/Win32/Midi.hs view
@@ -3,12 +3,12 @@ -- Error handling is via `fail`-s in the IO monad. {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}-module System.Win32.MIDI +module System.Win32.Midi ( Source(..) , Destination(..) , enumerateSources , enumerateDestinations- , MIDIHasName+ , MidiHasName , getName , getModel , getManufacturer