PCM179X??????の巻き 2014.5.17

こんなコメントをいただきました。


いままでPCM179Xシリーズで使用したICはPCM1794(24Bit),PCM1795(32Bit)のみですが、TI社から
でているPCM197×シリーズは色々とあります。
すこし、下記に現在リリースされているICについてまとめてみました。

型番 分解能 D-RANGE
(dB)
ピン配置 制御 価格
(DIGIKEY)
備考
PCM1791 24 113 SW可 731円 DSD入力可
PCM1792 24 132 SW可 1549円 DSD入力可

PCM1794の
S/W制御版?
PCM1793 24 113 H/W 529円
(141個以上)
PCM1791の
HW制御版
PCM1794 24 132 H/W 2017円 DSD不可
PCM1795 32 123 S/W可 918円 DSD入力可

唯一の32Bit
PC1796 24 123 S/W可 853円 DSD入力可

PCM1798の
S/W制御版
PCM1798 24 123 H/W 853円 DSD不可

これだけだとよくわかりませんが、大きくは4つのグループに分かれます。
Dレンジでグループとビット数で分かれますが、それぞれ113dBあるので性能的には問題ありません。
ちなみにDレンジがことなるのは、チップ内部のディジタルフィルターの次数の違いでしょう。
当然次数が多くなると、素子数が増えますからチップの製造コストが高くなります。

グループ 特徴 S/W制御 H/W制御 備考
1  24Bit Dレンジ 113dB PCM1791 PCM1793
24Bit Dレンジ 123dB  PCM1796 PCM1798
3  24Bit Dレンジ 132dB PCM1792 PCM1794
4  32Bit Dレンジ 123dB PCM1795

シャープロールオフにおける周波数特性

型式 PCM1791 PCM1792
Dレンジ 113dB 132dB
DF
周波数
特性


共通基板? 2014.8.23

基本的にPCM1792,PCM1796,PCM1795はピンコンパチでかつ、コマンドコンパチでもあるので
共通基板としてかけそうです。
SPDIFI、PCM、DSD入力対応です。


こんな感じ?

基板が到着しました。 2014.9.4

検討中のADC4222と同じく、基板ができあがりました。

部品面です。


半田面です。ディジタルとアナログのGNDはICの直下で接続しています。

まずは電源部分の組み立てをおこなって、通電して電圧を確認しておきます。
電源でミスれば部品が全部お釈迦になりかねませんからね。
電源はオペアンプアナログ、DACアナログ、DACディジタルの分離給電が可能ですが、
オペアンプアナログのみの給電ですべてまかなうことも可能です。
オペアンプアナログ電源(15V)→7805(5V)DACアナログ→48M33(3.3V)DACディジタル
で電圧を落としていきます。


電源部分の組み立てと動作の確認です。

どんどん組み立てましょう!

一気に組み立てましょう。
といっても、平日は時間があまりないので作業は亀の歩みです。
休日は休日で出先が多いので、こちらもほとんど時間がとれないので、さらに亀が遅くなっちゃいます(笑)。


まずはICソケット。


表面実装部品をとりつけていきましょう!


今回はPCM1796を使用してみました。

どんどん作りましょう。 2014.9.10
抵抗やコンデンサをどんどん搭載していきましょう。

ほぼ完成です。

今回のオペアンプにはシングルのOPA134Aを使いました。このオペアンプは安価ですが音がいいので気に入っています。


今回はOPA134Aを使いました。


ついでにICも搭載して完成時の雰囲気を味わっています(笑)。

動作確認しましょう。 2014.9.11

PICに最小限のプログラムを書き込んで動作確認をしていきましょう。
CS8416,PCM1796ともI2Cで動作制御しているので、インターフェイスソフトは共通でつかえるので、
プログラムは短くなります。ただ、最終的に電子ボリュームや、入力切替などを組み込むと、それなりに
長くなってしますますが・・・・。たぶんPIC16F819では2kワードのプログラム容量なので、ほぼ一杯に
なってしまうでしょう。

まずはSPDIFモード!

入力にSPDIFから入力してCS8416を使って変換してPC1796を駆動するモードです。
一番シンプルな動作モードでしょう。

SPDIFモードでの動作確認です。

まずは問題なく動くことを確認しました。

波形が出るとホットします。

次はPCMモードで!

PCM信号(DATA,LRCK.、BCK、SCK)の3線制御の出力ソースとしてはFFASRCを用いました。
これを使って44.1〜192kHzでの動作を確認しました。これも問題なく動作を確認できました。

PCMモードでの動作確認の様子です。

最後はDSDモードで!

DSDの出力ソースには、先日試作したADC4222のAD変換ボードを使用しました。
これであれば1本のフラットケーブルで接続できます。

DSD入力での動作確認です。


こちらも問題なく出力が確認できました。

IV抵抗を調整 2014.9.15

オシロの画面をみて少し出力電圧が小さいようです。データシートの回路図の値は820Ωですが、
手元にあった150Ωをつかったのが原因です。ということで、IV抵抗を再調整。
このDACではPCM179Xをパラ使いするので、IV抵抗値は半分の410Ωになりますが、
もっとも近い値である390Ωにいれかえました。

PCM、SPDIFでの出力は丁度いいくらい。
I
V抵抗を変更して、再度電源ONです。振幅は2.7V程度(5.4Vpp)なのでほぼ2Vrmsになるので
オーディオ機器の出力としてはピッタシです。
なお、接続はADC4222のPCM出力を接続しています。

振幅2.7V程度ですからほぼ2Vrmsです。

DSD出力は少し低め。
PCM、SPDIFの入力に対してDSD出力は少し低めです。
約半分程度の出力電圧になります。接続はADC4222のDSD出力を接続しています。
 ちょうど半分程度の出力になるので、ソフトの問題、ハードの接続の問題等がないか
念のため調べてみましたが、問題ないようでした(パターンを切断してPCM1796からの
出力を個別に調べました)。

DSD出力は少し低め。

 このようにDSD出力が低くなる、おそらく次のようなところだとおもいます。PCMは文字通り
パルスコード変調であり、ゼロならびに最大値がはっきり数値として定義できますので、最大値の
入力をすることが簡単です。
 それに対してDSDはPDM、すなわちパルス密度変調です。信号レベルをパルス密度で定義するので、
たとえば最大値をHighレベルオンリー、ゼロをLowレベルオンリーとすることができますが、
最大値だけの信号、あるいはゼロレベルだけの信号を送ることはできません(変調信号として成り立たない)。
したがって、どうしても最大値あるいはゼロで定義された振幅の内側での範囲でしか動作することが
できないのだろうとおもいます。そのため、PCM信号で得られる信号振幅の半分程度で動作するのが
自然なところなんでしょう。

試聴してみよう!

今回の試聴のソースは木住野佳子さんのHOPEを引っ張ってきました。
私のお気に入りのアーティストです。この人のピアノを聞いているととても癒されます。
基本はJAZZですので、ペースなどの低音やハイハットの高音も気持ちよくて、試聴にはとても相性がいいです。
でも、やっぱりこの人の弾くピアノが心をうちますね。

試聴に用いたCD

まずはDAC単体

接続は
CDP→(同軸)→DAC179X-2.1→EVC1159(電子ボリューム)→ヘッドホン(オーディオテクニカ ATH-W10VTG)
という構成です。
まず、最初に音が出たときは、「やっぱりこの人の音楽はいいな〜」という感じです。
まったく試聴にはなってないですね(笑)。
じっくり音楽を聞き入ってしまいます。まず雑味はまったくなく、クリアな音です。
PCM1794によく似ているかな?PCM1794の特徴はダイナミックなヤンチャ坊主の印象ですが、
PCM1796はやや落ち着いた音の印象です。でも、これってソースの雰囲気だったりします(笑)。
オーディオDACとしていい感じです。


まずはSPDIF入力で試聴です。

ちょっとややこしい!

こんどは試作中のADC4222の音質チェックを兼ねて下記の接続にしています。

DAC(PCM61P)→(アナログ)→ADC4222→(PCMorDSD)→DAC179X-2.1
→EVC1159(電子ボリューム)→ヘッドホン(オーディオテクニカ ATH-W10VTG)


です。ディジタル信号をアナログに変換したのち、再度ディジタルに変換してDAC179X-2.1でアナログに戻すという
変換が多い構成です。これで音質の劣化をみてみました。

試聴の時の装置の構成です。

まずはADC4222はPCM出力で。

まずADC4222とPCM179X-2.1とのインターフェイスはPCMとして試聴してみました。最初に音が出たときは、
ほんとにDAC直接で聞いた場合と違いがわからないです。これは、以前にオフミでPCM1804を使ったADCを
介した場合とそうでない場合を聞き比べた場合、差がわからなかったこともありますが、さらに性能の上がった
PCM4222ですから、ますます違いが判らないのでしょう。いづれにしてもPCM4222は十分な性能があるようです。

次はADC4222はDSD出力で。
つぎはADC4222とPCM179X-2.1とのインターフェイスはDSDとして試聴してみました。DSD入力の場合は少し
レベルが下がるので、すこし元気が無いような気がしましたが、レベルを合わせると・・・・
「違いがわからない・・・」という感じです。ややDSDの方がやさしい感じがするかな?というのもDSDはより
アナログに近い信号なので、そうのような音調になるのかもしれません。でも、これって、完全に先入観の
塊ですが(笑)。

IV無しも作ってみました。 2014.9.15

IVアンプ以降を省略した基板も作ってみました。IV抵抗やアンプは外付けになりますが、好みに応じた回路が使用
できるのが特徴です。以前にリリースしたDAC1794-3.5に近い構成です。ただし、今回の基板ではSPDIF入力に加えて、
PCM、DSDの入力が可能なことが特徴です。
v
DAC179X-2.1 SHORTです。

動作チェックにはPCM1795をつかってみました。旧BB社からでているDACの中では唯一の32BitDACです。
さてさて、どんな音がするでしょうね。

この基板ではPCM1795(32Bit)を搭載してみました。



お出かけ用の写真です。

動作確認!

動作確認のためにはIVアンプを接続する必要がありますが、ここは簡単にパッシブIVとしました。
出力に75Ωの抵抗を挟み込みました。

パッシブIVで動作確認です。

まずはSPDIF入力での動作確認です。PICのプログラムについてはPCM1796との互換性を確認するために、
まったく同じモノを書き込んでいます。


SPDIFでの動作確認の様子。

問題なく動いているようです。出力振幅は約600mVあります。
75Ωですから、電流は約8mAです。PCM1795の出力電流は4mAppですから、
パラ接続なので8mAppですから、ピッタシです。


SPDIFでの動作確認をしました。

あわせてPCM入力での確認です。PCM出力はいつものFFASRCを用いています。

FFASRCとの接続でPCM入力も問題ないことを確認しました。

折角なので

急遽 Simple IV for DUAL OPAを組み立てて、接続してみました(定数は手持ちの関係で一部変更しています)。

IVアンプと接続して動作の確認です。


勿論、出力は得られました。

DSDの確認のためにADC4222を接続して接続しました。

DSDでの動作確認です。

やはりPCM1796と同じようにDSDでは出力は少し低くなるようです。


DSDでの出力を確認しました。

プログラムを作成しましょう! 2014.9.18

入力数も少ないので、プログラムは比較的短く書けます。それでもPIC16F819のROM(2kW)の62%を必要としました。
プログラムを組むことで、フィルターの変更も可能になります。下記はPCM1796を使用した場合の基板のフィルタによる
変化です。

 
 ディジタルフィルタ SHARP ROLL OFF               SLOW ROLL OFF

USB-AUDIOとも接続 2014.10.3

エレアトさんのUSB-AUDIOとも接続してDSDの再生を確認しておきました。

エレアトさんUSB-AUDIOとの接続です。


問題なく再生できました。


おまけ機能?

USB-AUDIOはPCMとDSDが同じライン上に出力されますが、USB-AUDIOのP6のPin6に
どちらの出力であるかの信号がでます。Pin6はHならDSD,LならPCMです。これをつかって
DAC1794-X2.1も自動切換えできる機能をおまけ機能でつけくわえました。
たぶん問題ないとはおもいますが・・・。

方法は、あらかじめ、基板のP11(SPD1)とP12(SPD0)をGND接続します。この状態で電源が立ち上がると
USB-AUDIOとの接続であると認識させます。基板のP9にはUSB-AUDIOのPin6(P6)を接続します。
この場合の動作モードは下表の通りです。SPDIF1の入力は使えません。

P9(DSD)
USB-AUDIOの
Pin6(P6)に接続
P10
(PCM)
P11
(SPD1)
P12
(SPD0)
入力選択
L(PCM) OPEN GND GND PCM
L(PCM) GND GND GND SPDIF0
H(DSD) OPEN GND GND DSD
H(DSD) GND GND GND SPDIF0

プログラムはこんな感じです。読めば動作モードがわかる(?)かもしれません。
人の書いたプログラムって癖があって読みにくいんですよね〜。

//
// DAC179X-2.1 for DUAL PCM1792/1795/1796
//
// (c)OKIRAKU AUDIO / 2014-Sep
//
// version 1.0 simple use
//         2.0 use with USB-AUDIO for electro-art 
//             USB-AUDIO connection Pin6 of P6 into DSD PORT in case of SPD1=SPD0=L
//

#include "16F819.H"
#device ADC=10
#fuses INTRC_IO,NOWDT,PROTECT, NOMCLR,NOBROWNOUT,NOLVP,PUT
#use delay(internal=8MHz)
#include "math.h"

#use fast_io(A)
#use fast_io(B)

// PCB PIN definition
//

// INPUT SELECT 
#define	IN_DSD		PIN_B0
#define	IN_PCM		PIN_B1
#define	IN_SPDIF1	PIN_B2
#define	IN_SPDIF0	PIN_B3

#define	NOCHANGE		(0)
#define	DSD_SELECT		(1)
#define	PCM_SELECT		(2)
#define	SPDIF0_SELECT	(3)
#define	SPDIF1_SELECT	(4)

// JUMPER SETTING
#define	JP3		PIN_B7
#define	JP4		PIN_B6
#define	JP5		PIN_B5

#define	NOFORMAT	(0)
#define	I2S			(1)
#define	LEFTJ		(2)
#define	RIGHTJ16	(3)
#define	RIGHTJ24	(4)

//	JP3,JP4 PCM FORMAT
//  	JP3=H JP4=H		I2S
//  	JP3=L JP4=H		LEFTJ
//  	JP3=H JP4=L		RRIGHJ16
//  	JP3=L JP4=L		RIGHTJ24
//

#define	SHARPROLL	(0)
#define	SLOWROLL	(1)

//	JP5 DIGITAL FILTER
//	JP5=H SHARP ROLL OFF
// 	JP5=L SLOW  ROLL OFF
//

// Internal connection define
//

#define	PCM_SEL		PIN_A3
#define	SPDIF_SEL	PIN_A4
#define	DSD_SEL		PIN_A2

#define	I2C_SCL		PIN_A6
#define	I2C_SDA		PIN_A7
#define	CS_RST		PIN_B4
#define	PCM_RST		PIN_A1

// I2C ADRS definition
#define	I2C_CS		0x20	// CS8416
#define	PCM_L		0x98	// PCM L channel
#define	PCM_R		0x9a	// PCM R channel

#include "i2c.c"

// E-VOL variables
int			UP_DOWN;		// E-VOL direction 1:UP 0:Down
int16		CurrentEvolAD;  	// 0 to 1023
int			CurrentATT;     	// 0 to 255

// A/D interface subroutines for PIC

int16 get_ad(){
	int1	done; int16	value;
	read_adc(ADC_START_ONLY); done = adc_done();
	while(!done) done=adc_done();
	value=read_adc(ADC_READ_ONLY); return(value); 
}

int16	get_ad16(int ch){
	int16	v; int i;
	set_adc_channel(ch);		// select Volume
	delay_us(50);
	v=0; for(i=0;i<16;i++) v+=get_ad();
	v= v >> 4;
	return(v);
}

TranslateVol(){
	int16	n;
	n=CurrentEvolAD;
	if(n<=4){CurrentATT = 14;return;}
	if(n<=102){n*=80;n/=78;n+=10; CurrentATT=(n&0xff);return;}
	if(n<=514){n/=5;n+=85; CurrentATT=(n&0xff);return;}
	 n-=515; n*=6; n/=45; n+=188; CurrentATT=(n&0xff);return;
}

int GetVolume(){
	int16	v,n; int8	i;

	v=get_ad16(0);
	if(v==CurrentEvolAD) return(0);
	if(UP_DOWN){	// UP MODE 
		if(v > CurrentEvolAD) CurrentEvolAD = v;
		else if((v+1) < CurrentEvolAD){ CurrentEvolAD = v; UP_DOWN = 0;}
	} else {		// DOWN MODE
		if(v < CurrentEvolAD) CurrentEvolAD = v;
		if(v > (CurrentEvolAD+1)){ CurrentEvolAD = v; UP_DOWN = 1;}
	}
	return(1);
}

//	CS8416 setting subroutines
void cs8416out(int ch,n) {i2c_dataout(I2C_CS,ch,n);}	// command out


void cs8416_init()		// initialize
{	int	i;
	cs8416out(0x00,0x00); cs8416out(0x01,0x00);
	cs8416out(0x02,0x0b); cs8416out(0x03,0xb0);
	cs8416out(0x04,0x98); cs8416out(0x05,0x88);	//Right justified 24bit
	cs8416out(0x06,0x7f);
}

void cs8416_sel(int ch)	// channel selection
{
	int	i,j,k;
	ch &= 7; j=ch; j= j << 3; j &= 0b00111000; j |= ch;
	k=i=i2c_datain(I2C_CS,0x04);
	i &= 0xc0; i |= j;
	if(k!=i) cs8416out(0x04,i); // run and input select
}


//	I/O PORT input/output definition
io_select()
{
	output_drive(I2C_SCL);	output_high(I2C_SCL); output_float(I2C_SDA);
	port_b_pullups(0xff);
	output_high(PCM_SEL);	output_drive(PCM_SEL);
	output_high(SPDIF_SEL);	output_drive(SPDIF_SEL);
	output_high(DSD_SEL);	output_drive(DSD_SEL);

	output_low(CS_RST);		output_drive(CS_RST);		// CS8416 RESET
	output_low(PCM_RST);	output_drive(PCM_RST);		// PCM179X RESET
	output_float(JP3);
	output_float(JP4);
	output_float(JP5);
	output_float(IN_DSD);
	output_float(IN_PCM);
	output_float(IN_SPDIF0);
	output_float(IN_SPDIF1);
	setup_adc(ADC_CLOCK_DIV_32); setup_adc_ports(AN0);		// ADC OPEN
}

//	status of Input select and jumper 

int	InputStatus()
{
	int	i;
	
	i=NOCHANGE;
	if(input(IN_DSD)==0) 	i=DSD_SELECT;
	if(input(IN_PCM)==0) 	i=PCM_SELECT;
	if(input(IN_SPDIF1)==0) i=SPDIF1_SELECT;
	if(input(IN_SPDIF0)==0) i=SPDIF0_SELECT;
	return(i);	
}

int	InputStatusUSB()
{
	int	i;
	
	i=NOCHANGE;
	if(input(IN_PCM)==0){
		if(input(IN_DSD)) 	i=DSD_SELECT;
		else i=PCM_SELECT;
	}
	else i=SPDIF0_SELECT;
	return(i);	
}

int FormatStatus()
{
	int	i,i3,i4;

	i3=input(JP3);
	i4=input(JP4);
	if(i3 		&& 	i4		) 	i=I2S;		// I2S
	if(i3==0 	&& 	i4		) 	i=LEFTJ;	// LJ
	if(i3	 	&& 	i4==0	) 	i=RIGHTJ16;	// RJ16
	if(i3==0 	&& 	i4==0	) 	i=RIGHTJ24;	// RJ24
	return(i);
}

int FilterStatus()

{
	int	i;
	if(input(JP5))	i=SHARPROLL;	// SHARP
	else i=SLOWROLL;
	return(i);
}

main()
{
	int	InputSelect;
	int	FilterSelect;
	int	FormatSelect;
	int	usbdac;

	int	i,j,k,f;
	
	io_select();			// IO initialize
	delay_ms(500);			// wait power up
	output_high(CS_RST);	// resset inactive
	output_high(PCM_RST);
	delay_ms(100);			// wait
	cs8416_init();			// cs8416 initialize
	UP_DOWN=1;
	CurrentEvolAD=0;
	CurrentATT=0;
	
	// initial settting
	// INPUT:SPDIF0, RJ24, SHARP ROLLOFF, VOL=0(MUTE) 
	output_high(DSD_SEL);
	output_high(PCM_SEL);
	output_low(SPDIF_SEL);
	delay_ms(20);
	cs8416_sel(0);					// default select ch.0
	i2c_dataout(PCM_L,18,0xa0);		// RJ24
	i2c_dataout(PCM_L,19,0x00);		// SHARP ROLL OFF
	i2c_dataout(PCM_L,20,0x08);		// PCM MONO L
	i2c_dataout(PCM_L,21,0x01);		// NORMAL RUN

	i2c_dataout(PCM_R,18,0xa0);		// RJ24
	i2c_dataout(PCM_R,19,0x00);		// SHARP ROLL OFF
	i2c_dataout(PCM_R,20,0x0c);		// PCM MONO R
	i2c_dataout(PCM_R,21,0x01);		// NORMAL RUN
	
	i2c_dataout(PCM_L,16,0);		// initial MUTE
	i2c_dataout(PCM_R,16,0);	
	i2c_dataout(PCM_L,17,0);
	i2c_dataout(PCM_R,17,0);
	
	InputSelect=SPDIF0_SELECT;
	FilterSelect=SHARPROLL;
	FormatSelect=RIGHTJ24;
	usbdac=0;

	if(input(IN_SPDIF0)==0 && input(IN_SPDIF1)==0) usbdac=1;	// ELECTRO-ART USB AUDIO ACTIVE

	while(1){
		if(usbdac) i=InputStatusUSB(); else i=InputStatus();
		if((i!=NOCHANGE) && i!=InputSelect){
			switch(i){
			case	DSD_SELECT:
				output_high(SPDIF_SEL);
				output_high(PCM_SEL);
				output_low(DSD_SEL);
				delay_ms(20);
				i2c_dataout(PCM_L,20,0x28);
				i2c_dataout(PCM_R,20,0x2c);
				InputSelect=i;
				break;
			case	PCM_SELECT:
				output_high(DSD_SEL);
				output_high(SPDIF_SEL);
				output_low(PCM_SEL);
				delay_ms(20);
				if(InputSelect==DSD_SELECT){
					i2c_dataout(PCM_L,20,0x08);
					i2c_dataout(PCM_R,20,0x0c);
				}
				InputSelect=i;
				break;
			case	SPDIF1_SELECT:
			case	SPDIF0_SELECT:
				output_high(DSD_SEL);
				output_high(PCM_SEL);
				output_low(SPDIF_SEL);
				delay_ms(20);
				if(InputSelect==DSD_SELECT){
					i2c_dataout(PCM_L,20,0x08);
					i2c_dataout(PCM_R,20,0x0c);
				}
				if(i==SPDIF0_SELECT) cs8416_sel(0); else cs8416_sel(1);
				InputSelect=i;
				f=0xa0;	// RJ24
				i2c_dataout(PCM_L,18,f);
				i2c_dataout(PCM_R,18,f);
				FormatSelect=RIGHTJ24;
				break;
			default:break;
			}
		}
		i=FormatStatus();
		if((i!=FormatSelect)&&(InputSelect==PCM_SELECT)){
			switch(i){
				case	I2S:		f=0xd0; break;	// I2S
				case	LEFTJ:		f=0xb0; break;	// LJ
				case	RIGHTJ16:	f=0x80; break;	// RJ16
				case	RIGHTJ24:	f=0xa0; break;	// RJ24
				default:break;
			}
			i2c_dataout(PCM_L,18,f);
			i2c_dataout(PCM_R,18,f);
			FormatSelect=i;
		}
		i=FilterStatus();
		if((i!=FilterSelect)&&(InputSelect!=DSD_SELECT)){
			if(i==SHARPROLL){
				i2c_dataout(PCM_L,19,0x00);
				i2c_dataout(PCM_R,19,0x00);
			}
			else {
				i2c_dataout(PCM_L,19,0x02);
				i2c_dataout(PCM_R,19,0x02);
			}
			FilterSelect=i;
		}

		i=GetVolume();
		if(i){
			i=CurrentATT;
			TranslateVol();
			if(i!=CurrentATT){
				i= CurrentATT;
				i2c_dataout(PCM_L,16,i);
				i2c_dataout(PCM_R,16,i);
				i2c_dataout(PCM_L,17,i);
				i2c_dataout(PCM_R,17,i);
			}
		}
	}
}
	


(つづく?)