Browse Source

Изменён алгоритм расчёта LUFS

master
Maxim Lihachev 9 years ago
parent
commit
8234bb103f
  1. 28
      audioread.hs

28
audioread.hs

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}
-- Создан: Ср 28 сен 2016 10:18:53
-- Изменен: Пн 17 окт 2016 16:36:12
-- Изменен: Чт 20 окт 2016 10:14:42
-- Copyright (C) 2011-2013, Maxim Lihachev, <envrm@yandex.ru>
@ -66,19 +66,19 @@ notZero x = (not $ isNaN x) && (x /= 0) @@ -66,19 +66,19 @@ notZero x = (not $ isNaN x) && (x /= 0)
-- =============================================================================
-- Чтение данных аудиофайла
audioread :: WAVE -> [[Double]]
-- audioread :: WAVE -> [[Double]]
audioread = map samplesToDouble . waveSamples
where samplesToDouble (l:r:[]) = [sampleToDouble l, sampleToDouble r]
--Выбор канала из пары
getChannel :: [Char] -> [[Double]] -> [Double]
-- getChannel :: [Char] -> [[Double]] -> [Double]
getChannel ch = map selectChannel where
selectChannel (l:r:[]) | ch == "R" = r
| ch == "L" = l
| otherwise = l
-- k десятичных логарифмов
float2db :: (RealFloat a, Integral b) => b -> a -> a
-- float2db :: (RealFloat a, Integral b) => b -> a -> a
float2db k x
| notZero x = fromIntegral k * (logBase 10 x)
| otherwise = 0
@ -89,28 +89,28 @@ peak [] = acos(1) -- NaN @@ -89,28 +89,28 @@ peak [] = acos(1) -- NaN
peak xs = maximum xs
-- Вычисление уровня сигнала
calcLevel :: [Char] -> Int -> [Double] -> Int
calcLevel :: [Char] -> Int -> [Double] -> Double
calcLevel vu = case (toLower <@ vu) of
"lufs" -> calcLevelLUFS
"db" -> calcLevelDb
-- Вычисление уровня сигнала / Db
calcLevelDb :: Int -> [Double] -> Int
calcLevelDb :: Int -> [Double] -> Double
calcLevelDb fs samples = case dd of
[] -> -52 -- Неслышимый звук
_ -> round (median dd)
_ -> median dd
where
dd = notZero <# map (float2db 20 . peak) slices
slices = splitWhen (== 0) $ take fs samples
-- Вычисление уровня сигнала / LUFS
calcLevelLUFS :: Int -> [Double] -> Int
calcLevelLUFS fs samples = round (median $ getlufs <@ chunks)
where
getlufs l = float2db 10 (1 / fd' * (sum $ map (^2) l))
chunks = everyN fd $ take fs samples
fd = fs `div` 10
fd' = convert fd :: Double
calcLevelLUFS :: Int -> [Double] -> Double
calcLevelLUFS fs samples = lufs
where
lufs = float2db 10 (1 / fs' * s) + 3
s = sum [x*x | x <- samples]
fs' = convert fs :: Double
-- Вычисление значения фазы
calcPhase :: (Ord a, Fractional a) => [[a]] -> a

Loading…
Cancel
Save