Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

prasejarah

Dadi pacangan hardware retro, aku tau tuku ZX Spectrum + saka bakul ing UK. Kalebu karo komputer dhewe, aku nampa sawetara kaset audio karo game (ing kemasan asli karo instruksi), uga program sing direkam ing kaset tanpa tandha khusus. Kaget, data saka kaset 40 taun bisa diwaca kanthi apik lan aku bisa ndownload meh kabeh game lan program saka dheweke.

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Nanging, ing sawetara kaset aku nemokake rekaman sing jelas ora digawe dening komputer ZX Spectrum. Padha muni temen beda lan, ora kaya rekaman saka komputer kasebut, padha ora miwiti karo bootloader BASIC singkat, kang biasane ana ing rekaman kabeh program lan game.

Kanggo sawetara wektu iki Angker kula - Aku pancene wanted kanggo mangerteni apa sing didhelikake ing wong. Yen sampeyan bisa maca sinyal audio minangka urutan bita, sampeyan bisa nggoleki karakter utawa apa wae sing nuduhake asal saka sinyal kasebut. A jinis retro-arkeologi.

Saiki aku wis lunga kabeh lan ndeleng label saka kaset dhewe, aku mesem amarga

wangsulane ana ing ngarep mripatku kabeh
Ing label kaset kiwa ana jeneng komputer TRS-80, lan ing ngisor jeneng pabrikan: "Diprodhuksi dening Radio Shack ing AS"

(Yen sampeyan pengin tetep intrik nganti pungkasan, aja nganti spoiler)

Perbandingan sinyal audio

Kaping pisanan, ayo digitalisasi rekaman audio. Sampeyan bisa ngrungokake kaya apa:


Lan kaya biasane, rekaman saka komputer ZX Spectrum muni:


Ing kasus loro, ing awal rekaman ana sing disebut nada pilot - swara kanthi frekuensi sing padha (ing rekaman pisanan cendhak banget <1 detik, nanging bisa dibedakake). Nada pilot menehi sinyal komputer kanggo nyiapake nampa data. Minangka aturan, saben komputer mung ngenali nada pilot "dhewe" kanthi bentuk sinyal lan frekuensi.

Sampeyan perlu kanggo ngomong soko bab wangun sinyal dhewe. Contone, ing ZX Spectrum wangunΓ© persegi dowo:

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Nalika nada pilot dideteksi, ZX Spectrum nampilake bar abang lan biru gantian ing tapel wates layar kanggo nuduhake yen sinyal wis dikenali. Nada pilot rampung pulsa sinkro, sing menehi sinyal komputer kanggo miwiti nampa data. Iki ditondoi kanthi durasi sing luwih cendhek (dibandhingake karo nada pilot lan data sabanjure) (pirsani gambar)

Sawise pulsa sinkronisasi ditampa, komputer nyathet saben munggah / mudhun sinyal, ngukur durasi. Yen durasi kurang saka watesan tartamtu, bit 1 ditulis ing memori, yen ora 0. Bit diklumpukake dadi bita lan proses kasebut diulang nganti N bita ditampa. Nomer N biasane dijupuk saka header file sing diundhuh. Urutan loading kaya ing ngisor iki:

  1. nada pilot
  2. header (dawa tetep), ngemot ukuran data sing diundhuh (N), jeneng file lan jinis
  3. nada pilot
  4. data dhewe

Kanggo mesthekake yen data dimuat kanthi bener, maca ZX Spectrum sing diarani bait paritas (bait paritas), sing diwilang nalika nyimpen file kanthi XORing kabeh bita saka data sing ditulis. Nalika maca file, komputer ngetung bait paritas saka data sing ditampa lan, yen asil beda karo sing disimpen, nampilake pesen kesalahan "R Tape loading error". Tegese, komputer bisa ngetokake pesen iki luwih dhisik yen, nalika maca, ora bisa ngenali pulsa (ora kejawab utawa durasine ora cocog karo watesan tartamtu)

Dadi, ayo ndeleng apa sinyal sing ora dingerteni:

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Iki minangka nada pilot. Bentuk sinyal kasebut beda banget, nanging jelas yen sinyal kasebut kalebu mbaleni pulsa cendhak frekuensi tartamtu. Ing frekuensi sampling 44100 Hz, jarak antarane "puncak" kira-kira 48 conto (sing cocog karo frekuensi ~ 918 Hz). Ayo elinga tokoh iki.

Ayo saiki ndeleng fragmen data:

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Yen kita ngukur jarak antarane pulsa individu, ternyata jarak antarane pulsa "dawa" isih ~ 48 sampel, lan antarane sing cendhak - ~ 24. Looking ahead sethitik, Aku bakal ngomong sing ing pungkasan iku nguripake metu sing "referensi" pulses karo frekuensi 918 Hz tindakake terus-terusan, saka awal kanggo mburi file. Bisa dianggep yen nalika ngirim data, yen ana pulsa tambahan ing antarane pulsa referensi, kita nganggep minangka bit 1, yen ora 0.

Kepiye babagan pulsa sinkronisasi? Ayo katon ing wiwitan data:

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Nada pilot rampung lan data diwiwiti langsung. Ora suwe, sawise nganalisa sawetara rekaman audio sing beda-beda, kita bisa nemokake manawa data byte pisanan mesthi padha (10100101b, A5h). Komputer bisa miwiti maca data sawise nampa.

Sampeyan uga bisa mbayar manungsa waΓ© menyang shift pulsa referensi pisanan sanalika sawise 1st pungkasan ing bait sinkronisasi. Ditemokake mengko ing proses ngembangake program pangenalan data, nalika data ing wiwitan file ora bisa dibaca kanthi stabil.

Saiki ayo nyoba njlèntrèhaké algoritma sing bakal ngolah file audio lan mbukak data.

Loading Data

Pisanan, ayo goleki sawetara asumsi supaya algoritma tetep prasaja:

  1. Kita mung bakal nimbang file ing format WAV;
  2. File audio kudu diwiwiti kanthi nada pilot lan ora kudu nggawe bisu ing wiwitan
  3. File sumber kudu duwe tingkat sampling 44100 Hz. Ing kasus iki, jarak antarane pulsa referensi saka 48 sampel wis ditemtokake lan kita ora perlu ngetung kanthi program;
  4. Format sampel bisa wae (8/16 bit / floating point) - amarga nalika maca, kita bisa ngowahi menyang sing dikarepake;
  5. Kita nganggep yen file sumber dinormalisasi kanthi amplitudo, sing kudu nyetabilake asil;

Algoritma maca bakal kaya ing ngisor iki:

  1. Kita maca file menyang memori, ing wektu sing padha ngowahi format sampel dadi 8 bit;
  2. Nemtokake posisi pulsa pisanan ing data audio. Kanggo nindakake iki, sampeyan kudu ngetung jumlah sampel kanthi amplitudo maksimum. Kanggo gamblang, kita bakal ngetung sapisan kanthi manual. Ayo disimpen menyang variabel prev_pos;
  3. Tambah 48 menyang posisi pulsa pungkasan (pos := prev_pos + 48)
  4. Wiwit nambah posisi kanthi 48 ora njamin yen kita bakal entuk posisi pulsa referensi sabanjure (cacat tape, operasi mekanisme tape drive sing ora stabil, lan liya-liyane), kita kudu nyetel posisi pos pulsa. Kanggo nindakake iki, njupuk bagéyan cilik saka data (pos-8; pos + 8) lan golek nilai amplitudo maksimum ing. Posisi sing cocog karo maksimal bakal disimpen ing pos. Ing kene 8 = 48/6 minangka konstanta sing diduweni kanthi eksperimen, sing njamin kita bakal nemtokake maksimum sing bener lan ora bakal mengaruhi impuls liyane sing bisa uga ana ing cedhak. Ing kasus sing ala banget, nalika jarak antarane pulsa kurang saka utawa luwih saka 48, sampeyan bisa ngleksanakake telusuran paksa kanggo pulsa, nanging ing ruang lingkup artikel aku ora bakal njlèntrèhaké iki ing algoritma;
  5. Ing langkah sadurunge, sampeyan uga kudu mriksa manawa pulsa referensi ditemokake. Yaiku, yen sampeyan mung nggoleki maksimal, iki ora njamin yen impuls ana ing segmen iki. Ing implementasine program maca paling anyar, aku mriksa prabΓ©dan antarane nilai amplitudo maksimum lan minimal ing sawijining segmen, lan yen ngluwihi watesan tartamtu, aku ngetung ananΓ© impuls. Pitakonan uga apa sing kudu ditindakake yen pulsa referensi ora ditemokake. Ana 2 opsi: salah siji data wis rampung lan kasepen nderek, utawa iki kudu dianggep minangka kesalahan maca. Nanging, kita bakal ngilangi iki kanggo nyederhanakake algoritma;
  6. Ing langkah sabanjure, kita kudu nemtokake ananΓ© pulsa data (bit 0 utawa 1), kanggo iki kita njupuk tengah segmen (prev_pos;pos) middle_pos padha karo middle_pos := (prev_pos+pos)/2 lan ing sawetara lingkungan middle_pos ing babagan (middle_pos-8;middle_pos +8) ayo ngetung amplitudo maksimum lan minimal. Yen prabΓ©dan antarane wong-wong mau luwih saka 10, kita nulis bit 1 menyang asil, digunakake 0. 10 punika pancet dijupuk eksperimen;
  7. Simpen posisi saiki ing prev_pos (prev_pos := pos)
  8. Baleni wiwit saka langkah 3 nganti kita maca kabeh file;
  9. Array bit sing diasilake kudu disimpen minangka set bita. Awit kita ora njupuk menyang akun bait sinkronisasi nalika maca, jumlah bit bisa uga ora kaping 8, lan bit sing dibutuhake uga ora dingerteni. Ing implementasine algoritma pisanan, aku ora ngerti babagan anane bait sinkronisasi lan mulane mung nyimpen 8 file kanthi jumlah bit offset sing beda. Salah sijine ngemot data sing bener. Ing algoritma pungkasan, aku mung mbusak kabeh bit nganti A5h, sing ngidini aku langsung entuk file output sing bener

Algoritma ing Ruby, kanggo sing kasengsem
Aku milih Ruby minangka basa kanggo nulis program, amarga ... Aku program ing paling wektu. Opsi kasebut ora nduweni kinerja dhuwur, nanging tugas kanggo nggawe kacepetan maca kanthi cepet ora pantes.

# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ 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*")

asil

Sawise nyoba sawetara varian saka algoritma lan konstanta, aku begja entuk sing menarik banget:

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Dadi, miturut senar karakter, kita duwe program kanggo ngrancang grafik. Nanging, ora ana tembung kunci ing teks program. Kabeh tembung kunci dienkode minangka bita (saben nilai> 80h). Saiki kita kudu ngerti komputer saka 80s bisa nyimpen program ing format iki.

Nyatane, meh padha karo program BASIC. Komputer ZX Spectrum nyimpen program ing format sing padha ing memori lan nyimpen program kanggo tape. Ing kasus, aku mriksa tembung kunci marang meja. Nanging, asil temenan negatif.

Aku uga mriksa tembung kunci BASIC saka Atari populer, Commodore 64 lan sawetara komputer liyane ing wektu iku, sing aku bisa nemokake dokumentasi, nanging tanpa sukses - kawruh saka jinis komputer retro dadi ora amba.

Banjur aku mutusake lunga dhaptar, banjur mripatku tiba ing jeneng pabrikan Radio Shack lan komputer TRS-80. Iki jeneng sing ditulis ing label kaset sing ana ing mejaku! Aku ora ngerti jeneng kasebut sadurunge lan ora kenal karo komputer TRS-80, mula aku rumangsa Radio Shack minangka produsen kaset audio kayata BASF, Sony utawa TDK, lan TRS-80 minangka wektu puter maneh. Ngapa ora?

Komputer Tandy/Radio Shack TRS-80

Kemungkinan rekaman audio kasebut, sing dakwenehake minangka conto ing wiwitan artikel, digawe ing komputer kaya mangkene:

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Ternyata komputer iki lan macem-macem (Model I / Model III / Model IV, lan sapiturute) banget populer ing sawijining wektu (mesthi, ora ing Rusia). Wigati dimangerteni manawa prosesor sing digunakake uga Z80. Kanggo komputer iki sampeyan bisa nemokake ing Internet akeh informasi. Ing taun 80-an, informasi komputer disebarake ing majalah. Ing wayahe ana sawetara emulator komputer kanggo platform beda.

Aku ngundhuh emulator trs80gp lan kanggo pisanan aku bisa ndeleng carane komputer iki bisa. Mesthine, komputer ora ndhukung output warna, resolusi layar mung 128x48 piksel, nanging ana akeh ekstensi lan modifikasi sing bisa nambah resolusi layar. Ana uga akeh opsi kanggo sistem operasi kanggo komputer iki lan opsi kanggo ngleksanakake basa BASIC (sing, ora kaya ZX Spectrum, ing sawetara model malah ora "flashed" menyang ROM lan opsi apa wae bisa dimuat saka floppy disk, kaya OS dhewe)

Aku uga ketemu sarana Ngonversi rekaman audio menyang format CAS, sing didhukung dening emulator, nanging sakperangan alesan ora bisa maca rekaman saka kaset sing digunakake.

Sawise ngerteni format file CAS (sing dadi salinan data saka tape sing wis ana, kajaba header sing ana bait sinkronisasi), aku nggawe sawetara owah-owahan ing programku lan bisa ngasilake file CAS sing bisa digunakake ing emulator (TRS-80 Model III):

Carane aku mbalekake data ing format sing ora dingerteni saka tape magnetik

Aku ngrancang versi paling anyar saka sarana konversi kanthi otomatis nemtokake pulsa pisanan lan jarak antarane pulsa referensi minangka paket GEM, kode sumber kasedhiya ing GitHub.

kesimpulan

Dalan sing wis kita lewati dadi perjalanan sing nyenengake ing jaman kepungkur, lan aku bungah yen pungkasane aku nemokake jawaban kasebut. Antarane liyane, aku:

  • Aku ngerteni format kanggo nyimpen data ing ZX Spectrum lan sinau rutin ROM sing dibangun kanggo nyimpen / maca data saka kaset audio
  • Aku kenal karo komputer TRS-80 lan macem-macem, sinau sistem operasi, ndeleng program sampel lan malah duwe kesempatan kanggo debugging ing kode mesin (sawise kabeh, kabeh mnemonik Z80 wis kenal karo aku).
  • Nulis sarana lengkap kanggo ngowahi rekaman audio menyang format CAS, sing bisa maca data sing ora diakoni dening sarana "resmi".

Source: www.habr.com

Add a comment