{- | System Exclusive messages -} module Sound.MIDI.Message.System.Exclusive ( T(..), get, getIncomplete, put, ) where import qualified Sound.MIDI.Manufacturer as Manufacturer import Sound.MIDI.IO (ByteList) import Sound.MIDI.Parser.Primitive import qualified Sound.MIDI.Parser.Class as Parser import qualified Sound.MIDI.Writer.Basic as Writer import Sound.MIDI.Monoid ((+#+)) import qualified Control.Monad.Trans.Class as MT import qualified Control.Monad.Exception.Asynchronous as Async import Data.Maybe (fromMaybe, ) data T = Commercial Manufacturer.T ByteList | NonCommercial ByteList | NonRealTime NonRealTime | RealTime RealTime -- * Non-real time {-# DEPRECATED NonRealTime "structure must be defined, yet" #-} newtype NonRealTime = NonRealTimeCons ByteList -- * Real time {-# DEPRECATED RealTime "structure must be defined, yet" #-} newtype RealTime = RealTimeCons ByteList -- * serialization get :: Parser.C parser => Parser.Fragile parser T get = do (Async.Exceptional err sysex) <- getIncomplete maybe (return sysex) Parser.giveUp err getIncomplete :: Parser.C parser => Parser.Partial (Parser.Fragile parser) T getIncomplete = do manu <- Manufacturer.get incBody <- MT.lift getBody return $ flip fmap incBody $ \body -> fromMaybe (Commercial manu body) $ lookup manu $ (Manufacturer.nonCommercial, NonCommercial body) : (Manufacturer.nonRealTime, NonRealTime $ NonRealTimeCons body) : (Manufacturer.realTime, RealTime $ RealTimeCons body) : [] getBody :: Parser.C parser => Parser.Partial parser ByteList getBody = Parser.until (0xf7 ==) getByte {- | It is not checked whether SysEx messages contain only 7-bit values. -} put :: Writer.C writer => T -> writer put sysex = case sysex of Commercial manu body -> Manufacturer.put manu +#+ Writer.putByteList body NonCommercial body -> Manufacturer.put Manufacturer.nonCommercial +#+ Writer.putByteList body NonRealTime (NonRealTimeCons body) -> Manufacturer.put Manufacturer.nonRealTime +#+ Writer.putByteList body RealTime (RealTimeCons body) -> Manufacturer.put Manufacturer.realTime +#+ Writer.putByteList body