|
|
|
@ -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 |
|
|
|
|