-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | ID3v2 tag editing-suite -- -- ID3v2 tag editing-suite @package idiii @version 0.0 -- | UNSYNCHRONISATION -- -- This module contents a couple of functions to convert readed bytes (as -- [Word8]) of synchronized values to unsynchronised -- Integer. -- -- UNSYNCRONISATION -- -- The only purpose of unsynchronisation is to make the ID3v2 tag as -- compatible as possible with existing software and hardware. There is -- no use in unsynchronising tags if the file is only to be -- processed only by ID3v2 aware software and hardware. Unsynchronisation -- is only useful with tags in MPEG 1/2 layer I, II and III, MPEG 2.5 and -- AAC files. -- --
-- %11111111 111xxxxx ---- -- and should be replaced with: -- --
-- %11111111 00000000 111xxxxx ---- -- This has the side effect that all $FF 00 combinations have to be -- altered, so they will not be affected by the decoding process. -- Therefore all the $FF 00 combinations have to be replaced with the $FF -- 00 00 combination during the unsynchronisation. -- -- To indicate usage of the unsynchronisation, the unsynchronisation flag -- in the frame header should be set. This bit MUST be set if the frame -- was altered by the unsynchronisation and SHOULD NOT be set if -- unaltered. If all frames in the tag are unsynchronised the -- unsynchronisation flag in the tag header SHOULD be set. It MUST NOT be -- set if the tag has a frame which is not unsynchronised. -- -- Assume the first byte of the audio to be $FF. The special case when -- the last byte of the last frame is $FF and no padding nor footer is -- used will then introduce a false synchronisation. This can be solved -- by adding a footer, adding padding or unsynchronising the frame and -- add $00 to the end of the frame data, thus adding more byte to the -- frame size than a normal unsynchronisation would. Although not -- preferred, it is allowed to apply the last method on all frames ending -- with $FF. -- -- It is preferred that the tag is either completely unsynchronised or -- not unsynchronised at all. A completely unsynchronised tag has no -- false synchonisations in it, as defined above, and does not end with -- $FF. A completely non-unsynchronised tag contains no unsynchronised -- frames, and thus the unsynchronisation flag in the header is cleared. -- -- Do bear in mind, that if compression or encryption is used, the -- unsynchronisation scheme MUST be applied afterwards. When decoding an -- unsynchronised frame, the unsynchronisation scheme MUST be reversed -- first, encryption and decompression afterwards. -- --
-- 255 (%11111111) syncIntegerd as a 16 bit synchsafe integer is 383 -- (%00000001 01111111). ---- -- (http://www.id3.org/id3v2.4.0-structure) module ID3.Parser.UnSync -- | converting list of bytes to Integer value wordsToInteger :: [Word8] -> Integer -- | unsynchronisation between Integers unSyncInteger :: Integer -> Integer -- | unsychronisation (just unSyncInteger . wordsToInteger) unSynchronise :: [Word8] -> Integer -- | converting Integer value to list of bytes integerToWords :: Int -> Integer -> [Word8] -- | synchronisation between Integers syncInteger :: Integer -> Integer -- | sychronisation (just integerToWords 4 . syncInteger) synchronise :: Integer -> [Word8] module ID3.Type.Unparse class Parsed a unparse :: (Parsed a) => a -> [Word8] data Str Str :: String -> Str data Inf Inf :: [(String, String)] -> Inf class HasSize a size :: (HasSize a) => Accessor a Integer updateSize :: (HasSize a) => a -> a instance Eq Inf instance Eq Str instance Parsed Inf instance Show Inf instance Parsed Str instance Parsed Integer module ID3.Type.Flags data Flags Flags :: [Bool] -> Flags emptyFlags :: Flags allFlags :: Accessor Flags [Bool] accessFlag :: Int -> Accessor Flags Bool instance Eq Flags instance Parsed Flags module ID3.Type.Header -- | ID3v2 HEADER OVERVIEW -- -- The first part of the ID3v2 tag is the 10 byte tag header, laid out as -- follows: -- --
-- ID3v2/file identifier "ID3" -- ID3v2 version $04 00 -- ID3v2 flags %abcd0000 -- ID3v2 size 4 * %0xxxxxxx ---- -- The first three bytes of the tag are always "ID3", to indicate that -- this is an ID3v2 tag, directly followed by the two version bytes. The -- first byte of ID3v2 version is its major version, while the second -- byte is its revision number. In this case this is ID3v2.4.0. All -- revisions are backwards compatible while major versions are not. If -- software with ID3v2.4.0 and below support should encounter version -- five or higher it should simply ignore the whole tag. data ID3Header ID3Header :: TagVersion -> TagFlags -> TagSize -> ID3Header -- | id3v2 version: [major version, revision number] tagVersion_ :: ID3Header -> TagVersion -- | header flags as Bool values tagFlags_ :: ID3Header -> TagFlags -- | full size of tag tagSize_ :: ID3Header -> TagSize -- | id3v2 version major version . revision number type TagVersion = [Word8] -- | MEANING OF FLAGS -- --
-- ID3v2 flags %abcd0000 ---- -- The version is followed by the ID3v2 flags field, of which currently -- four flags are used: -- -- a - Unsynchronisation -- -- Bit 7 in the 'ID3v2 flags' indicates whether or not unsynchronisation -- is applied on all frames (see section 6.1 for details); a set bit -- indicates usage. -- -- b - Extended header -- -- The second bit (bit 6) indicates whether or not the header is followed -- by an extended header. The extended header is described in section -- 3.2. A set bit indicates the presence of an extended header. -- -- c - Experimental indicator -- -- The third bit (bit 5) is used as an 'experimental indicator'. This -- flag SHALL always be set when the tag is in an experimental stage. -- -- d - Footer present -- -- Bit 4 indicates that a footer (section 3.4) is present at the very end -- of the tag. A set bit indicates the presence of a footer. -- -- All the other flags MUST be cleared. If one of these undefined flags -- are set, the tag might not be readable for a parser that does not know -- the flags function. type TagFlags = Flags -- | SIZE BYTES -- -- The ID3v2 tag size is stored as a 32 bit synchsafe integer (section -- 6.2), making a total of 28 effective bits (representing up to 256MB). -- -- The ID3v2 tag size is the sum of the byte length of the extended -- header, the padding and the frames after unsynchronisation. If a -- footer is present this equals to ('total size' - 20) bytes, otherwise -- ('total size' - 10) bytes. type TagSize = Integer instance Eq ID3Header instance Parsed ID3Header instance Show ID3Header module ID3.Type.ExtHeader -- | EXTENDED HEADER OVERVIEW (optional) -- -- The extended header contains information that can provide further -- insight in the structure of the tag, but is not vital to the correct -- parsing of the tag information; hence the extended header is optional. -- --
-- Extended header size 4 * %0xxxxxxx -- Number of flag bytes $01 -- Extended Flags $xx ---- -- Where the 'Extended header size' is the size of the whole extended -- header, stored as a 32 bit synchsafe integer. An extended header can -- thus never have a size of fewer than six bytes. data ID3ExtHeader emptyID3ExtHeader :: ID3ExtHeader initID3ExtHeader :: [ID3ExtHeader -> ID3ExtHeader] -> ID3ExtHeader -- | Extended Header Flags Meaning -- -- The extended flags field, with its size described by 'number of flag -- bytes', is defined as: -- --
-- %0bcd0000 ---- -- Each flag that is set in the extended header has data attached, which -- comes in the order in which the flags are encountered (i.e. the data -- for flag b comes before the data for flag c). Unset -- flags cannot have any attached data. All unknown flags MUST be unset -- and their corresponding data removed when a tag is modified. -- -- Every set flag's data starts with a length byte, which contains a -- value between 0 and 128 ($00 - $7f), followed by data that has the -- field length indicated by the length byte. If a flag has no attached -- data, the value $00 is used as length byte. -- -- b - Tag is an update -- -- If this flag is set, the present tag is an update of a tag found -- earlier in the present file or stream. If frames defined as unique are -- found in the present tag, they are to override any corresponding ones -- found in the earlier tag. This flag has no corresponding data. -- --
-- Flag data length $00 ---- -- c - CRC data present -- -- If this flag is set, a CRC-32 [ISO-3309] data is included in the -- extended header. The CRC is calculated on all the data between the -- header and footer as indicated by the header's tag length field, minus -- the extended header. Note that this includes the padding (if there is -- any), but excludes the footer. The CRC-32 is stored as an 35 bit -- synchsafe integer, leaving the upper four bits always zeroed. -- --
-- Flag data length $05 -- Total frame CRC 5 * %0xxxxxxx ---- -- d - Tag restrictions -- -- For some applications it might be desired to restrict a tag in more -- ways than imposed by the ID3v2 specification. Note that the presence -- of these restrictions does not affect how the tag is decoded, merely -- how it was restricted before encoding. If this flag is set the tag is -- restricted as follows: -- --
-- Flag data length $01 -- Restrictions %ppqrrstt ---- -- p - Tag size restrictions -- --
-- 00 No more than 128 frames and 1 MB total tag size. -- 01 No more than 64 frames and 128 KB total tag size. -- 10 No more than 32 frames and 40 KB total tag size. -- 11 No more than 32 frames and 4 KB total tag size. ---- -- q - Text encoding restrictions -- --
-- 0 No restrictions -- 1 Strings are only encoded with ISO-8859-1 [ISO-8859-1] or -- UTF-8 [UTF-8]. ---- -- r - Text fields size restrictions -- --
-- 00 No restrictions -- 01 No string is longer than 1024 characters. -- 10 No string is longer than 128 characters. -- 11 No string is longer than 30 characters. ---- -- Note that nothing is said about how many bytes is used to represent -- those characters, since it is encoding dependent. If a text frame -- consists of more than one string, the sum of the strungs is restricted -- as stated. -- -- s - Image encoding restrictions -- --
-- 0 No restrictions -- 1 Images are encoded only with PNG [PNG] or JPEG [JFIF]. ---- -- t - Image size restrictions -- --
-- 00 No restrictions -- 01 All images are 256x256 pixels or smaller. -- 10 All images are 64x64 pixels or smaller. -- 11 All images are exactly 64x64 pixels, unless required -- otherwise. --data ExtFlags emptyExtFlags :: ExtFlags initExtFlags :: [ExtFlags -> ExtFlags] -> ExtFlags extSize :: Accessor ID3ExtHeader Integer extFlags :: Accessor ID3ExtHeader ExtFlags isUpdate :: Accessor ExtFlags Bool crc :: Accessor ExtFlags [Word8] restrictions :: Accessor ExtFlags [Bool] instance Eq ExtFlags instance Eq ID3ExtHeader instance Parsed ExtFlags instance Show ExtFlags instance Parsed ID3ExtHeader instance Show ID3ExtHeader module ID3.Type.FrameInfo data FrameInfo UFID :: String -> String -> FrameInfo owner :: FrameInfo -> String id :: FrameInfo -> String Text :: Integer -> String -> FrameInfo enc :: FrameInfo -> Integer text :: FrameInfo -> String TXXX :: Integer -> String -> String -> FrameInfo enc :: FrameInfo -> Integer descr :: FrameInfo -> String text :: FrameInfo -> String URL :: String -> FrameInfo url :: FrameInfo -> String WXXX :: Integer -> String -> String -> FrameInfo enc :: FrameInfo -> Integer descr :: FrameInfo -> String url :: FrameInfo -> String MCDI :: FrameInfo ETCO :: FrameInfo MLLT :: FrameInfo SYTC :: FrameInfo USLT :: Integer -> String -> String -> String -> FrameInfo enc :: FrameInfo -> Integer lang :: FrameInfo -> String descr :: FrameInfo -> String text :: FrameInfo -> String SYLT :: Integer -> String -> Integer -> Integer -> String -> FrameInfo enc :: FrameInfo -> Integer lang :: FrameInfo -> String timeFormat :: FrameInfo -> Integer content :: FrameInfo -> Integer descr :: FrameInfo -> String COMM :: Integer -> String -> String -> String -> FrameInfo enc :: FrameInfo -> Integer lang :: FrameInfo -> String descr :: FrameInfo -> String text :: FrameInfo -> String RVA2 :: FrameInfo EQU2 :: FrameInfo RVRB :: FrameInfo APIC :: Integer -> String -> Word8 -> String -> [Word8] -> FrameInfo enc :: FrameInfo -> Integer mime :: FrameInfo -> String picType :: FrameInfo -> Word8 descr :: FrameInfo -> String picData :: FrameInfo -> [Word8] GEOB :: FrameInfo PCNT :: Integer -> FrameInfo counter :: FrameInfo -> Integer POPM :: String -> Integer -> Integer -> FrameInfo email :: FrameInfo -> String rating :: FrameInfo -> Integer counter :: FrameInfo -> Integer RBUF :: FrameInfo AENC :: FrameInfo LINK :: FrameInfo POSS :: FrameInfo USER :: Integer -> String -> String -> FrameInfo enc :: FrameInfo -> Integer lang :: FrameInfo -> String text :: FrameInfo -> String OWNE :: FrameInfo COMR :: FrameInfo ENCR :: FrameInfo GRID :: FrameInfo PRIV :: FrameInfo SIGN :: FrameInfo ASPI :: FrameInfo TCMP :: Bool -> FrameInfo isPart :: FrameInfo -> Bool Unknown :: String -> FrameInfo value :: FrameInfo -> String instance Eq FrameInfo instance Show FrameInfo instance Parsed FrameInfo -- | This module contain different general parsers. module ID3.Parser.General -- | Just a synonim for one item of input stream type Token = Word8 -- | Parsers state data St State :: Integer -> Integer -> Integer -> St -- | current position in tag , headerFlags :: [Bool] -- ^ , frFlags :: -- [Bool]} -- ^ current frame flags tagPos :: St -> Integer -- | current frame size curSize :: St -> Integer -- | current frame encoding curEncoding :: St -> Integer type TagParser = Parser St Token run :: TagParser a -> [Word8] -> (Either String a, [Token]) -- | Returns tagPos from St. posGet :: TagParser Integer -- | Updates tagPos with given function. posUpdate :: (Integer -> Integer) -> TagParser () -- | Sets tagPos with given value. posSet :: Integer -> TagParser () -- | Decrements tagPos. posDec :: TagParser () -- | Incremets tagPos. posInc :: TagParser () -- | Returns curSize from St. sizeGet :: TagParser Integer -- | Updates curSize with given function. sizeUpdate :: (Integer -> Integer) -> TagParser () -- | Sets curSize with given value. sizeSet :: Integer -> TagParser () -- | Decrements curSize. sizeDec :: TagParser () -- | Incremets curSize. sizeInc :: TagParser () -- | Returns curEncoding from St. encGet :: TagParser Integer -- | Updates curEncoding with given function. encUpdate :: (Integer -> Integer) -> TagParser () -- | Sets curEncoding with given value. encSet :: Integer -> TagParser () -- | Parses one byte and sets curEncoding. encRead :: TagParser Integer -- | Wrapper for reiterative parsers. Mnemonic: if -- curSize > 0 then continue else stop ifSize :: TagParser [a] -> TagParser [a] -- | Wrapper for atomic parsers. Increases tagPos and decreases -- curSize. -- -- many' p parses a list of elements with individual -- parser p. Cannot fail, since an empty list is a valid return -- value. Unlike default many, stops if curSize became 0. many' :: TagParser a -> TagParser [a] -- | Parse a non-empty list of items. many1' :: TagParser a -> TagParser [a] -- | manyTill' p end parses a possibly-empty sequence of -- p's, terminated by a end. manyTill' :: TagParser a -> TagParser z -> TagParser [a] -- | 'manyTill1\' p end' parses a non-empty sequence of p's, terminated by -- a end. manyTill1' :: TagParser a -> TagParser z -> TagParser [a] -- | Parse a list of items separated by discarded junk. sepBy' :: TagParser a -> TagParser sep -> TagParser [a] -- | Parse a non-empty list of items separated by discarded junk. sepBy1' :: TagParser a -> TagParser sep -> TagParser [a] -- | 'count n p' parses a precise number of items, n, using the parser p, -- in sequence. count :: (Num n) => n -> TagParser a -> TagParser [a] -- | count n p' parses a precise number of items, n, using the -- parser p, in sequence. count' :: (Num n) => n -> TagParser a -> TagParser [a] -- | Hybrid of count and 'sepBy\'' countSepBy' :: (Num n) => n -> TagParser a -> TagParser sep -> TagParser [a] -- | terminator parses values termination symbol, according to -- current encoding (curEncoding). terminator :: TagParser [Token] encPack :: Integer -> [Token] -> String -- | Parses a list of values (as [Token]) separated with termination symbol parseValues :: (Num n) => n -> TagParser [[Token]] -- | Parses one value (as [Token]) till termination symbol parseValue :: TagParser [Token] -- | Parses one value and returns it as a String parseString :: TagParser String -- | Parses one value and returns it as a Integer parseNumber :: TagParser Integer -- | Parses 3 bytes of language value (as a String) and returns a pair -- (Language, value) parseLanguage :: TagParser String -- | Takes a list of keys and parses a list of values. Result is zip of -- these two lists. formValues :: [String] -> TagParser [(String, String)] -- | Takes a list of Parsers and applies them by turns. parsers :: [TagParser a] -> TagParser [a] -- | Parses given Token. word8 :: Token -> TagParser Token -- | Parses given list of Tokens. word8s :: [Token] -> TagParser [Token] -- | Parses given ByteString. byteString :: ByteString -> TagParser ByteString -- | Same as byteString but argument is simple String. string :: String -> TagParser ByteString -- | Parses upper-case letters (as Token) upper :: TagParser Token -- | Parses digit-symbol (as Token) digit :: TagParser Token -- | Parses any Token. anyWord8 :: TagParser Token type Size = Integer -- | 'parseSize_ n' parses n bytes of synchronized size-value, and returns -- unsynchronized Integer value. parseSize_ :: Integer -> TagParser Size -- | Takes template of flags-byte and returns it as [Bool] value. -- For example, for %abcd0000 template you should use 'parseFlags_ -- [1..4]'. parseFlags_ :: [Int] -> TagParser [Bool] instance Show St module ID3.Parser.NativeFrames textInfo :: String -> TagParser FrameInfo module ID3.Type.Frame data ID3Frame ID3Frame :: FrameHeader -> FrameInfo -> ID3Frame -- | frame Header frHeader_ :: ID3Frame -> FrameHeader -- | frame Information Value frInfo_ :: ID3Frame -> FrameInfo type FrameName = String -- | Frame Header data FrameHeader FrameHeader :: FrameID -> FrameSize -> FrameFlags -> FrameHeader -- | frame ID frID_ :: FrameHeader -> FrameID -- | frame Size frSize_ :: FrameHeader -> FrameSize -- | frame Flags frFlags_ :: FrameHeader -> FrameFlags type FrameID = String type FrameSize = Integer data FrameFlags FrameFlags :: StatusFlags -> FormatFlags -> FrameFlags -- | Frame status flags statusF :: FrameFlags -> StatusFlags -- | Frame format flags formatF :: FrameFlags -> FormatFlags type StatusFlags = Flags type FormatFlags = Flags instance Eq FrameFlags instance Eq FrameHeader instance Eq ID3Frame instance Parsed FrameFlags instance Show FrameFlags instance Parsed FrameHeader instance Show FrameHeader instance Parsed ID3Frame instance Show ID3Frame instance HasSize ID3Frame module ID3.Type.Tag data ID3Tag ID3Tag :: ID3Header -> Maybe ID3ExtHeader -> Map FrameID ID3Frame -> [FrameID] -> Integer -> ID3Tag tagHeader :: ID3Tag -> ID3Header tagExtHeader :: ID3Tag -> Maybe ID3ExtHeader tagFrames :: ID3Tag -> Map FrameID ID3Frame tagFramesOrder :: ID3Tag -> [FrameID] tagPadding :: ID3Tag -> Integer frame :: FrameID -> Accessor ID3Tag (Maybe ID3Frame) instance Eq ID3Tag instance Parsed ID3Tag instance Show ID3Tag instance HasSize ID3Tag -- | This Module provides parsers for frames. module ID3.Parser.Frame parseFrames :: TagParser ([FrameID], Map FrameID ID3Frame) -- | Parses any Frame Header anyFrameHeader :: TagParser FrameHeader -- | Parses any Frame anyFrame :: TagParser ID3Frame -- | Parses Frame Header with given id frameHeader :: FrameID -> TagParser FrameHeader -- | Parses Frame with given id parseFrame :: FrameID -> TagParser ID3Frame frameID :: TagParser FrameID frameSize :: TagParser FrameSize -- | This module provides parsers for Extended Header -- -- (http://www.id3.org/id3v2.4.0-structure) module ID3.Parser.ExtHeader -- | Parses Extended Header as ID3ExtHeader structure parseExtHeader :: TagParser ID3ExtHeader -- | This module provides parsers for Header. -- -- (http://www.id3.org/id3v2.4.0-structure) module ID3.Parser.Header -- | Parses id3v2 Header parseHeader :: TagParser ID3Header -- | ID3v2 FOOTER (optional) -- -- To speed up the process of locating an ID3v2 tag when searching from -- the end of a file, a footer can be added to the tag. It is REQUIRED to -- add a footer to an appended tag, i.e. a tag located after all audio -- data. The footer is a copy of the header, but with a different -- identifier. -- --
-- ID3v2 identifier "3DI" -- ID3v2 version $04 00 -- ID3v2 flags %abcd0000 -- ID3v2 size 4 * %0xxxxxxx --parseFooter :: TagParser ID3Header module ID3.Type module ID3.Parser.Tag data ID3Tag ID3Tag :: ID3Header -> Maybe ID3ExtHeader -> Map FrameID ID3Frame -> [FrameID] -> Integer -> ID3Tag tagHeader :: ID3Tag -> ID3Header tagExtHeader :: ID3Tag -> Maybe ID3ExtHeader tagFrames :: ID3Tag -> Map FrameID ID3Frame tagFramesOrder :: ID3Tag -> [FrameID] tagPadding :: ID3Tag -> Integer run :: TagParser a -> [Word8] -> (Either String a, [Token]) parseTag :: TagParser ID3Tag parseTag_ :: ID3Header -> TagParser ID3Tag module ID3.Parser module ID3.ReadTag hReadTag :: Handle -> IO (Maybe ID3Tag) readTag :: FilePath -> IO (Maybe ID3Tag) module ID3.WriteTag hWriteTag :: ID3Tag -> Handle -> IO () writeTag :: FilePath -> ID3Tag -> IO () module ID3.Simple type Tag = ID3Tag setArtist :: String -> Tag -> Tag setTitle :: String -> Tag -> Tag setAlbum :: String -> Tag -> Tag setYear :: String -> Tag -> Tag setTrack :: String -> Tag -> Tag getArtist :: Tag -> Maybe String getTitle :: Tag -> Maybe String getAlbum :: Tag -> Maybe String getYear :: Tag -> Maybe String getTrack :: Tag -> Maybe String readTag :: FilePath -> IO (Maybe ID3Tag) writeTag :: FilePath -> ID3Tag -> IO () module ID3