DSD 인코더 품질 개선, 새 컨테이너 .dst와 DST 압축 인코더
- siseong3
- 18시간 전
- 4분 분량
DSD를 만드는 인코더를 처음부터 다시 만들었습니다
Pine Player Pro의 포맷 변환기는 그동안 DSD 변환을 기존 Pine Player 개발 시의 구현된 초기 인코더에 맡겨 왔습니다. 잘 동작했지만 측정을 해 보면 아쉬운 대목이 남아 있었습니다. 특히 DSD128·DSD256처럼 배속을 올렸을 때 기대만큼 조용해지지 않는, 오디오적으로 앞뒤가 맞지 않는 상태가 있었습니다.
이번 판에서는 PCM을 DSD로 만드는 경로와 DSD를 PCM으로 되돌리는 경로를 모두 새로 구현했고, 여기에 그동안 없었던 DST 압축 인코더와 새 컨테이너 .dst를 더했습니다. 무엇이 어떻게 바뀌었는지 측정치와 함께 정리합니다.

한눈에 보기
항목 | 기존 Pine Player 인코더 | 새 구현 |
DSD64 SNR (1kHz −6dBFS) | 100.0 dB | 111.7 dB |
DSD64 THD | −114.2 dB | −134.7 dB |
무음 구간 잡음 (DSD64) | −108 dBFS | −137 dBFS |
대역내 잡음 (DSD128) | −136.3 dBFS | −180.8 dBFS |
대역내 잡음 (DSD256) | −156.8 dBFS | −191.9 dBFS |
PCM → DSD 변환 시간 (30초 곡) | 10.62 초 | 3.25 초 |
DST 압축 만들기 | 불가 (읽기 전용) | 49.0% · 2.04배 (실시간 3.6배) |
측정 조건과 방법은 본문 각 절에 적었습니다. 모두 같은 조건에서 디코드·FFT로 비교한 값입니다.
1. PCM → DSD: 새 시그마-델타 변조기
DSD는 1비트 신호입니다. 16비트나 24비트 PCM을 1비트로 바꾸려면 양자화 오차를 가청대역 밖으로 밀어내는 잡음 성형이 필요하고, 이 설계가 결과의 음질을 좌우합니다.
새 변조기는 오차 되먹임 구조로 만들었습니다. 잡음 전달 함수의 영점은 가청대역 안에 체비셰프 방식으로 퍼뜨려 그 대역의 잡음을 최대한 눌렀고, 극점은 대역외 최대 이득이 1.5가 되도록 버터워스 방식으로 배치해 1비트 변조기가 발산하지 않을 여유를 두었습니다. 차수는 5·6·7차를 준비했으며, 상태가 한계를 넘어서면 그 구간만 되살리는 보호 장치도 넣었습니다.
측정 (DSD64, 1kHz −6dBFS, 같은 방법으로 디코드·FFT)
기존 Pine Player 인코더 — SNR 100.0dB, THD −114.2dB
새 변조기(6차) — SNR 111.7dB, THD −134.7dB
무음 구간의 잡음은 −108dBFS에서 −137dBFS로 내려갔고, 출력 레벨은 종전과 같습니다. 실제 음악에서 31Hz~16kHz 응답 편차는 ±0.06dB입니다.
2. 배속을 올리면 실제로 조용해집니다
잡음 전달 함수의 영점은 “가청대역이 정규화 주파수에서 어디까지인가”에 맞춰 놓아야 합니다. 처음 구현은 DSD64 기준으로 만든 계수표 하나를 모든 배속에 쓰고 있었고, 그래서 DSD128·DSD256에서는 영점이 40~80kHz로 밀려나 가청대역 안의 잡음이 거의 줄지 않았습니다. 배속을 올린 보람이 없는 상태였던 것입니다.
배속마다 5·6·7차 계수표를 새로 설계했습니다. 대역내 잡음(무음 입력 기준)은 다음과 같이 달라졌습니다.
DSD64 — −140.1dBFS (변동 없음)
DSD128 — −139.2 → −180.8dBFS (41.6dB 개선)
DSD256 — −141.5 → −191.9dBFS (50.4dB 개선)
1kHz 정현파 기준 SNR도 DSD128이 126.1 → 130.8dB, DSD256이 127.9 → 130.8dB로 올라갔습니다. 이제 배속을 올린 만큼 실제로 조용해집니다.
3. 44.1~48kHz 원본의 고역, 그리고 정밀도 문제 세 가지
기존 인코더와 나란히 놓고 측정하는 과정에서 세 가지를 더 잡았습니다.
44.1~48kHz 원본의 고역이 깎이던 문제. 보간 필터가 위상당 32탭이어서 전이대역이 너무 넓었고, 18~20kHz가 1.4~4.3dB 깎였습니다. 필터 길이를 전이대역 폭 기준으로 정하고 보간을 두 단으로 나눴습니다. 1단은 원본을 8배까지 날카로운 필터(위상당 140탭, 카이저 β=10)로 올리고, 2단은 신호가 표본율의 3% 아래에만 남은 상태이므로 가벼운 곡선 보간으로 채웁니다. 그 결과 44.1~48kHz 스윕에서 20kHz까지 기존 인코더와 0.00dB로 일치합니다(이전에는 19~20kHz가 −4.3dB).
16비트 Normalize의 이중 양자화. 첫 판을 16비트로 쓴 뒤 다시 읽어 레벨을 맞추면서 한 번 더 양자화하고 있었습니다. 이제 중간 결과를 32비트 실수로 두고 마지막에 한 번만 양자화하며, 16비트 출력에는 TPDF 디더를 넣습니다. 조용한 원본 기준 SNR이 58.1dB에서 93.3dB로 올라갔습니다.
필터 지연 미보정. 군지연만큼 앞당겨 읽고 원본이 끝난 뒤 꼬리를 마저 뽑도록 해서, 원본 대비 16표본이던 지연이 0표본이 되었습니다. 길이도 정확히 맞습니다.
속도도 함께 좋아졌습니다. 30초 곡의 PCM → DSD 변환이 3.25초로, 기존 인코더(10.62초)의 3.3배입니다. 화면의 DSD Gain(−10~+10dB)과 Normalize 설정도 이제 PCM 원본에서 제대로 반영됩니다(예전에는 무시됐습니다).
4. DSD → PCM 복조도 자체 구현
반대 방향도 새로 만들었습니다. 바이트 표를 이용한 256탭 FIR로 8배 줄이고, 필요하면 63탭 하프밴드 필터를 최대 4단 더 거칩니다. 많이 줄일수록 필터를 길게 잡아 초고역 잡음이 접혀 들어오지 않게 했고, 16비트 출력에는 TPDF 디더를 넣었습니다.
44.1k · 48k · 96k · 192k 모두 SNR 약 100dB, THD −114dB로 종전과 같은 수준이며, 20Hz~30kHz 응답 차이는 0.00dB, 시간 정렬도 1표본 이내입니다. DSF·DFF·DST 세 입력의 결과는 표본 단위로 완전히 같습니다. 속도는 30초 DSD64 기준 실시간의 21~36배입니다.
5. DST 압축 인코더 — DSD 파일을 절반 크기로
DST(Direct Stream Transfer)는 SACD가 쓰는 DSD 무손실 압축입니다. 지금까지 Pine Player Pro는 이미 DST로 압축된 자료(SACD ISO)를 읽을 수만 있었고, DST를 새로 만들 수는 없었습니다. 압축을 만드는 인코더가 없었기 때문입니다.
이번에 DST 인코더를 새로 작성했습니다. 산술부호화기, 프레임 문법, 프레임·채널마다 다시 계산하는 예측 필터(자기상관 → 레빈슨-더빈 → 9비트 양자화, 차수 128), 예측 오차 확률표(64칸)까지 규격대로 구현했고, 압축 이득이 없는 구간은 규격의 ‘압축하지 않음’ 프레임으로 되돌립니다.
실측 (29.7초 SACD 음원, 5스레드) — 20,971,520바이트 → 10,269,578바이트. 49.0%, 약 2.04배 압축이고 8.3초에 끝납니다(실시간의 3.6배). 무손실이므로 압축을 풀면 원본과 바이트 단위로 완전히 같고, 독립적인 외부 DST 디코더에서도 정상 재생됩니다.
변환기 출력 형식에 DFF(DFF with DST compression)이 추가되었습니다. DST는 SACD 규격상 DSD64만 정의되어 있어 이 형식을 고르면 배속은 DSD64로 고정됩니다. 압축 진행 상황은 기존 진행 막대에 이어서 표시되며, 동시 변환(최대 5개) 시에는 코어 수를 파일 수로 나눠 작업들이 서로 밀어내지 않게 했습니다.
6. 새 컨테이너 .dst — 압축된 DSD에 태그와 앨범아트를
DFF는 오래된 컨테이너이라 태그를 담는 표준 자리가 마땅치 않습니다. 반대로 DSF는 태그를 잘 담지만 압축을 지원하지 않습니다. 그래서 두 쪽의 장점을 합친 컨테이너을 새로 만들었습니다.
.dst는 소리 자료로 DFF의 DST 압축을 그대로 쓰고, 파일 끝에 ID3v2.3 태그를 붙여 곡 정보와 앨범아트를 담습니다. DFF를 읽는 프로그램은 뒤에 붙은 태그 바이트를 그냥 지나치므로 호환성 문제도 없습니다.
변환기의 출력 형식 DST(DSF with DST compression)으로 만들 수 있고, 원본의 곡 정보와 앨범아트를 그대로 옮겨 붙입니다. 재생은 일반 PCM 경로와 DoP 네이티브 경로 모두 지원하며, 메타 정보 편집기에서 태그를 읽고 쓸 수 있습니다.
검증 과정에서는 같은 소리의 .dst와 .dff를 비교해 풀어낸 DSD 5,644,930바이트가 전부 일치하는 것, 앨범아트 PNG·JPEG가 왕복 후 바이트 단위로 같은 것, 잘린 파일이나 태그 크기를 부풀린 파일에서도 앱이 죽지 않는 것을 확인했습니다.
7. 그 밖에 달라진 것들
DSD끼리 변환은 컨테이너만 바꿉니다. 같은 배속의 DSD를 다른 DSD 컨테이너으로 옮길 때 예전에는 PCM으로 갔다 오는 재변환을 하고 있었습니다. 이제는 소리 자료를 그대로 옮겨 담습니다. DSF ↔ DFF는 물론, DST로 압축된 DFF에서 DSF로 갈 때도 압축을 풀면서 곧바로 담습니다(임시 파일 없음). 무손실이고 훨씬 빠릅니다.
DST로 압축된 .dff도 변환됩니다. 예전에는 비압축 DSD만 읽을 수 있어 DST .dff는 변환이 실패했습니다. 이제 압축을 풀어 처리하며, 곡 정보와 결과 파일 이름은 원본을 그대로 따릅니다.
DoP 네이티브 재생 범위가 넓어졌습니다. SACD ISO 트랙과 DST로 압축된 .dff를 DoP로 그대로 재생합니다. 압축을 푼 스트림을 파일처럼 넘겨 주는 입력 경로를 만들어 해결했고, 탐색과 다음 곡 진행도 정상 동작합니다.
형식 이름을 알기 쉽게 바꿨습니다. DFF(DST)는 DFF(DFF with DST compression)로, DST(DSD)는 DST(DSF with DST compression)로 바꿨습니다. 예전 이름이 설정에 저장돼 있어도 자동으로 새 이름으로 읽어 들입니다.
정리
요점은 세 가지입니다. DSD 인코더를 새로 만들어 DSD64에서 SNR을 11.7dB, DSD128·DSD256에서 대역내 잡음을 41~50dB 개선했고, DST 압축 인코더를 더해 DSD 파일을 무손실로 절반 크기까지 줄일 수 있게 되었으며, 압축된 DSD에도 태그와 앨범아트를 담을 수 있는 새 컨테이너 .dst를 추가했습니다.
본문의 측정치는 모두 같은 조건에서 디코드·FFT로 비교한 값입니다. DSD 음원을 직접 만들고 보관하시는 분들께 도움이 되기를 바랍니다.



댓글