{-# LANGUAGE OverloadedStrings #-}
module AcousticBrainz.LowLevel where
import AcousticBrainz.StatisticalUnits
import AcousticBrainz.MetaData
import qualified AcousticBrainz.LowLevel.Algorithm.SilenceRate as SilenceRate
import AcousticBrainz.LowLevel.BarkBands
import AcousticBrainz.LowLevel.CepstralCoefficients
import qualified AcousticBrainz.LowLevel.EquivalentRectangularBandwidth as EquivalentRectangularBandwidth
import AcousticBrainz.LowLevel.MelBands
import AcousticBrainz.LowLevel.Rhythm
import AcousticBrainz.LowLevel.Spectral
import AcousticBrainz.LowLevel.Tonal
import MusicBrainz
import Control.Monad.Catch
import Data.Aeson as JSON
import Data.Aeson.Types as JSON
import qualified Data.ByteString.Lazy as Lazy
import qualified Data.ByteString.Streaming as Q
import Data.ByteString.Streaming.HTTP
import Data.Scientific
import qualified Data.Text as Text
getLowLevelData :: MonadIO m => MonadThrow m => MusicBrainzIdentifier -> m LowLevelResponse
getLowLevelData (MusicBrainzIdentifier identifier) = io $ do
request <- parseRequest $ "https://acousticbrainz.org/api/v1/" <> Text.unpack identifier <> "/low-level"
manager <- newManager tlsManagerSettings
withHTTP request manager $ \r ->
r & responseBody & Q.toLazy_ <&> eitherDecode >>= liftEither
where liftEither (Left e) = throwM $ LowLevelException e
liftEither (Right a) = return a
data LowLevelResponse = LowLevelResponse
{ _data :: LowLevelData
, _tonal :: Tonal
, _rhythm :: Rhythm
, _metadata :: MetaData
} deriving(Eq, Read, Show)
instance FromJSON LowLevelResponse where
parseJSON = withObject "response" $ \v -> LowLevelResponse
<$> v .: "lowlevel"
<*> v .: "tonal"
<*> v .: "rhythm"
<*> (v .: "metadata" >>= parseMetaData)
parseMetaData = withObject "metadata" $ \v -> MetaData
<$> v .: "audio_properties"
<*> v .: "tags"
<*> v .: "version"
data LowLevelData = LowLevelData
{ _averageLoudness :: Scientific
, _barkBands :: BarkBands
, _dissonance :: StatisticalUnits
, _dynamicComplexity :: Scientific
, _equivalentRectangularBandwidthBands :: EquivalentRectangularBandwidth.Bands
, _gfcc :: CepstralCoefficients
, _highFrequencyContent :: StatisticalUnits
, _melBands :: MelBands
, _mfcc :: CepstralCoefficients
, _pitchSalience :: StatisticalUnits
, _silenceRate :: SilenceRate.Output
, _spectral :: Spectral
, _zeroCrossingRate :: StatisticalUnits
} deriving(Eq, Ord, Read, Show)
instance FromJSON LowLevelData where
parseJSON value = flip (withObject "lowlevel") value $ \v -> LowLevelData
<$> v .: "average_loudness"
<*> parseJSON value
<*> v .: "dissonance"
<*> v .: "dynamic_complexity"
<*> parseJSON value
<*> v .: "gfcc"
<*> v .: "hfc"
<*> parseJSON value
<*> v .: "mfcc"
<*> v .: "pitch_salience"
<*> parseJSON value
<*> parseJSON value
<*> v .: "zerocrossingrate"
newtype LowLevelException = LowLevelException String deriving(Eq, Ord, Read, Show)
instance Exception LowLevelException