-Y8950のADPCMについて [[Y8950アプリケーションマニュアル>http://d4.princess.ne.jp/msx/datas/Y8950/Y8950AP.html]] Y8950はFM音源に加えて1チャンネルのADPCM録音再生機能を持っている。 FM音源とADPCM部分は別で、ADPCMの機能は、音声のサンプリング(録音)と再生、 可変速度再生。(この機能で音階を付けることは出来る) またその際の音声データはY8950が管理するメモリに記録される。 ADPCMのチャンネル数は1チャンネルのみ。 ADPCMデータの再生は、メモリ上の再生開始アドレスを指定し、サンプリング周波数を指定し 再生コマンドを実行する。 FM音源部分の信号はY8950外部のD/Aコンバータにデータをシリアル形式で出力する。 この時のフォーマットは13bitで、10bitデータ、3bit指数という形式で出力される。 このシリアルデータはY8950のMO端子から同期クロックで出力され、外付けDAC(YM3014) で音が再生される。 ADPCM関連のデータはY8950内部のDACが使われる。 FM音源とADPCMは、二つの信号がオペアンプを経由してミキシングされ音声出力される。 音声入力はマイク端子からアンプを経由してY8950内部のADCへ接続される。音声の サンプリング時はY8950内部のADCが利用される。 外部I/OとしてY8950は4bitのGPIOを持つほか、8bitバスの鍵盤用データI/Oを持っている。 この鍵盤用8bitI/Oはレジスタで直接アクセスすることができる。 そのほか割り込み機能を持ち、幾つかのサンプリングのタイミングに割り込みを発生させる ことができる。 またY8950は内部に2つのタイマー機能を持っており、ADPCMのサンプリングの際のタイミングは 内部タイマーを使う事が可能。 Y8950のADPCMの資料に記載されている、音声分析、音声合成という表現は 現代的に言えば問題がある。 ADPCMの記述は現代的にすれば、音声分析、音声合成とはY8950のハードウエアによる ADPCMのエンコード・デコードであり、実際には録音、再生のこと。 当時はエンコード・デコードは音声分析、合成と呼んでいたようだが、この表現は 現在使わない。 ADPCMのハードウエアエンコード・デコードはサンプリングし録音されたデータに対して、 8bit分解能のデータ絶対量をそのまま記録するPCMではなく、差分情報を使い音声を 符号化する。 この方法では約1/2程度の情報量で、PCMと同じ程度品質の音がエンコード・デコードできる。 ADPCM方式は通常の音声信号PCMデータに対し現在のサンプルデータと一つ前のサンプルデータを 比較し、差分情報を得てADPCMへエンコードする。 デコードの際は逆に時間的な変化量や差分情報から、PCMの波形データをデコードし、 D/A出力して音を再生する。 ADPCMは現代的なMP3と比較してデータ圧縮比は小さいが、ハードウエアエンコード・デコードが MP3などと比べて簡単で比較的昔から使われてきた。 エンコード・デコード時の遅延も少ない事から電話の圧縮方式として使われている。 ADPCMの良くある誤解の一つにはサンプリング時に予測モデルを使うという話もあるが、 実際のADPCMは現在のサンプリングデータと、1サンプル過去のデータをつき合わせて 差分(信号の傾き)を得ているのであって、予測によって音声信号を得ている訳ではない。 FM音源についても現在では複合正弦波音声合成方式とはあまり呼ばない。 -レジスタについて Y8950はADPCM関連のレジスタと、FM音源のレジスタがある。 FM音源のオペレータは2オペレータなので音質的にはYM2413とあまり違いはない。 異なる点はFM音源のレジスタ構成がYM2413と違いプリセットの音色がないのでFM音源を発音する際に あらかじめ音パラメータを初期化として設定しなければならないこと。 そしてKey-ON/OFFレジスタに一旦アクセスしないとチャンネルが有効とならず、音が鳴らない。 チャンネルをアクティブにするにはKey-ON/OFFに一回アクセスする必要があるらしい。 Y8950の音色データを設定するレジスタセットは、YM2413と大きく異なり同じではない。 音源チャンネルと[[スロット]]との関係が違うので音色データの設定は注意が必要。 (YM2413の資料にあるチャンネルとスロットの図は実際のレジスタパラメータとは関係がないが、 Y8950の場合は資料中の各チャンネルと音色パラメータとスロットの関係はレジスタ設定に必須 なので理解しておく必要がある) -Cによるプログラミング レジスタアクセスは0xC0にy8950のレジスタ番号を、0xC1にデータを書き込む。 //R#0F WRITE Y8950 REGISTER outp(0xC0,0xF); outp(0xC1,255); ステータスリードとデータリードは0xC0を読むとステータス取得、0xC1はレジスタデータ。 //Y8950 READ STATUS a=inp(0xC0); 関数としては以下のようなもので良いだろう。 確認していないが別途ウエイトタイミングは必要かもしれない。 void y8950(unsigned char reg, unsigned char data){ outp(0xC0,reg); outp(0xC1,data); } 以下の例はY8950のADPCMを再生する。メモリアクセス機能を使いY8950が管理するメモリ領域に データを適当に書き込み、メモリ上のADPCMデータを再生する。 初めにデータ作成のコードを示す。 void main(void){ int i; //MEMORY ACCESS MODE y8950(0x7,0x60); //SET ADPCM START ADDRESS y8950(0x9,0); y8950(0xa,0); //END ADDRESS y8950(0xb,255); y8950(0xc,0); //WRITE DATA for(i=0; i<255; i++){ y8950(0xf,i); } //RESET MODE y8950(0x7,0); } メモリ上のデータを再生する場合の例。 //1,モード設定(MEMDATA) //SET MODE y8950(0x7,0x20); //2,再生データアドレス範囲指定 //SET ADPCMPLAY START ADDRESS y8950(0x9,0); y8950(0xa,0); //END ADDRESS y8950(0xb,255); y8950(0xc,0); //3,サンプリング周波数設定 //SET ADPCM SAMPLING FREQUENCY y8950(0x10,0xf0); y8950(0x11,0x28); //4,ADCボリューム設定 //SET VOLUME y8950(0x12,0xff); //5,R#7のSTARTで再生 //PLAY y8950(0x7,0x80); //REPEAT SOUND PLAY //y8950(0x7,0x90); サンプリングデータはADPCMであり、再生開始はR#7のSTARTビットで制御する。 R#7のREPEATビットを1にすると、繰り返し再生を行なう。 再生中にサンプリング周波数を変えることも可能で、可変速度再生が可能。 これらはADPCMの音階を与える際にも利用可能。 サンプリング周波数の指定はR#10,R#11の2byteを用いて指定する。 資料にも書かれているが、ADPCM初期設定時には割り込みフラグ関係をダミーリードする とされており、ADC開始もダミーリードライトをすることで開始が始まると書かれている。 同様なことはFM音源についても言える。初期化動作は特殊なので注意が必要かもしれない。 初期化はリセット直後の最初の一回だけR#4,0x80を設定すると良いかもしれない。 //Y8950 ADPCM INIT y8950(0x4,0x80);