超暇人MSX

MSXと語り合える日

MSXに口をつける!

文字通り 「MSXに喋らせる」 、すなわち、MSXで音声再生する方法は色々と有りますが、ここではMSX1本体のみを使って出来る方法(、ただし、何らかの記録メディアは必須です。ここではフロッピーディスクを使っています) について書いてみます。ただし、私は物理も数学も分からないので、全て理解して書いているわけでは有りません。本人にはその気はありませんが、このページに書いていることはウソかもしれません。ご了承の程をお願いします

MSXに喋らせる実験ファイル MSX1 RAM64K ディスクドライブ必須

PSG−PCMについて

PSGで再生できるのは4bitモノラルPCMデータです。PCMとは何か? というと 「Pulse Code Modulation」 の頭文字です。日本語だと 「脈符号変調」 ですが、パルス符号変調/パルス符号化などと言います。以下は『コンピュータ音声処理』(安居院 猛/中嶋 正之著 1980年)という本を読んで、私の理解で書いたPCMの説明です

パルス符号変調(Pulse Code Modulation)

アナログの信号の波形の振幅を、一定間隔で記録してデジタル化すること。これをPCMと略す。この場合に記録することをサンプリングと言い、1秒間のサンプリングの頻度をサンプリング周波数と呼ぶ。
 振幅を数値化する際は、コンピュータで扱いやすい2進数で区切りの良い段階に分ける。例えば2進数4ビットで表せる数値でPCMデータにするとすれば、16段階(又は15段階)となり、波形が0と交差する所を0000とする方法と、1000とする方法(とその他?)がある

 4ビットでPCMする場合           符号あり 符号なし      最大値→ 0111   1111 ←最大値           0110   1110           0101   1101           0100   1100           0011   1011           0010   1010           0001   1001  ここを0とする→ 0000   1000 ←ここを0とする           1111   0111           1110   0110           1101   0101           1100   0100           1011   0011           1010   0010    (最小値→) 1001   0001 (←最小値)      最小値→ 1000   0000 ←最小値

サンプリングをする前に、サンプリング周波数の1/2に相当する周波数以上の高周波成分を取り除かなければ、上手くサンプリング出来ない。例えば8kHzでサンプリングするなら、4kHz以上の成分をカットしておく。これをアンチエイリアスフィルタ(anti-alias filter)と呼ぶ。

変調時の信号対雑音比(S/N比)は、数式の「6(ビット数−1)」で求められる。例えば、S/N比60dB、10kHz、1秒間なら

    6(bits-1)=60 → bits=11

となり、メモリは11×10kHzで、110Kビット≒14Kバイト必要となる。

PSGは4ビット固定なので、変調時の理想的なS/N比18dB、8kHzなら4×8kHzで、1秒32Kビット=4Kバイト必要

(1980年当時の)電話の音質が3kHz程なので、サンプリングに必要な周波数は2倍(そういう定理がある)の6kHz程となり、7kHzのサンプリングで電話以上の音質となる。8kHz有れば、音質重視以外の大抵の用途に使える

今、MSX用にPCMデータを作るとすれば、Windows等のパソコンを使うのが一番簡単だと思います。試しに、Windowsで8ビットモノラルWAV録音(又は変換)したファイル(中を見たら「符号なし」、すなわち0が128(80H)だった。えっ、違う?) のヘッダ情報を飛ばしてデータだけ読んで、1バイトずつ16分の1して間を詰めて4ビットデータファイル(4bitPCM)にして、MSXのPSGで鳴らしたら、ちゃんと鳴ってる様に聞こえました(?)。所謂PSG−PCMです、実験ファイルで試聴してみて下さい

ページのTOPへもどる

1ビットサウンドポートについて

MSXの内蔵音源には、PSG(やFM音源)の他に「1ビットサウンドポート」という音声出力があって、BASICではキークリック音の発生にのみ使用されています(もったいない!!)。1ビットで電圧のオンオフをするだけですが、PC-8801等の音源のない8ビットパソコンで使用された 「BEEP音楽」 相当の事が出来ますし、データレコーダー端子からの入力のハイとローを拾って記録すれば、“超低音質”且つ“数秒間の”録音再生機となります。また、幾つかのゲーム(例 「レイドック2」)では、音声再生に使われています。
 PSG−PCMに比べてデータが4分の1で済む所が優位点、ノイズが全く取れないところが不利な点です

 参考:MSXでデータレコーダー端子からの入力音を鳴らす     データレコーダーの入力はPSGレジスタ14のビット7から読める。     1ビットサウンドポートはI/Oの0ABHに在り、0Fを受けると     ハイを出力し、0Eを受けるとローを出す     OUT (0A0H),14 ; PSGレジスタ14 ヲ シテイ     IN A,(0A2H) ; 14カラ ヨミコム     AND 80H ; ビット7ダケノコス     RLCA ; ビット7 -> ビット0     OR 0EH ; A=0Eカ 0Fトナル     OUT (0ABH),A ; SOUND PORTニ シュツリョク     これを繰り返す。また、ビット7の値を記録していけば、録音できる

この1ビットサウンドポート用の音声データを作るには、データレコーダー端子からの入力を記録する方法の他に、PCMデータを加工する下記の方法が使えます。次の説明も『コンピュータ音声処理』からの受け売りです

デルタ変調(Delta Modulation)

まず、アナログデジタル変換した音声信号(PCM)データを1回分ずつ(例えばWindowsのモノラル8ビット非圧縮WAVなら1バイト)読んで、前回の予測信号(後で説明)と比較し(残差をとるという)、前回の値より大きければ“1”、小さければ“0”とする(1ビットで符号化する)。この“1”と“0”を、正符号(プラス)と負符号(マイナス)とみなす

  残差 = 音声信号データの値 − 予測信号   例.音声データが「5444321・・・」と並んでいる場合    1番最初のデータは5。前回の予測信号は無いので0として     残差 = 5 − 0 = 5    残差が正(プラス)なら符号1、負(マイナス)なら符号0とする    今回の残差は5で正なので、符号は1

あらかじめ任意で大きさを決めておいたΔ(デルタ = 変化量)に符号を付けて前回の予測信号に足し、今回の予測信号を得る

    予測信号 = 前回の予測信号 + Δ   仮にΔを2とすれば、1番初めの予測信号は、前回が無いので0として     予測信号 = 0 + (+2) = 2   予測信号は2となる

2回目のデータは4。よって残差は、4−2=2。2は正なので符号は1。予測信号にΔを足して今回の予測信号を得ると、2+(+2)=4。予測信号は4となる。
 以下、同じ動作すなわち「次のデータを読んで、予測信号を引いて残差をとる。その残差の正負でΔの符号を決めて予測信号に足し、次の予測信号を得る」を繰り返し、符号を記録していく。これを、デルタ変調(Delta Modulation)と言い、DMと略す

この0と1の符号列と変調時のΔの値があれば、符号を読んでΔの正負を決めて順に足していけば、元の音声信号に近い信号が求められる、これを復号化(de-code)という

  例.音声データ「5444321・・・」、デルタを2として     得られる符号列は「1101001・・・」となり、それを     復号化すると「2424202・・・」という音声データになる     この例だけでは判らないが、これを繰り返して作った復号データを     波形グラフ化すれば、元の音声データと似た波形だと判る   表にしてみる     DM流れ表   →  →  →  →  →  →      音声データ 5  4  4  4  3  2  1      残差    5  2  0  2 −1  0  1      符号    1  1  0  1  0  0  1      デルタ   2  2 −2  2 −2 −2  2      予測信号  2  4  2  4  2  0  2     ↑まず縦方向を下に進んで、次に隣の列の上に移るように見ていく     再生時に必要なのは、符号行のデータとΔのサイズだけ

ここで、上の表の音声データの4と4が並んでいる所の様に、前後の音声データで差が無い場合が続けば残差は0と成るが、1ビット符号化のゆえに残差0には割り当てがない。残差0に符号1を割り当てると信号がどんどん大きくなってしまうので、符号0を割り当てる。結果として、音声データに変化が無ければ残差はΔの分だけ上下動を繰り返し、符号は0と1を繰り返す。元の音声データでは何も変化が無いのに、復号化した音声データは最小の凹凸を繰り返してしまうわけである。これによって生ずる音の歪みを、グラニュラー雑音(granular noise)という
 また、Δの値が一定な為、元の音声データの変化が急で大きい場合に、予測信号が追いつかずに波形にズレが生じる。これをオーバーロード雑音(overload noise)という

グラニュラー雑音を抑えるにはΔを小さくし、オーバーロード雑音を抑えるにはΔをやや大きくする必要があるので、トレードオフ関係となる。
 出来たデータを再生する場合に、ローパスフィルタを使って周波数以上の高周波成分を取り除かなければ、雑音の嵐となる

おまけ

適応デルタ変調(Adaptive Delta Modulation)

DMに於いて、同じ符号が続く場合に音の変化が激しいと見て、同符号が3回続けば、3回目からは同符号が続く限り毎回Δを2倍する、異符号が来れば2分の1すると決めて、オーバーロード雑音を抑えようとする方法がある。この方法では、同じ符号が続けば、どんどんΔが大きくなるので、Δの最大値をあらかじめ任意に決めておく。これを適応デルタ変調(Adaptive Delta Modulation)方式と呼び、ADMと略す

  ADMのΔの設定表    前々回 前回 現在 Δの大きさ 方向     1  1  1  2倍    +     1  0  1  1/2   +     0  1  1  そのまま  +     0  0  1  1/2   +     0  0  0  2倍    −     0  1  0  1/2   −     1  0  0  そのまま  −     1  1  0  1/2   −

おまけのADM方式は不可能でしょうが、 DM方式のΔを1と見れば、MSXの1ビットサウンドポート用の再生データになります。ただし、MSXの場合、再生時のローパスフィルタは無いわけです。

1ビットサウンドポート再生時のΔは常に1なので、DMせずとも、データを一回分ずつ比較してプラスなら1、マイナスか0なら0とするだけで良さそうなものですが、DMすると自動的に(多少は)ノイズ除去されるので、たとえ再生Δが1固定でも、少し雑音がへります。その代わり少しこもった音になります。

MSX用ではなく音声ファイル一般について、超高音質素材でない限り何らかのノイズ除去処理を行えば、幾分は「宇宙ボイス」になります (はぁ?)。それを避ける為、今回の実験ファイルに使用した素材WAVのノイズ除去はしていません注1実験ディスクに入っているDMデータの WIN98.DM や INTRO1.DM には、元の素材WAVにある声の「かすれ」や言葉尻の「息」が見事に「轟音ノイズ」として乗っています。私の1ビットサウンドポート用DMでは、「息」や「かすれ」程度のどんな小音でも全開の音量で記録されてしまうのです。(オイオイ! でも、きっと誰が作っても同・・・??)

ノイズ除去と音質劣化はトレードオフ関係ですが、雑音はDMする前にWindows上のソフト等で可能な限り綺麗にしてください(^^;)

 MSXのDMに最適なWAV素材  ・声優が録音スタジオで録音したような無雑音のハッキリした人声  ・声の質に「かすれ」や「ブレス」成分が少ない  ・太い、低い声  MSXのDMで不可能なWAV素材  ・音楽  ・屋外で録音したような騒音/雑音入り  ・二人以上で同時に話している

上手くいけば、何を言っているか聞き取れる音質で再生可能な1ビット符号データ化出来るでしょう。超暇人MSXとしては、80年代当時のファミコンのDPCM(『燃えプロ』など一言喋るアレ)より、良い再生音質に聞こえます。

また、4bitPCMデータをPSGで再生した場合は音量がかなり小さくなりますし、DM時に小音除去フィルタは必須なので、どちらに変換する場合でも元のWAVファイルの音量は正規化 (割れない範囲でバランス良く最大化すること) しておいた方が上手く変換できます

一度試してみてDMで無理があるWAVは素直に諦めるか、データレコーダ端子からの録音(ソフトを自作(^^;))や4bitPCMの方でチャレンジしてください

  注1.無関係ではないがちょっと脱線した話    日本の戦前の映画等の古い素材は、しばしば酷いノイズが乗ったまま放送等に    使用されるが、ハリウッドの名作等では、例えば20人で3ヶ月かけて、一々    人の耳や眼で部分部分の雑音や、一コマずつ映像のノイズを取ってから放送や    DVDに使用する。現時点では機械的に行えば、ノイズ以外にも変化(劣化)    が起きる為である。     これは、白人英語圏を含む全世界のコンテンツ商売を握る米メディアなれば    こそ、名作とはいえ古い作品の再利用に+アルファの「大金」を使えるワケ。     本当はこういう作業こそ、日本人の得意とする所であるのになぁ

ページのTOPへもどる

このページは、1024×768画面に合わせて作りました。ちゃんと見えなかったらスミマセン