FSKローダは、JR-100のSAVE文によって出力される音声ファイルを復号して、JR-100のプログラムを取り出すプログラムです。記録媒体がカセットテープというアナログ音源であって、またテープが経年劣化し、テープが伸びたり音質が低下していることを前提とし、ディジタル信号処理を施すことによりなるべく読み取りエラーが起きないような信号処理を行っています
目次
使い方
起動
Windowsの場合、ダウンロードしたjarファイル(loader.jar)をカレントディレクトリに置いて、以下のコマンドを実行してください。
% loader.jar
Windowsの場合はloader.jarのアイコンをダブルクリックしても構いません。 メモリが足りない場合はJavaのヒープを大きくするために以下のように-Xmxオプションを指定して実行してください。
% java -Xmx128M loader.jar
すると次のようなメインウィンドウが表示されます。
※ コマンドラインでの実行モードもありますが、その起動方法やオプションの意味については後日記載します。
設定ファイル
起動に成功すると、loader.jarと同じディレクトリにFSKローダの設定ファイルjr100loader.iniを作成します。すでに存在している場合はr100loader.iniを読み込んで設定情報を復元します。
※ ファイル名やファイル内のフォーマットは正式版までに変更する可能性があります。
読み込の準備
まずSAVEデータをPCに取り込みます。そのためのツールとしては以下のものがあります。
- サウンドカードに付属のツール
- 各種フリーソフト (Vectorの音声 録音・再生カテゴリなどを参考にしてください)
- CD/DVDレコーディングソフトに付属のツール Windowsに付属の「サウンドレコーダー」では一度に録音できる時間に制限がある(WindowsXPの場合は60秒)ので使えません。
これらを利用してwavフォーマットのファイルを作成してください。 その際、サンプリング周波数は22050Hz程度、サンプリングビット数は16bitをお勧めします。特にサンプリング周波数は重要で、あまり低いと読み取りエラーが発生しやすくなります。逆に大きすぎてもファイルサイズも大きくなりますし、処理時間も長くかかるので程々にしてください。
ステレオで録音する必要はありません。ステレオで録音されたwavファイルを入力した場合は、左右のチャンネルの音の平均値を1サンプルとして扱います。
また録音する際はボリュームにも注意してください。あまり大きくしすぎると波形が歪んだりノイズのレベルも大きくなってしまい、うまく処理できないことがあります。逆に小さすぎても信号とノイズとの区別がしにくくなります。適度な大きさの音となるようにうまく調整してください。録音ソフトにレベルメータがあれば、最大値に達しないギリギリのレベルになるようにすると良いでしょう。
カセットデータからPCにうまく音声を取り込む手法については以下のサイトに詳しいです。
アナログ音源再生計画
読み込み(ロード)
メインメニューから「ファイル→開く」を選ぶと以下のようなウィンドウが開きます。
ファイルを開くディレクトリは、初期状態ではユーザのホームディレクトリ(Windows XPの場合、通常"c:\Documents and Settings\ユーザアカウント名"となっています。なおこのディレクトリは設定により変更することができます。
選択できるファイルは、wavフォーマットファイルか、すでにwavから復元されたJR-100プログラムファイルのいずれかとなります。
ファイルを選択して「開く」ボタンを押すと、メインウィンドウの入力ファイル名に選択したファイルのフルパス名が表示され、同時に出力ファイル名として拡張子を「.prg」に変更したファイル名が表示されます。必要ならば直接ファイル名を編集することも可能です。
選択したファイルがJR-100プログラムファイル形式の場合は出力ファイル名の欄には何も表示されません。この状態でプログラムを読み込む(ロードボタンを押す)と、対象のプログラムを読み込んでその内容を表示します。
ここで「ロード」ボタンを押すとファイルのロードが始まります。
読み込んだプログラムの確認
エラー無く読み込んだ場合はメインウィンドウ最下部のステータスバーに「正常に読み込みました」と表示し、読み込んだプログラムの名前(SAVE時に指定した文字列)と、読み込んだプログラムの内容をウィンドウ下部のタブペインに表示します。BASICプログラムの場合はBASICプログラムと、メインRAM上に展開されるバイナリデータの両方を見ることができます。
読み取りエラーが発生した場合は、wavファイルを再作成するか、FSKローダのパラメータを調整して正しく読み取れるまで繰り返してください。
※ 読み取りエラーが発生した場合の対処は今後追記していきますが、FSKローダの正式版が出るまではなるべく私の方でも解析して調べてみたいので、ご連絡下さい。
プログラム名の横の「詳細」ボタンを押すと、そのwavファイルのサンプリング周波数や搬送波周波数などの情報などを表示します。
プログラムの保存
正常にプログラムをよみこんだ後、メインウィンドウの「セーブ」ボタンを押すことにより読み込んだプログラムの内容をPRG形式でファイルに保存します。
設定の変更
メインウィンドウから「ツール→プロパティ」を選択すると、FSKローダの各種プロパティを表示・設定するための画面を表示します。
各設定値の意味は下表の通りです。
ロードパス | ファイルを開くときに最初に選択可能なディレクトリ |
FFT | 搬送波周波数などを解析するための処理方法を選択する。 [FFTを使用する場合] FFTの次数を自動選択にするか、指定の固定値にするかを選択 [FFTを使用しない場合] 搬送波周波数・空白周波数・マーク周波数をそれぞれ固定値で指定する。 |
フィルタ | 入力音声から余計な周波数成分を除去するための帯域通過フィルタの緒元を設定する。帯域通過フィルタにはFIRを使用しており、窓関数としてKaiser窓を使用している。※パラメータの詳細は後日記載増幅器 |
増幅器 | フィルタ通過後の波形を方形波化するための増幅器の各種パラメータを設定する。※パラメータの詳細は後日記載 |
ロードパスのテキストフィールドの横の「詳細」ボタンを押すと下図のウィンドウが開くので、適切なディレクトリを選択して「開く」を押してください。
技術情報
PRGファイルのフォーマット
ファイルはPRG形式を表す4バイトのバイト列から始まり、以下各種データが以下のように並びます。2バイトよりも大きな数値は、すべてリトルエンディアンでファイルに格納します。
オフセット | バイト長 | 値 | 備考 |
0 | 4 | 0x50524f47 | 'P' 'R' 'O' 'G'の4文字 |
4 | 4 | フォーマットバージョン | 現在は0x00000001の固定値 |
8 | 4 | プログラム名長n | |
12 | n | プログラム名 | null終端されている必要は無い。 |
12+n | 4 | プログラムの先頭アドレス | |
16+n | 4 | プログラム長 m | |
20+n | 4 | フラグ (4バイト) | 現在は以下のビットのみ使用 b0: BASIC(0) / マシン語(1) |
21+n | m | プログラムデータ |
JR-100のカセットテープ保存フォーマット
カセットテープに保存される1バイトの値は、スタートビット1ビットとストップビット2ビットを合わせて11ビットで表現する。またスタートビットの次にはバイト値のLSBがくる(ビット列がリトルエンディアン)。
0 | b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7 | 1 | 1 |
以下にカセットテープに保存するデータの形式を示す。非データ部分にはスタートビットとストップビットの区別はなく、単純なビットパターンの繰返しとなる。非データ部分2でビット値'0'が出現するが、BASICインタプリタの内容を解析したところ、これを何かに利用しているわけではないようである。
オフセット | バイト長 | 値 | 備考 |
(非データ部分1) | ― | 1 (2進数) | |
(非データ部分2) | ― | 111111110 (2進数)を28回繰返し | |
(非データ部分3) | ― | 1 (2進数) を3828ビット分(255*15+3)繰返し | |
0 | 16 | ファイル名 | ファイル名(最大15文字)+16バイトに満たない部分を0x00で埋める。 |
16 | 2 | 先頭アドレス | BASICプログラムの場合は'0x0246' |
18 | 2 | プログラム長N | |
20 | 1 | フラグ | BASICの場合 0x00、マシン語の場合 'M' (0x4d) |
21 | 11 | 0x00 | 埋め草 |
32 | 1 | オフセット0〜31までのチェックサム | 合計値の下位1バイト |
(非データ部分4) | ― | 1 | (2進数)を255ビット分繰返し |
0 | N | プログラムデータ | オフセット18で与えられる値Nバイト |
N | 1 | プログラムデータのチェックサム | 合計値の下位1バイト |
信号処理について
FSKローダが行う信号処理の流れを下図に示します。
(ステップ1) キャリア周波数の決定
SAVE文によってカセットテープに保存された音声データは、テープ自体の経年劣化や、音声の保存に使用したカセットデッキの性能などにより、本来の方形波からはかなり異なった波形となっています。JR-100の場合、空白を1200Hz、マークを2400Hzで表現し、搬送波周波数として600Hzを使用するFSKでデータを保存しますが、実際に保存されたデータの周波数が必ずこの値になっているとは限りません。
一例として、手元のラジカセを使ってカセットテープからのデータをPCに取り込んだ音声の波形を以下に示します。
測定データの緒元
使用データ | JR-T01「いろいろなアルゴリズム」から「SHUFFLE」 |
再生に使用した再生機 | Victor RC-Q1 (CDラジカセ) (生産完了品のためカタログ無し) |
録音に使用したサウンドデバイス | ASUSTeK P4800-Eオンボードサウンドデバイス |
録音に使用したソフトウェア | B's RECORDER GOLD8付属のツール |
音声波形編集ソフト | GoldWave ver 5.10 (シェアウェア) |
ご覧の通り、高周波成分がなくなって方形波ではなくなっています。また振幅も一定ではなく、低周波成分が混ざってしまって波打ってしまっています(波の中心が0ではなく負の値から正の値に変化している)。また、この画像からは分かりにくいですが、正確に1200/2400Hzのデータが現れているわけではなく、多少ずれています。
FSKで符号化されたデータを復号するためには、空白とマークが何Hzなのかを正確に知らないといけません。そうでないと0か1かを判定するための境界を誤判定してしまう可能性があるからです。そこでこのようなデータから元のデータを復元するために、まず空白成分とマーク成分の正確な周波数を求める、言い換えると搬送波周波数が正確にはどんな値になっているかを求める必要があります。
FSKローダではそのためにFFTを使用しています。 入力された音声データをFFTをかけて、もっとも高いピーク値を持つ周波数成分を求めます。正確には2のn乗(nは元データのサンプリング周波数によって適度な値に設定する)で元データを区切って、それぞれごとにFFTをかけ、その結果を全データにわたって積算します。その結果1200/2400Hz付近でもっとも大きな値を持つ周波数成分F0とF1を求め、Fc=(F0+F1)/6として搬送波周波数を求めます。
上記の例の周波数成分のピーク値を求めたものを以下に示します(WaveSpectra使用)。
1kHz付近と2kHz付近にピークが出ているのが分かります。
実際にFSKローダで解析した結果を「情報」ウィンドウで確認すると以下のようになります。
空白周波数もマーク周波数も、本来の仕様(1200/2400Hz)よりもかなり低くなっていることが分かります。そこで以下に続く解析では、搬送波周波数としてこの521.68Hzを使用することにします。
(ステップ2) ノイズ成分の除去
次に、高周波ノイズや低周波成分(振幅の中心値が0を中心としてゆっくり変動する成分)を除去するために、帯域通過フィルタを通します。この結果を以下に示します。
振幅の中心値がほぼゼロに集まり、波形自体も正弦波に近づきました。
ステップ(3) 方形波化
この次は、この信号を増幅し、最大・最小値でクリッピングすることにより、方形波に近くなるように処理をします。
だいぶきれいな方形波が得られました。後はこの信号を元に空白(0)とマーク(1)を先に求めた各周波数を元にFSK復号し、JR-100のテープ保存方式に従ってプログラムの復元を行います。