不明な形式のデータを磁気テープから復元する方法

バックグラウンド



レトロな鉄の愛好家として、私はかつてZX Spectrum +を英国の販売者から購入しました。コンピューター自体を完成させて、ゲーム付きのオーディオカセット(説明書のある元のパッケージ)と、特別な指定なしにカセットに記録されたプログラムをいくつか手に入れました。驚いたことに、40年前のカセットからのデータは読みやすく、ほとんどすべてのゲームとプログラムをそれらからダウンロードすることができました。







しかし、一部のカセットでは、ZX Spectrumコンピューターでは明らかに作成されていない録音を見つけました。それらは完全に異なって聞こえ、前述のコンピューターからの録音とは異なり、通常はすべてのプログラムとゲームの録音に存在する短いBASICブートローダーで始まりませんでした。



しばらくの間、私はこれに悩まされていました。何が隠されているのかを本当に知りたかったのです。オーディオ信号を一連のバイトとして読み取ることができた場合は、信号の起源を示す文字または何かを探すことができます。一種のレトロな考古学。



ずっとやって来て、カセットのラベルを見てきたので、笑って

答えはいつも私の目の前でした
— TRS-80, : «Manufactured by Radio Shack in USA»


(陰謀を最後まで続けたい場合は、スポイラーの下に行かないでください)



オーディオ信号の比較



最初のステップは、オーディオ録音をデジタル化することです。あなたはそれがどのように聞こえるかを聞くことができます:





そしていつものように、ZX Spectrumコンピュータからの録音は鳴ります:





どちらの場合も、録音の最初に、いわゆるパイロットトーンが聞こえます。これは、1つの周波数の音です(最初の録音では、1秒未満の非常に短い音ですが、区別できます)。パイロットトーンは、データを受信する準備をするようにコンピュータに通知します。通常、各コンピュータは、波形とその周波数によって「その」パイロットトーンのみを認識します。



信号の形状自体についてお話します。たとえば、ZXスペクトラムでは、その形状は長方形です。







パイロットトーンが検出されると、ZXスペクトラムは画面の境界に交互に赤と青のストライプを表示し、信号が認識されたことを示します。パイロットトーンはシンクロパルスで終了します、コンピュータにデータの受信を開始するように通知します。(パイロットトーンおよび後続のデータと比較して)短い期間が特徴です(図を参照)



。同期パルスが受信された後、コンピューターは信号の各立ち上がり/立ち下がりを記録し、その期間を測定します。継続時間が特定の制限より短い場合、ビット1がメモリに書き込まれ、それ以外の場合は0になります。ビットはバイトに収集され、Nバイトが受信されるまでプロセスが繰り返されます。番号Nは通常、ダウンロードしたファイルのヘッダーから取得されます。起動シーケンスは次のとおりです。



  1. パイロットトーン
  2. ヘッダー(固定長)、ロードされたデータのサイズ(N)、名前、ファイルタイプが含まれます
  3. パイロットトーン
  4. データ自体


データが正しく読み込まれるように、ZXスペクトラムは、いわゆるバイトパリティ(パリティバイト)の最後のバイトを読み取ります。これは、記録されたデータのすべてのバイトに対してファイル操作XORを保存するときに計算されます。コンピュータはファイルを読み取るときに、受信したデータからパリティバイトを計算し、結果が保存されたデータと異なる場合は、エラーメッセージ「R Tape loading error」を表示します。厳密に言うと、コンピューターが読み取り時にインパルスを認識できない場合(それが失われた場合、またはその期間が特定の境界に対応していない場合)、コンピューターはこのメッセージを先に発行できます。



では、未知の信号がどのように見えるかを見てみましょう。







これはパイロットトーンです。波形は大きく異なりますが、信号が特定の周波数の繰り返しの短いパルスで構成されていることがわかります。 44100 Hzのサンプリングレートでは、「ピーク」間の距離は約48サンプルです(これは、約918 Hzの周波数に対応します)。この図を思い出してみましょう。



次に、データを含むフラグメントを見てみましょう。







個々のパルス間の距離を測定すると、「長い」パルス間の距離は依然として〜48サンプルであり、短いパルス間の距離は〜24であることがわかります。少し先に実行すると、最終的に、918 Hzの周波数を持つ「参照」パルスがファイルの最初から最後まで継続的に続くことがわかりました。データ送信中に、基準パルスの間に追加のパルスが発生した場合、それをビット1と見なし、そうでない場合は0と見なすことができます。



シンクロパルスとは何ですか?データの始まりを見てみましょう







。パイロットトーンが終了し、データがすぐに始まります。少し後、いくつかの異なるオーディオ録音を分析した後、最初のデータバイトが常に同じであることがわかりました(10100101b、A5h)。コンピューターは、データを受信した後、データの読み取りを開始する場合があります。



シンクロバイトの最後の1の直後の最初の基準パルスのシフトにも注意を払うことができます。ファイルの先頭にあるデータを安定して読み取ることができなかったときに、データ認識のためのプログラムを開発するプロセスのずっと後で発見されました。



次に、オーディオファイルを処理してデータをロードするアルゴリズムについて説明します。



データのロード



最初に、アルゴリズムが複雑にならないように、いくつかの仮定を見てみましょう。



  1. WAV形式のファイルのみを考慮します。
  2. 音声ファイルはパイロットトーンで開始する必要があり、最初に無音を含めることはできません
  3. ソースファイルのサンプリングレートは44100 Hzである必要があります。この場合、48サンプルの参照パルス間の距離はすでに決定されているため、プログラムで計算する必要はありません。
  4. サンプル形式は任意(8/16ビット/浮動小数点)にすることができます-読み取るときに、それを目的の形式に変換できます。
  5. 元のファイルは振幅が正規化されていると想定しています。これにより、結果が安定します。


読み取りアルゴリズムは次のようになります。



  1. ファイルをメモリに読み込み、同時にサンプル形式を8ビットに変換します。
  2. オーディオデータの最初のパルスの位置を決定します。これを行うには、最大振幅のサンプル数を計算する必要があります。簡単にするために、手動で1回カウントしてみましょう。それをprev_pos変数に保存しましょう。
  3. 最後のインパルスの位置に48を追加します(pos:= prev_pos + 48)
  4. 48 , ( , ), pos. (pos-8;pos+8) . , , pos. 8 = 48/6 — , , . , 48, , ;
  5. , . , , . , , . , . 2 : , . ;
  6. ( 0 1), (prev_pos;pos) middle_pos middle_pos := (prev_pos+pos)/2 middle_pos (middle_pos-8;middle_pos+8) . 10, 1 0. 10 — ;
  7. prev_pos (prev_pos := pos)
  8. 3, ;
  9. . - , 8, . - 8 . . A5h,


Ruby,
Ruby, .. . , .



#  gem 'wavefile'
require 'wavefile'

reader = WaveFile::Reader.new('input.wav')
samples = []
format = WaveFile::Format.new(:mono, :pcm_8, 44100)

#  WAV ,    Mono, 8 bit 
#  samples       0-255
reader.each_buffer(10000) do |buffer|
  samples += buffer.convert(format).samples
end

#    ( 0)
prev_pos = 0
#   
distance = 48
#       
delta = (distance / 6).floor
#        "0"  "1"
bits = ""

loop do
  #    
  pos = prev_pos + distance
  
  #       
  break if pos + delta >= samples.size

  #   pos     [pos - delta;pos + delta]
  (pos - delta..pos + delta).each { |p| pos = p if samples[p] > samples[pos] }

  #    [prev_pos;pos]
  middle_pos = ((prev_pos + pos) / 2).floor

  #     
  sample = samples[middle_pos - delta..middle_pos + delta]

  #    "1"           10
  bit = sample.max - sample.min > 10
  bits += bit ? "1" : "0"
end

#  -       256   (  ) 
bits.gsub! /^[01]*?10100101/, ("0" * 256) + "10100101"

#   ,    
File.write "output.cas", [bits].pack("B*")






アルゴリズムと定数のいくつかのバリアントを試した結果、非常に興味深いものを得ることができてラッキーでした。







つまり、文字列から判断すると、グラフをプロットするためのプログラムがあります。ただし、プログラムテキストにはキーワードがありません。すべてのキーワードはバイトとしてコード化されます(各値> 80h)。次に、80年代のどのコンピュータがこの形式でプログラムを保存できるかを調べる必要があります。



これは実際にはBASICプログラムに非常に似ています。ほぼ同じ形式で、ZX Spectrumコンピュータはメモリに格納し、プログラムをテープに保存します。念のため、キーワードをと照合しました。しかし、結果は明らかに否定的でした。



また、当時人気のあったAtariコンピュータ、Commodore 64などのBASICキーワードも確認しました。そのため、ドキュメントを見つけることができましたが、役に立たなかったのです。レトロコンピュータの種類に関する知識はそれほど広くありませんでした。



それから私はリストを調べることを決心し、それから私の目はRadio ShackとTRS-80コンピューターのメーカーの名前に目を向けました。これらの名前は、私のテーブルにあるカセットのラベルに書かれていました。結局のところ、私は以前これらの名前を知らなかったし、TRS-80コンピュータに慣れていなかったので、Radio ShackはBASF、Sony、TDKなどのオーディオカセットのメーカーであり、TRS-80は再生時間でした。何故なの?



コンピュータタンディ/ラジオシャックTRS-80



記事の冒頭で例として挙げた問題のオーディオ録音がそのようなコンピューターで作成された可能性が非常に高いです。







このコンピューターとそのバリアント(モデルI /モデルIII /モデルIVなど)が非常に人気があることが判明しました時間(もちろん、ロシアではありません)。それらで使用されているプロセッサもZ80であることは注目に値します。このコンピュータのインターネット上の多くの情報を見つけることができます。 1980年代には、コンピューターに関する情報が雑誌に掲載されました。現在、さまざまなプラットフォーム用のいくつかのコンピューターエミュレーターがあります。trs80gp



エミュレータをダウンロードしましたそして、このコンピューターがどのように機能するかを初めて知ることができました。もちろん、コンピューターはカラー出力をサポートしておらず、画面解像度は128x48ピクセルしかありませんでしたが、画面解像度を上げることができる多くの拡張機能と変更がありました。このコンピューターのオペレーティングシステムのオプションやBASIC言語の実装オプションも多数ありました(ZXスペクトラムとは異なり、一部のモデルではROMに「フラッシュ」されておらず、オプションはフロッピーディスクやOS自体からロードできました)



オーディオ録音をエミュレーターでサポートされているCAS形式に変換するためユーティリティを見つけましたが、何らかの理由で自分のカセットから録音を読み取ることができませんでした。



CASファイル(同期バイトが存在するヘッダーを除いて、すでに手元にあるテープからのデータのビット単位のコピーであることがわかった)の形式を理解した後、プログラムにいくつかの変更を加え、出力で動作するCASファイルを取得することができました。それはエミュレーター(TRS-80モデルIII)で







機能しました。最初のパルスと基準パ​​ルス間の距離を自動検出して変換するためのユーティリティの最後のバージョンは、GEMパッケージとして設計しましたソースコードはGithubで入手できます



結論



たどった道は過去へのエキサイティングな旅であることが分かりました、そして私は結局解決策を見つけたことを嬉しく思います。とりわけ、私は:



  • ZXスペクトラムにデータを保存するためのフォーマットを理解し、オーディオテープからデータを保存/読み取るための組み込みROMルーチンを調べました
  • 私はTRS-80コンピューターとその種類について知り、オペレーティングシステムを研究し、プログラムの例を見て、マシンコードでデバッグする機会さえありました(結局のところ、すべてのZ80ニーモニックは私に馴染みがあります)。
  • オーディオ録音をCAS形式に変換するための本格的なユーティリティを作成しました。これにより、「公式」ユーティリティで認識されないデータを読み取ることができます。



All Articles