diff --git a/README.md b/README.md index 380c61e..7100ba4 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,7 @@ * [License](#license) This is Haskell bindings to [TagLib](https://taglib.github.io/), library for -reading and editing meta-data of several popular audio formats. This library -is easy to use and type-safe. +reading and editing meta-data of several popular audio formats. It works with the following formats: @@ -31,7 +30,7 @@ It works with the following formats: * MP4 * ASF -This happens in abstract, uniform way, so you don't need to handle any +This happens in an abstract, uniform way, so you don't need to handle any low-level details. As a consequence, it's currently not possible to work with format-specific functionality. @@ -49,18 +48,17 @@ I wrote this. ## A note for FLAC users If you want to work with FLAC, there is -a [complete Haskell binding](https://github.com/mrkkrp/flac) to `libFLAC` — -reference FLAC implementation. It allows to work with all FLAC metadata -(read and write) and also provides Haskell API to stream encoder and stream -decoder. Please prefer that package if you don't need to work with other -audio formats. +a [complete Haskell binding](https://github.com/mrkkrp/flac) to +`libFLAC`—reference FLAC implementation. It allows to work with all FLAC +metadata (read and write) and also provides Haskell API to stream encoder +and stream decoder. Please prefer that package if you don't need to work +with other audio formats. ## Quick start First, since this is bindings to C-interface of the library, you'll need to -install the library itself. If you're on Unix-like system, chances are -you'll have it in official repositories of your distro. Users of other -systems should also be able to install it without particular pain. +install the library itself. If you're on a Unix-like system, chances are +you'll have it in the official repositories of your distro. After installation of the library, install `htaglib` package using Cabal or Stack (recommended): @@ -96,8 +94,8 @@ A couple of notes here. We use unique types for every component of meta data, so it's more difficult to use track title in lieu of track artist, for example. Meta data that is represented by strings also has smart constructors, they replace zero bytes with spaces, this is necessary to -avoid troubles when your Haskell strings go to C-level (well, zero-bytes in -strings is rather edge case, but it should be mentioned). Of course, +avoid troubles when your Haskell strings go to the C-level (well, zero-bytes +in strings is rather edge case, but it should be mentioned). Of course, `Title`, `Artist`, `Album`, `Comment`, and `Genre` all are instances of `IsString`, so just turn on `OverloadedStrings` and you can use normal string literals to create data of these types. @@ -156,8 +154,8 @@ N.B. If you need to extract duration of tracks, TagLib only returns number of seconds as an integer. This means that if you want to calculate total duration, you'll have slightly incorrect result. Proper solution is to extract duration as floating-point number, for that we recommend bindings to -`libsndfile` — [`hsndfile`](https://hackage.haskell.org/package/hsndfile) -(or the above-mentioned `flac` package for Haskell if you work with FLAC). +`libsndfile`—[`hsndfile`](https://hackage.haskell.org/package/hsndfile) (or +the above-mentioned `flac` package for Haskell if you work with FLAC). ### Writing meta data @@ -184,8 +182,7 @@ main = do print track ``` -This code loads file and changes “title” and “artist” meta data -fields. +This code loads file and changes “title” and “artist” meta data fields. ## Conclusion diff --git a/Sound/HTagLib.hs b/Sound/HTagLib.hs index 1b2e6d8..58efc4e 100644 --- a/Sound/HTagLib.hs +++ b/Sound/HTagLib.hs @@ -7,8 +7,8 @@ -- Stability : experimental -- Portability : portable -- --- This module includes complete high-level interface to TagLib. This is the --- module you should import to use in your projects. +-- This module provides a complete high-level interface to TagLib. This is +-- the module you should import to use in your projects. module Sound.HTagLib ( -- * Getters diff --git a/Sound/HTagLib/Getter.hs b/Sound/HTagLib/Getter.hs index 355f8e7..56afaa1 100644 --- a/Sound/HTagLib/Getter.hs +++ b/Sound/HTagLib/Getter.hs @@ -7,7 +7,7 @@ -- Stability : experimental -- Portability : portable -- --- High-level applicative interface for reading of audio meta data. You +-- A high-level applicative interface for reading of audio meta data. You -- don't need to import this module directly, import "Sound.HTagLib" -- instead. @@ -37,11 +37,11 @@ import Sound.HTagLib.Type import qualified Sound.HTagLib.Internal as I #if !MIN_VERSION_base(4,8,0) -import Control.Applicative (Applicative, (<$>), (<*>), pure) +import Control.Applicative #endif --- | This type represents a composable entity that can be used with --- 'getTags' or 'getTags'' functions to read batch of meta parameters. +-- | A composable entity that can be used with 'getTags' or 'getTags'' +-- functions to read batch of meta parameters. newtype TagGetter a = TagGetter { runGetter :: I.FileId -> IO a } @@ -59,7 +59,7 @@ instance Applicative TagGetter where -- extension. If this is not satisfactory and you want to explicitly specify -- the file type, see 'getTags'' variation of this function. -- --- In case of trouble 'I.HTagLibException' will be thrown. +-- In the case of trouble 'I.HTagLibException' will be thrown. getTags :: MonadIO m => FilePath -- ^ Path to audio file diff --git a/Sound/HTagLib/Internal.hs b/Sound/HTagLib/Internal.hs index 1432f30..5b337ed 100644 --- a/Sound/HTagLib/Internal.hs +++ b/Sound/HTagLib/Internal.hs @@ -68,6 +68,7 @@ data TagLibProperties newtype FileId = FileId (Ptr TagLibFile) +---------------------------------------------------------------------------- -- Misc foreign import ccall unsafe "taglib/tag_c.h taglib_set_string_management_enabled" @@ -96,6 +97,7 @@ foreign import ccall unsafe "taglib/tag_c.h taglib_file_audioproperties" foreign import ccall unsafe "taglib/tag_c.h taglib_file_save" c_taglib_file_save :: Ptr TagLibFile -> IO CInt +---------------------------------------------------------------------------- -- Tag API foreign import ccall unsafe "taglib/tag_c.h taglib_tag_title" @@ -140,6 +142,7 @@ foreign import ccall unsafe "taglib/tag_c.h taglib_tag_set_year" foreign import ccall unsafe "taglib/tag_c.h taglib_tag_set_track" c_taglib_tag_set_track :: Ptr TagLibTag -> CUInt -> IO () +---------------------------------------------------------------------------- -- Audio properties API foreign import ccall unsafe "taglib/tag_c.h taglib_audioproperties_length" @@ -154,14 +157,13 @@ foreign import ccall unsafe "taglib/tag_c.h taglib_audioproperties_samplerate" foreign import ccall unsafe "taglib/tag_c.h taglib_audioproperties_channels" c_taglib_properties_channels :: Ptr TagLibProperties -> IO CInt +---------------------------------------------------------------------------- -- Special convenience ID3v2 functions foreign import ccall unsafe "taglib/tag_c.h taglib_id3v2_set_default_text_encoding" c_taglib_id3v2_set_default_text_encoding :: CInt -> IO () --- Wrappers. Here we prepare a little higher-level interface that will be --- used by the rest of the library. - +---------------------------------------------------------------------------- -- File API -- | Open audio file and return its ID (an opaque type that the rest of @@ -212,6 +214,7 @@ saveFile path (FileId ptr) = do unless success $ throw (T.SavingFailed path) +---------------------------------------------------------------------------- -- Tag API -- | Get title tag associated with file. @@ -284,6 +287,7 @@ setYear v = setIntValue c_taglib_tag_set_year (T.unYear <$> v) setTrackNumber :: Maybe T.TrackNumber -> FileId -> IO () setTrackNumber v = setIntValue c_taglib_tag_set_track (T.unTrackNumber <$> v) +---------------------------------------------------------------------------- -- Audio properties API -- | Get duration of track associated with file. @@ -310,6 +314,7 @@ getChannels :: FileId -> IO T.Channels getChannels = fmap (fromJust . T.mkChannels) . getIntProperty c_taglib_properties_channels +---------------------------------------------------------------------------- -- Special convenience ID3v2 functions -- | Set the default encoding for ID3v2 frames that are written to tags. @@ -317,6 +322,7 @@ getChannels = fmap (fromJust . T.mkChannels) id3v2SetEncoding :: T.ID3v2Encoding -> IO () id3v2SetEncoding = c_taglib_id3v2_set_default_text_encoding . enumToCInt +---------------------------------------------------------------------------- -- Helpers getStrValue diff --git a/Sound/HTagLib/Setter.hs b/Sound/HTagLib/Setter.hs index db63f75..fccc95d 100644 --- a/Sound/HTagLib/Setter.hs +++ b/Sound/HTagLib/Setter.hs @@ -7,7 +7,7 @@ -- Stability : experimental -- Portability : portable -- --- High-level interface for writing audio meta data. You don't need to +-- A high-level interface for writing audio meta data. You don't need to -- import this module directly, import "Sound.HTagLib" instead. {-# LANGUAGE CPP #-} @@ -76,7 +76,7 @@ instance Monoid TagSetter where -- | Set tags in specified file using the given setter. -- --- In case of trouble 'I.HTagLibException' will be thrown. +-- In the case of trouble 'I.HTagLibException' will be thrown. setTags :: MonadIO m => FilePath -- ^ Path to audio file diff --git a/tests/Sound/HTagLib/GetterSpec.hs b/tests/Sound/HTagLib/GetterSpec.hs index 223bc54..fd6ddae 100644 --- a/tests/Sound/HTagLib/GetterSpec.hs +++ b/tests/Sound/HTagLib/GetterSpec.hs @@ -5,7 +5,7 @@ import Sound.HTagLib.Test.Util import Test.Hspec #if !MIN_VERSION_base(4,8,0) -import Control.Applicative ((<$>)) +import Control.Applicative #endif spec :: Spec diff --git a/tests/Sound/HTagLib/SetterSpec.hs b/tests/Sound/HTagLib/SetterSpec.hs index 6fda63c..eff1730 100644 --- a/tests/Sound/HTagLib/SetterSpec.hs +++ b/tests/Sound/HTagLib/SetterSpec.hs @@ -9,7 +9,7 @@ import System.FilePath ((), takeFileName) import Test.Hspec #if !MIN_VERSION_base(4,8,0) -import Control.Applicative ((<$>)) +import Control.Applicative #endif spec :: Spec diff --git a/tests/Sound/HTagLib/Test/Util.hs b/tests/Sound/HTagLib/Test/Util.hs index f2de50a..712e43d 100644 --- a/tests/Sound/HTagLib/Test/Util.hs +++ b/tests/Sound/HTagLib/Test/Util.hs @@ -15,7 +15,7 @@ import Sound.HTagLib import Test.Hspec #if !MIN_VERSION_base(4,8,0) -import Control.Applicative ((<$>), (<*>), pure) +import Control.Applicative #endif data AudioTags = AudioTags