void setAndPrintBypassOSF(){ // This is just a toggle function
if(bypassOSF==true){
bypassOSF=false;
<略>
lcd.setCursor(13,0);
lcd.write(0x5E); // Indicate oversampling is ON (^)
}
else {
まず、「^」が表示されているので、bypassOSFはfalse。
unsigned long sampleRate() {
if (SPDIFValid){
#ifdef USE80MHZ
DPLLNum*=80; // Calculate SR for SPDIF -80MHz part
DPLLNum/=4295; // Calculate SR for SDPIF -80MHz part
#endif
#ifdef USE100MHZ
DPLLNum*=20; // Calculate SR for SPDIF -100MHz part
DPLLNum/=859; // Calculate SR for SDPIF -100MHz part
#endif
} else { // Different calculation for SPDIF and I2S
#ifdef USE80MHZ
DPLLNum/=3436; // Calculate SR for I2S -80MHz part
#endif
#ifdef USE100MHZ
DPLLNum*=4; // Calculate SR for I2S -100MHz part
DPLLNum/=10995; // Calculate SR for I2S -100MHz part
#endif
}
if(bypassOSF) // When OSF is bypassed, the magnitude of DPLL is reduced by a factor of 64
DPLLNum*=64;
return DPLLNum;
}
ちゅーことで、最後の*64は行われていない。つまり、素のDPLLNumがリターンされてる。
素のDPLLNumの計算は…色々数値出てますが…
2^32 / 1M = 4294967296 / 1M = 4295 (小数点以下丸めこみ)
DP * 80 / 4295 = DP * 80MHz / 2^32
DP * 20 / 859 = DP * 100MHz / 2^32
( 859 * 5(100/20) = 4295 )
DP / 3436 = DP * 80MHz / 2^32 / 64
DP * 4 / 10995 = DP * 100MHz / 2^32 / 64
って計算。今回の値を計算すると…DPLLNUMの読み出し値は
39043*3436 = 134151748
となって、90.3MHzで再計算すると
134151748 * 90MHz / 2^32 / 64 = 134151748 * 90 / 4295 / 64 = 43923.375
ちなみに、
134151748 * 90MHz / 2^32 = 2811096 ( 実際は少し丸めこみあり )
なので、この値がDSDのサンプルレートに一番近い気がします。2.8MHzですしね…つまり、I2Sとはまた違ったサンプルレート演算が必要そう…少しHifiduinoのsampleRateの計算式を弄る必要がありそうです。
また、ぶれを試しに、39100と39000で計算すると
39100の場合 2815200
39000の場合 2808000
で、7kHzくらいのぶれになる。2.6%くらいか…なんだろなー
実機で再度測定してみっかー、100MHz台が測定できる周波数カウンタがほしくなりました(笑)とさ。
100MHzのカウンタで何桁表示させたいんでしょうか?
返信削除8桁以上なら自作もありかも。
http://www.geocities.jp/ja3npl/gps/counter_11dgt_v2.html
時間軸だけは自分で作っても信頼度の高い測定器が作れますから。
HifiduinoのページにI2Sアイソレーターの紹介が出てましたがハイエンドになるとアイソレーターは必需なのは古いBBの1702Super Audio DACでもI2Sに使ってますね。
http://www.tij.co.jp/jp/lit/an/jaja001/jaja001.pdf
HifiduinoならI2Cに入れるとマイコンのノイズの混入も減らせるでしょうね。
でもUSB由来のノイズだとUSBアイソレーター入れるのが一番効果ありそうです。 PCのノイズはマイコンの比ではありません。
気になってるのは、どこのせいで、SampleRateがふらついて表示されるんだろう、って処。
返信削除ソースを見る限り、ES9018のチップから「今のDPLL_NUM寄こせ」ってやって、その値を拾ってきて計算してるだけなので、このDPLL_NUMが何らかの要因によってぶれている。ES9018では絶対時間は持てないので、SCLKベースでカウントしてるとは思うんですが、クロックシンク動作させてるのに、なんでずれるんだろ?みたいな。
要するにSCLKでDPLL動かして、そこでロックした数をカウントしてるんだと思ってるんですが、これが大きくずれるってことは、クロックシンクでもどっかロックできてない可能性が…
一つの可能性としては、SCLKがそれなりにずれてるのかなぁ…と。で、SRの数値から逆算してSCLKを1%のずれで測定できればいいので、余裕をもって0.1%精度として100MHzに対して±100kHzで測定できれば…測定器側のクロックが安定させられれば、そのくらいの品はゴロゴロしてそうではありますが…
I2Sはアイソレーター噛ました接続なので、あまり心配してないんですが、I2Cは気になりますやねぇ…
PCは…まぁ、考えるまでもなく…orz なのでPCからの再生自体今は完全に諦めてます…あくまで実験用データ扱う用途とか…
手持ちのDG1022が200MHzまで6桁精度で使えるっぽい…ので、これ使ってみようかと思います。
返信削除SCLKが揺れてるのか、それとも別の要因か…
DPLL読出値が振れる原因が、中島千明さんの解説で判明しました。
返信削除DPLLはMCLK(マスタークロック)の周波数が0xFFFFFFFFに正規化される32bitのunsigned longの整数で、I2S, DSDの場合はDATA_CLKがカウントされます。たとえば、44.1kHz系だと90.3168MHzが0xFFFFFFFFとなり、DATA_CLKの2.8224Mzのカウント値は0x08000000となります。
同期といえども、少しはこのカウント数がぶれるので、その値は0x07FFFFFF~0x08000001などとなります。この値をI2Cでレジスタ28~31から読み出すわけですが、”同時”に4バイト分を読み出せずにひとつずつ少し時間を置きながら読み出します。その間に、各バイトが07にまたは08になったり、00またはFFになったり、01または00またはFFになったりします。
結局DPLLNumの値は、それらのシャッフルの結果が結合された値となり、正しい値を反映していないのです。
あー、納得です。やはりそんなところでしたか。I2Cのタイムラグの問題があるだろなぁ、と思っていたら…
返信削除というわけで、周波数測定は見送ります…子供寝せたらやろうかと思ってた所だったのでw
細かい値を表示してもしょうがないので、スレッショルド値決めて、その値に近かったらその値を表示する、等が精神衛生上はいいんでしょうねぇ…
サンプルレートがふらつくとしたら
返信削除ソース側の揺れではないのでしょうか?
ES9018のDPLLがlowestでロックしない問題が一時話題になってましたがいくら受け側で対策してもソース側のクロックの揺れは止められません。
CDPやDVDのVCXOのクロックは結構いいかげんです。
自分で100円ショップのステンレス保温マグでOCXOを作りましたがオリジナルより3桁くらい安定度が上がりました。
秋月で売っているサーモスイッチのICを使ったダブルオーブンです。
ヒーターはクリスタル直巻きを半田こてのヒーターで、ダイカストケースの外側(マグの内側)を電気毛布のシリコンヒーターの抵抗値を低電圧で使える長さに。
うまくいったら発泡ウレタンのスプレーで断熱するともっと安定します。
表示が揺れるのはレジスタを読み込むタイミングが合っていないからでは?
レジスタのデータをラッチしてから読まないとカウント途中では表示が正しくない可能性もあるのでは?
> rtm_iino さん
返信削除まさしくレジスタ4つでDPLL_NUMが構成されていて、その読み出しタイミングの問題、のようです。ラッチしようにも、I2Cでレジスタを読み出すタイムラグがあるので、どーにもならなさそうw
ソース側のクロックは、実はDAC側のクロックと同期させています(システムにクロックが1つ(44.1kHz系で1つ、48kHz系で1つ)しかない)。ソース側の再生用クロックを逓倍(4倍ですね、今は)してそのままES9018のMCLKに突っ込むという。なので、Lowestでもロックが外れる筈がなくて…でもなんでゆれるんだろ?って所が疑問の最初の所でした。
クロック1つなので、そのクロックが安定しなくても、結局それぞれその安定しないクロックに同期しちゃうのではずれようがないと…相対的な時間しか判別できませんし…