Browse Source

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

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

26
audioread.hs

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

Loading…
Cancel
Save