Symphonic MPD [2] 기술적 고찰

Date:     Updated:

카테고리:

태그:

의문점

제 생각과 인터넷에서 찾은 정보를 취합해서 정리를 해 봤습니다.

Symphonic MPD (이하 smpd)를 설치해서 일주일 가까이 앰프, 스피커도 변경하면서 다양한 방식으로 청음을 하면서 도대체 어떤 방식의 튜닝이 적용되었는지 궁금해지기 시작했습니다.

저도 엔지니어 직종에서 오랬동안 일을 해왔지만 분야를 막론하고 일반적으로 공학 계열에서 어떤 문제를 해결하거나 개선을 한다고 하면 목표로 하는 지향점이나 이를 측정해서 검증할 수 있는 지표 같은 것이 있어야 합니다. 또한 어떤 개선이 있다면 반드시 이유가 있습니다.

물론 피곤하게 그 이유를 꼭 알아야 하냐는 반문도 있을 수 있습니다.^^

속된 말로 공돌이의 습성이라고 할 수 있지만 저의 생각은 Audiophile DIYER 라고 하면 이러한 기술적 고찰과 본인이 원하는 소리를 찾기 위한 과학적이고 객관적인 접근 방식이 필요하다고 생각합니다.

전 smpd 포럼의 소개 내용만으로는 납득이 가지 않았습니다.

레이턴시(Latency)를 줄이는 것이 음질하고 무슨 상관인가 ? (상관이 있을 수도 있지만 ….)

라즈베리파이의 OS, 재생 소프트웨어를 튜닝하면 음질이 향상될 수 있는가? 돈이 좀 들어가더라도 단순히 좋은 DAC 바꾸면 되는 것이 아닌가? 전원부를 업그래드하면 더 효과적이지 않을까?……

smpd 의 기술적 고찰을 위해서 참고로 할만한 정보가 부족해서 diyaudio.com 의 글타래를 시간을 내서 천천히 읽어 봤습니다.

diyAudio Symphonic MPD

많은 사람들이 등장하지 않지만 파파리우스 (papalius) 라는 아이디를 사용하는 사람이 smpd 개발자입니다. 이 외에 몇몇 아이디들이 등장하는데 제가 diyaudio.com 에서 piCorePlayer, Logitech Media Server 관련 글에서 보았던 개발자나 엔지니어로 보이는 아이디였습니다.

질문의 집중된 내용은 smpd의 음질향상의 기술적으로 어떻게 이루어지고 이를 입증할 데이터가 있는가로부터 시작됩니다.

보통 일반적인 카페에서 이런 논쟁이 벌어졌다면 싸움이 나기 쉽상입니다. 내용 중에 다소 무례한 표현들 (근거 없이 소리가 좋다고 하는 사람들을 부두교라고….) 이 나와도 놀랐지만 논쟁을 통해서 서로간의 기술적 이견들이 깊이를 더하면서 정말 많은 아이디어들이 나와서 관전(?) 하는 입장에서는 많은 공부가 되었습니다.

소스 공개에 대한 논쟁

이 당시 smpd 소스가 오픈되어 있지 않아서 기술적으로 어떤 방식으로 음질 향상을 꾀했는지 다른 사람이 정확히 알기가 어려웠습니다. 논쟁의 중심도 입증할 측정 방식이나 측정기는 일반 개인 DIYER에서 감당할 수 있는 수준을 넘어가는 부분이 있으니 소스를 보지 않는 이상 기술적으로 어떻게 접근했는 알 수 있는 방법이 없었던 것입니다.

예를 들어서 어떤 진공관 앰프를 누가 만들었는데 음질이 기가 막히다고 합니다. 주변 사람들이 음질이 좋다고 합니다. 다른 엔지니어들이 어떻게 음질을 개선했는지 질문을 합니다. 이런 경우에 가장 간단히 설명할 수 있는 방법은 회로도를 보여주면 됩니다. 엔지니어의 언어는 회로도지 설명이 아닙니다. 마찬가지로 소프트웨어도 소스를 보면 이를 알 수 있습니다.

물론 개발자가 소스 오픈을 거부할 수도 있습니다. 앰프 회로도 공개를 거부할 수 있습니다. 그렇지만 소프트웨어계에는 GPL (GNU General Public License) 라는 것이 있습니다. 리눅스 커널을 포함한 많은 소프트웨어들이 GPL 을 따릅니다. MoOde, Volumio 등도 GPL 을 따릅니다.

GPL은 자유 소프트웨어 재단에서 만든 소프트웨어 라이선스로 내가 만약 어떤 소프트웨어를 개발했는데 이를 GPL 라이선스를 따른다고 규정을 하면 누군가 내가 만든 소프트웨어 코드를 사용하거나 이용해서 소프트웨어를 만든다면 그 소프트웨어 또한 GPL을 따라야 합니다. 즉, 소스를 공개해야 합니다. 이게 싫으면 100% 본인이 모든 기능을 구현하고 GPL을 따르는 소프트웨어 모듈을 사용하지 않으면 됩니다.

앰프 회로에 GPL 라이선스가 사용되었다고 하면 반드시 공개와 출처를 밝혀야 합니다. 만약에 내가 순수 100% 독창적인 앰프를 개발했고 이 앰프를 나 혼자 사용한다면 공개할 이유가 없지만 이 앰프를 대중에 판매(배포)를 한다고 하면 GPL 라이선스가 적용된 원전 회로의 출처를 반드시 사용자에게 밝혀야 합니다.

예를 들어서 앰만사의 진공관 앰프 회로를 GPL 라이선스를 따른다고 하면 이 앰프를 개인적으로 제작한다면 문제가 안되겠지만 이 회로를 약간 변경해서 앰프를 제작해서 다른 사람들에게 배포나 판매를 한다면 반드시 원전 회로의 출처를 밝혀야 합니다. 그렇지 않으면 소송을 당할 수 있습니다.

어쨋든 법적인 부분은 저도 전문이 아니라서…..복잡합니다.

이야기가 잠깐 다른쪽으로 샛는데 어쨋든 smpd의 중요 부분의 소스가 공개가 안된 상황이라서 논쟁이 GPL 까지 번졌습니다.

파파리우스가 소스를 공개하지 않았던 이유를 솔직히 고백(?)하는 부분에서 많이 공감되는 부분이 있었습니다. 대부분 회로도 공개나 소프트웨어 소스 공개를 하지 않는 이유 중에 하나는 상업적인 부분이 크다고 생각합니다. 그렇지만 파파리우스씨의 경우에는 본인이 만든 아름답지 못한 소스를 공개하는 것에 대한 두려움(?)이 컷던것 같습니다. 본인의 개발한 산출물을 공유는 OK 라고 합니다.

제 생각에는 소스를 보고 파파리우스씨의 아이디어를 이해할 사람들은 많지 않고 코드 문법 같은 시시콜콜한 것으로 태클을 많이 걸 것 같아서 공개를 꺼린것 같습니다. diyaudio.com 에서의 논쟁으로 본인의 아이디어를 이해할 사람들이 있다는 것을 확신한 것 같습니다.

유럽 개발자 이야기는 대부분의 사람들은 공개된 소스코드의 코딩이 아름다운지에는 크게 관심이 없고 개발자의 아이디어에 관심이 많다고 하네요. 이 아이디어를 공유하는 것이 가장 큰 거라고 합니다…..

파파리우스씨가 github 에 소스를 공개하기로 이 이슈는 일단락되었습니다.

측정에 대한 논쟁

이 이미지는 RIGOL DS1054Z로 측정한 것이라고 합니다. 측정하는 사람은 DAC HAT의 설계자이자 개발자입니다.

오실로스코프를 사용한 프로빙은 그 자체로 고급 기술이지만 나는 그의 기술을 전적으로 믿습니다.​

I2S signal Yellow: LRCK, Red: DATA, Blue: BCK

volumio2 Hifiberry-dac driver (DAC slave) 5us

smpd i2s measure 1

volumio2 Hifiberry-dac driver (DAC slave) 10ns

smpd i2s measure 2

symphonic-mpd v0.8.x hifiberry-dac driver (DAC slave) 10ns

smpd i2s measure 3

symphonic-mpd v0.8.x hifiberry-dac driver (DAC master) 10ns

smpd i2s measure 4

diyAudio Symphonic MPD

이에 대한 나의 견해를 듣기 전에 몇 가지 가정이 있습니다.

Compute Module 데이터시트에 따르면 Raspberry Pi의 발진기는 20피코초의 주기 주기 지터를 가지며 PLL에서 생성된 클록의 경우 주기 주기 지터는 48피코초 수준입니다.

Raspberry Pi 발진기 (Pi3에서는 19.2MHz, Pi4에서는 54MHz). 5개의 PLL이 주변에 매달려 있어 다양한 주변 장치에 시계를 제공합니다.

5가지 유형의 PLL은 각각 다음과 같이 사용됩니다.

  • PLLA … RPi3에서는 사용되지 않았고 RPi4에서는 사용되었습니다.
  • PLLB … CPU 클럭에만 사용
  • PLLC … GPU, SDRAM 등의 클럭에 사용됩니다.
  • PLLD … I2S(기본적으로 500MHz)와 같은 주변 장치에 사용
  • PLLH … HDMI와 같은 주변 장치에 사용

I2S에서 사용하는 클럭은 PLLD (500MHz)를 쪼개서 얻은 것이다.

예를 들어, 44.1KHz 음원에 대해 BCLK 2,822,400Hz를 생성하려면 RPi3를 사용하여 2,808,988Hz와 2,824,858Hz의 두 가지 주파수를 특정 비율로 결합하여 2,822,400Hz의 BCLK를 생성합니다.

단순히 MASH를 끄면 RPi3는 2,824,858Hz의 BCLK를 생성하고 이는 피치의 변화와 재생 속도의 변화를 일으킵니다. (절대 음높이가 없는 분들은 음높이의 변화는 음악을 들으면서 익숙해지는 것일 뿐이고 템포의 변화에 ​​민감해 대부분의 사람들이 받아들이기 힘듭니다.)

개발 과정에서 내가 예리하게 인식하고 있는 두 가지가 있습니다.

첫 번째는 하드웨어가 제대로 작동하려면 의도한 용도에 맞게 올바르게 구성해야 한다는 것입니다. Raspberry Pi는 다목적 하드웨어이며 많은 기본 설정이 오디오 재생 품질을 고려하지 않습니다. 특정 응용 프로그램에 대한 하드웨어를 적절하게 초기화하면 PLL에서 MASH로 인해 발생하는 BCLK 흔들림(지터 유형)을 쉽게 대처할 수 있습니다.

둘째, 더 중요한 것은 오실로스코프 관찰에 차이가 거의 또는 전혀 없더라도 DAC 마스터와 DAC 슬레이브 사이에 여전히 상당한 음질 차이가 있다는 것입니다. 또한 소프트웨어 최적화를 통해 DAC 마스터와 DAC 슬레이브의 음질 차이를 역전시킬 수 있음을 경험했습니다. 실제로 소프트웨어 최적화가 적용된 DAC 슬레이브의 음질은 소프트웨어 최적화가 없는 DAC 마스터의 음질보다 높습니다.

USB 오디오의 경우 이러한 눈에 띄는 차이가 발생할 가능성은 거의 없다고 생각합니다. I2S 신호를 DAC 칩에 제공하는 것이 USB 리시버의 역할이며, 리시버 설계가 음질에 주는 무게는 적지 않다.

이것이 단일 보드 컴퓨터에서 I2S로 작업하는 것이 흥미로운 이유입니다.


안녕하세요 파팔리우스님

SMPD를 이용한 음질 측정에 대한 제 의견입니다.

측정은 음질에 차이가 있는 이유에 집중해야 합니다. 음질과 측정 간의 상관 관계에 대해 완전히 입증된 것은 없습니다. 따라서 들을 때 음질에 차이가 있다면 측정을 통해 왜 차이가 나는지 알아내야 합니다!

파팔리우스는 측정 결과에 대해 지나치게 걱정할 필요는 없다고 생각합니다. 상업적 목적으로 SMPD를 게시하지 않습니다. 그러므로 당신은 음질에 대해서는 책임을 지지 않습니다. 또한 당신은 다음과 같이 말합니다.

바닥글 및 게시물에 명확하게 명시되어 있습니다.

SMPD와 Volumio의 음질 차이는 일본 국민이라면 누구나 인정하는 부분입니다. 따라서 음질의 차이가 발생하는 이유를 명확히 하는 형태로 측정해야 합니다.

하드웨어와 소프트웨어의 음질차이가 왜 생기는지 궁금증을 푸는 단순한 접근이 정답이지, 측정 결과로 특정 소프트웨어나 특정 하드웨어를 우월하게 만들거나 열등하게 만드는 것이 아니다.

완고한 안락의자 이론가의 말을 들을 필요는 없습니다.

행운을 빌어요.

일본 카게무샤에서


​측정에 대한 부분은 계속 논의가 되었고 장비 섭외등의 이슈로 추가 결과는 올라오지 않은 상태입니다…

SMPD 의 클럭 재설정

글타래를 읽다가 드디어 궁금했던 SMPD의 핵심(?) 을 발견했습니다.


안녕하세요

dt-blob.bin을 사용하여 초기 PLL 값을 설정합니다.

다음을 dt-blob.dts로 저장합니다. dtc 명령으로 dts 파일을 빌드하고 dt-blob.bin을 /boot에 넣습니다.

// build command:
//   dtc -q -I dts -O dtb -o dt-blob.bin dt-blob.dts
//
// osc  : 54MHz
// PLLA : NONE
// PLLB : arm_freq
// PLLC : core_freq
// PLLD : BCLK
// PLLH : HDMI etc

/dts-v1/;

/ {
   videocore {
      clock_routing {
        vco@PLLA { freq =  <638976000>; };
        vco@PLLD { freq =  <632217600>; };
        chan@APER  { div = <1>; };
        chan@DPER  { div = <1>; };
        clock@GPCLK0 {
                pll = "PLLA";
                chan = "APER";
        };
      }; // clock routing
      clock_setup {
        clock@GPCLK0 { freq = <638976000>; };
      };
   };
};

clk-bcm2835.c의 diff는 다음과 같습니다. 참고하세요. [링크] (https://raw.githubusercontent.com/ra…/clk-bcm2835.c)

656a657,659
>       printk("clk-bcm2835: (%s) rate=%lu\n",
>               clk_hw_get_name(hw), clk_hw_get_rate(&pll->hw));
> 
995d997
< 
1224a1227,1253
> static unsigned long decimal_frac(u32 v) {
>       int i;
>       unsigned long frac=0;
>       unsigned int mask = (int)1 << (sizeof(v) * 8 - 1);
>       unsigned long arr[12];
>       arr[0]=500000000000;
>       arr[1]=250000000000;
>       arr[2]=125000000000;
>       arr[3]=62500000000;
>       arr[4]=31250000000;
>       arr[5]=15625000000;
>       arr[6]=7812500000;
>       arr[7]=3906250000;
>       arr[8]=1953125000;
>       arr[9]=976562500;
>       arr[10]=488281250;
>       arr[11]=244140625;
> 
>       mask >>= 20;
>       for (i=0; i<12; i++) {
>               if (mask & v)
>                       frac += arr[i];
>               mask >>= 1;
>       }
>       return frac;
> }
> 
1258a1288,1289
>               printk("clk-bcm2835:debug req=%lu div=%u.%012lu %s=%lu min=%lu avg=%lu\n",
>                       req->rate, div>>12, decimal_frac(div), clk_hw_get_name(parent), prate, rate, avgrate);
1274a1306,1308
>       printk("clk-bcm2835:%s %s=%ld min=%ld avg=%ld\n",
>               clk_hw_get_name(hw), clk_hw_get_name(best_parent), best_prate, best_rate, best_avgrate);
> 
1611d1644
<       "xosc",
1614a1648
>       "plla_per",
1732a1767,1776
>       [BCM2835_PLLA_PER]      = REGISTER_PLL_DIV(
>               SOC_ALL,
>               .name = "plla_per",
>               .source_pll = "plla",
>               .cm_reg = CM_PLLA,
>               .a2w_reg = A2W_PLLA_PER,
>               .load_mask = CM_PLLA_LOADPER,
>               .hold_mask = CM_PLLA_HOLDPER,
>               .fixed_divider = 1,
>               .flags = CLK_SET_RATE_PARENT),
1753d1796
< 
2135,2136c2178,2179
<               .is_mash_clock = true,
<               .low_jitter = true,
---
>               .is_mash_clock = false,
>               .low_jitter = false,

printk 및 decimal_frac(u32 v)는 디버깅용이므로 제거할 수 있습니다.

decimal_frac(u32 v)가 무엇을 하는지 잘 기억나지 않습니다. 2년 전에 추가한 디버깅 코드입니다.

diyAudio Symphonic MPD


papalius: 힌트 주셔서 감사합니다. 나는 클럭 재정의를 정말 좋아합니다. 사용하지 않은 PLLA를 재사용하여 각각 44.1 및 48kHz 속도 제품군의 정수배인 두 개의 클록을 제공합니다. 그리고 best_parent 시계가 자동으로 선택되는 위치를 보여주셔서 감사합니다 (즉, 디버그를 추가한 방법).

따라서 정수 다중 클럭은 모든 표준 샘플 속도에 대해 분수 분할기와 MASH를 사용하지 않으며 주어진 샘플 속도에 따라 자동으로 전환됩니다. RPi의 내장 하드웨어/소프트웨어 리소스를 아주 잘 사용합니다.

IMO는 일부 업스트림 구성에 대해 고려해야 할 변경 사항이며 기껏해야 /boot/config.txt의 일부 장치 트리 식별자(“오디오 파일”)에 의해 선택됩니다.

아마도 설정은 GPxCLK 핀 중 하나를 통해 선택적 DAC/ADC 마스터클록을 제공할 수 있으며, PLLA와 PLLD + 각 샘플 속도 및 특정 DAC 칩(예: 256fs, 128fs 등)에 해당하는 분배기 간에 자동으로 전환됩니다.

RPi의 PLL 클럭은 특별하지 않지만(PLLd GPCLK에 대한 데이터시트에 명시된 최대 rms 지터는 48ps임) 많은 SPDIF 수신기가 PLL 복구 클럭으로 출력하는 것보다 낫습니다. IMO는 듣기 목적으로 완벽하게 OK입니다.


느낀점

이외에도 많은 내용들이 있지만 제 지식 범위를 넘어가는 부분이 대부분입니다.^^

PC도 그렇고 라즈베리파이, 의료 장비, 네트웍 장비, CDP 들과 같은 디지털 기기들은 클럭을 이용합니다. 단지 청음 후에 원리가 궁금하던 차에 자료를 찾아 봤습니다.

오디오 클럭은 44.1Khz, 48Khz 의 배수를 사용하기 때문에 지터(오류) 문제 등을 최소화하기 위해서 DAC에 클럭을 내장하는 방식을 사용하기도 하고 (이런 DAC 를 Master 라고 부름) 라즈베리파이의 PLL을 의존하는 Slave DAC와 같은 방식이 있습니다.

smpd 는 i2s DAC의 성능개선을 위한 것입니다.

고가의 DAC의 경우 고급 DDC에 내장된 클럭을 이용하기 때문에 그냥 프로급 DAC 와 고급 클럭과 회로가 내장된 DDC 를 구매하면 되지 뭐하러 이런 삽질을 하냐라고 할 수도 있습니다.

그렇지만 PLL에 의존하는 Slave DAC (상당히 많은 DAC가 이 방식임) 의 문제를 개선할 필요가 없다는 의미는 아닌것 같습니다. 이것도 Audiophile DIYER 라면 큰 의미가 있는 작업이라고 생각합니다.

SMPD 카테고리 내 다른 글 보러가기

댓글 남기기