Files

40 lines
2.2 KiB
Python

"""독립 BS.1770 구현으로 exact WAV를 검사한다. 일반 npm test에서는 실행하지 않는다."""
import hashlib
from importlib.metadata import version
import json
from pathlib import Path
import platform
import sys
import pyloudnorm as pyln
import soundfile as sf
ROOT = Path(__file__).resolve().parents[3]
EVIDENCE = Path(__file__).resolve().parent
assert version('pyloudnorm') == '0.2.0'
assert version('soundfile') == '0.13.1'
def sha(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
rows = []
# manifest의 loudness나 생성기 함수를 읽지 않고 실제 파일을 독립 구현으로 측정한다.
for path in sorted((ROOT / 'public/ambience').glob('*.wav')):
before = sha(path)
data, rate = sf.read(path, dtype='float64', always_2d=False)
assert rate == 24000 and data.shape == (288000,)
meter = pyln.Meter(rate, filter_class='K-weighting', block_size=0.400)
value = float(meter.integrated_loudness(data))
assert sha(path) == before
rows.append({'file': str(path.relative_to(ROOT)), 'sha256': before, 'bytes': path.stat().st_size,
'frames': len(data), 'sampleRate': rate, 'integratedLUFS': value,
'targetErrorLU': value + 32.5})
spread = max(r['integratedLUFS'] for r in rows) - min(r['integratedLUFS'] for r in rows)
passed = len(rows) == 8 and all(abs(r['targetErrorLU']) <= 0.2 for r in rows) and spread <= 0.4
report = {'method': 'Independent pyloudnorm BS.1770 K-weighting, 400ms blocks, mono exact PCM16 decoded by soundfile',
'python': platform.python_version(), 'versions': {name: version(name) for name in ('pyloudnorm','soundfile','numpy','scipy','cffi','pycparser','future')},
'libsndfileVersion': sf.__libsndfile_version__, 'scriptSha256': sha(Path(__file__)),
'manifestSha256': sha(ROOT/'public/ambience/manifest.json'), 'targetIntegratedLUFS': -32.5,
'toleranceLU': 0.2, 'maximumSpreadLU': 0.4, 'spreadLU': spread, 'passed': passed, 'files': rows}
with (EVIDENCE/'pyloudnorm-results.json').open('x') as stream:
stream.write(json.dumps(report, indent=2, allow_nan=False)+'\n')
print(json.dumps(report, indent=2, allow_nan=False))
if not passed: sys.exit('Independent loudness release criterion failed')