Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

prasajarah

Salaku pencinta hardware retro, kuring sakali mésér ZX Spectrum + ti anu ngajual di Inggris. Kaasup jeung komputer sorangan, abdi nampi sababaraha kaset audio jeung kaulinan (dina bungkusan aslina kalawan parentah), kitu ogé program dirékam dina kaset tanpa markings husus. Ahéngna, data tina kaset umur 40 taun tiasa dibaca saé sareng kuring tiasa ngaunduh ampir sadaya kaulinan sareng program ti aranjeunna.

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Nanging, dina sababaraha kaset kuring mendakan rékaman anu jelas henteu dilakukeun ku komputer ZX Spectrum. Aranjeunna disada lengkep béda sareng, teu sapertos rékaman tina komputer anu disebatkeun, aranjeunna henteu ngamimitian ku bootloader BASIC pondok, anu biasana aya dina rékaman sadaya program sareng kaulinan.

Pikeun sababaraha waktos ieu haunted kuring - Abdi hoyong pisan manggihan naon disumputkeun di aranjeunna. Upami anjeun tiasa maca sinyal audio salaku sekuen bait, anjeun tiasa milarian karakter atanapi naon waé anu nunjukkeun asal-usul sinyal. Hiji jenis retro-arkeologi.

Ayeuna kuring geus indit kabeh jalan jeung kasampak di labél tina kaset sorangan, kuring seuri sabab

jawaban éta katuhu dina hareupeun panon kuring sapanjang
Dina labél kaset kénca nyaéta nami komputer TRS-80, sareng di handapeun nami produsén: "Dihasilkeun ku Radio Shack di AS"

(Upami anjeun hoyong ngajaga intrik dugi ka akhir, ulah aya dina spoiler)

Babandingan sinyal audio

Anu mimiti, hayu urang ngadigitalkeun rékaman audio. Anjeun tiasa ngadangukeun naon sorana:


Sareng sapertos biasa rékaman tina komputer ZX Spectrum disada:


Dina duanana kasus, dina awal rekaman aya nu disebut nada pilot - sora tina frékuénsi anu sarua (dina rekaman kahiji pondok pisan <1 detik, tapi bisa dibédakeun). Nada pilot sinyal komputer pikeun nyiapkeun pikeun nampa data. Sakumaha aturan, unggal komputer ngan ngakuan nada pilot "sorangan" ku bentuk sinyal sareng frékuénsina.

Ieu perlu ngomong hal ngeunaan bentuk sinyal sorangan. Contona, dina ZX Spectrum bentukna rectangular:

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Nalika nada pilot dideteksi, spéktrum ZX mintonkeun bar beureum jeung biru bolak dina wates layar pikeun nunjukkeun yén sinyal geus dipikawanoh. Nada pilot tungtung pulsa sinkro, nu sinyal komputer pikeun ngamimitian narima data. Hal ieu dicirikeun ku durasi anu langkung pondok (dibandingkeun sareng nada pilot sareng data saterasna) (tingali gambar)

Saatos pulsa singkronisasi ditampi, komputer ngarékam unggal naékna / ragrag sinyal, ngukur durasina. Lamun lilana kirang ti wates nu tangtu, bit 1 ditulis kana mémori, disebutkeun 0. Bit dikumpulkeun kana bait jeung prosés nu terus-terusan nepi ka N bait narima. Jumlah N biasana dicokot tina lulugu file diundeur. Urutan loading nyaéta kieu:

  1. nada pilot
  2. lulugu (panjangna tetep), ngandung ukuran data diundeur (N), ngaran file jeung tipe
  3. nada pilot
  4. data sorangan

Pikeun mastikeun yén data dimuat leres, maca ZX Spéktrum nu disebut bait paritas (parity byte), anu diitung nalika nyimpen file ku XORing sadaya bait tina data ditulis. Nalika maca file, komputer ngitung parity byte tina data anu ditampi sareng, upami hasilna bénten sareng anu disimpen, nampilkeun pesen kasalahan "R Tape loading error". Tegesna, komputer tiasa ngaluarkeun pesen ieu sateuacanna upami, nalika maca, teu tiasa ngenal pulsa (lasut atanapi durasina henteu saluyu sareng wates anu tangtu)

Janten, hayu urang tingali kumaha sinyal anu teu dipikanyaho:

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Ieu nada pilot. Bentuk sinyal béda sacara signifikan, tapi écés yén sinyalna diwangun ku ngulang pulsa pondok tina frékuénsi anu tangtu. Dina frékuénsi sampling 44100 Hz, jarak antara "puncak" kira-kira 48 sampel (anu pakait jeung frékuénsi ~918 Hz). Hayu urang inget inohong ieu.

Hayu urang ayeuna ningali fragmen data:

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Lamun urang ngukur jarak antara pulsa individu, tétéla yén jarak antara pulsa "panjang" masih ~ 48 sampel, sarta antara leuwih pondok - ~ 24. Ningali payun sakedik, kuring bakal nyarios yén tungtungna tétéla yén "rujukan" pulsa kalayan frékuénsi 918 Hz terus-terusan, ti mimiti dugi ka ahir file. Bisa nganggap yén nalika ngirimkeun data, upami aya pulsa tambahan di antara pulsa rujukan, urang nganggap bit 1, disebutkeun 0.

Kumaha upami pulsa singkronisasi? Hayu urang nempo awal data:

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Nada pilot réngsé sarta data dimimitian langsung. Sakedap deui, saatos nganalisa sababaraha rékaman audio anu béda, kami tiasa mendakan yén bait data anu munggaran sami (10100101b, A5h). Komputer tiasa ngamimitian maca data saatos nampi éta.

Anjeun oge bisa nengetan shift tina pulsa rujukan munggaran langsung saatos 1 panungtungan dina bait singkronisasi. Kapanggihna engké dina prosés ngembangkeun program pangakuan data, nalika data dina awal file henteu tiasa dibaca sacara stabil.

Ayeuna hayu urang coba ngajelaskeun algoritma anu bakal ngolah file audio sareng ngamuat data.

Ngamuat Data

Mimiti, hayu urang tingali sababaraha asumsi pikeun ngajaga algoritma saderhana:

  1. Urang ngan bakal mertimbangkeun payil dina format WAV;
  2. Payil audio kudu dimimitian ku nada pilot jeung teu kudu ngandung tiiseun di awal
  3. Berkas sumber kedah gaduh laju sampling 44100 Hz. Dina hal ieu, jarak antara pulsa rujukan tina 48 sampel geus ditangtukeun sarta kami teu perlu ngitung eta programmatically;
  4. Format sampel tiasa wae (8/16 bit / floating point) - saprak nalika maca urang bisa ngarobah ka nu dipikahoyong;
  5. Kami nganggap yén file sumber dinormalisasi ku amplitudo, anu kedah nyaimbangkeun hasilna;

Algoritma bacaan bakal kieu:

  1. Kami maca file kana mémori, dina waktos anu sami ngarobih format sampel kana 8 bit;
  2. Nangtukeun posisi pulsa munggaran dina data audio. Jang ngalampahkeun ieu, anjeun kudu ngitung jumlah sampel kalawan amplitudo maksimum. Pikeun kesederhanaan, urang bakal ngitung sakali sacara manual. Hayu urang simpen kana variabel prev_pos;
  3. Tambahkeun 48 kana posisi pulsa panungtungan (pos:= prev_pos + 48)
  4. Kusabab ngaronjatkeun posisi ku 48 teu ngajamin yén urang bakal meunang ka posisi pulsa rujukan salajengna (cacat pita, operasi teu stabil tina mékanisme tape drive, jeung sajabana), urang kudu nyaluyukeun posisi pulsa pos. Jang ngalampahkeun ieu, nyandak sapotong leutik data (pos-8; pos + 8) sarta manggihan nilai amplitudo maksimum dina eta. Posisi anu cocog sareng maksimal bakal disimpen dina pos. Di dieu 8 = 48/6 mangrupa konstanta diala sacara ékspériméntal, nu ngajamin yén urang bakal nangtukeun maksimum bener jeung moal mangaruhan impulses séjén nu bisa jadi caket dieu. Dina kasus pisan goréng, nalika jarak antara pulsa teuing kirang ti atawa leuwih gede ti 48, anjeun tiasa nerapkeun pilarian kapaksa pikeun pulsa, tapi dina lingkup artikel kuring moal ngajelaskeun ieu dina algoritma nu;
  5. Dina lengkah samemehna, éta ogé bakal diperlukeun pikeun pariksa yen pulsa rujukan kapanggih pisan. Nyaéta, upami anjeun ngan ukur milarian maksimal, ieu henteu ngajamin yén dorongan aya dina bagean ieu. Dina palaksanaan program bacaan panganyarna kuring, kuring pariksa bédana antara nilai amplitudo maksimum sareng minimum dina ruas, sareng upami éta ngaleuwihan wates anu tangtu, kuring ngitung ayana dorongan. Patarosan ogé naon anu kudu dipigawé lamun pulsa rujukan teu kapanggih. Aya 2 pilihan: boh data parantos réngsé sareng tiiseun nuturkeun, atanapi ieu kedah dianggap kasalahan maca. Nanging, urang bakal ngaleungitkeun ieu pikeun nyederhanakeun algoritma;
  6. Dina lengkah saterusna, urang kudu nangtukeun ayana pulsa data (bit 0 atawa 1), pikeun ieu urang nyokot tengah ruas (prev_pos;pos) middle_pos sarua jeung middle_pos := (prev_pos+pos)/2 jeung di sababaraha lingkungan middle_pos on ruas (middle_pos-8;middle_pos +8) hayu urang ngitung amplitudo maksimum sarta minimum. Lamun bédana antara aranjeunna leuwih ti 10, urang nulis bit 1 kana hasilna, disebutkeun 0. 10 mangrupakeun konstanta diala ékspériméntal;
  7. Simpen posisi ayeuna di prev_pos (prev_pos := pos)
  8. Ngulang mimitian ti hambalan 3 nepi ka urang maca sakabéh file;
  9. Asép Sunandar Sunarya bit nu dihasilkeun kudu disimpen salaku sakumpulan bait. Kusabab urang teu tumut kana akun bait singkronisasi nalika maca, jumlah bit bisa jadi sababaraha kali 8, sarta bit offset diperlukeun ogé kanyahoan. Dina palaksanaan mimiti algoritma, kuring henteu terang ngeunaan ayana bait singkronisasi sahingga ngan saukur disimpen 8 file kalayan jumlah bit offset anu béda. Salah sahijina ngandung data anu leres. Dina algoritma ahir, kuring ngan saukur miceun kabeh bit nepi ka A5h, nu ngidinan kuring langsung meunangkeun file kaluaran bener

Algoritma dina Ruby, pikeun maranéhanana kabetot
Kuring milih Ruby salaku basa pikeun nulis program, sabab... Kuring program dina lolobana waktu. Pilihanna henteu berkinerja tinggi, tapi tugas pikeun ngagancangkeun maca gancang-gancang henteu 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*")

hasil

Saatos nyobian sababaraha varian algoritma sareng konstanta, kuring untung nampi anu pikaresepeun pisan:

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Janten, ditilik ku senar karakter, urang gaduh program pikeun ngarencanakeun grafik. Nanging, henteu aya kecap konci dina téks program. Sadaya kecap konci disandikeun salaku bait (unggal nilai> 80h). Ayeuna urang kudu manggihan komputer mana ti 80s bisa nyimpen program dina format ieu.

Nyatana, éta mirip pisan sareng program BASIC. Komputer ZX Spectrum nyimpen program dina format nu sarua dina mémori jeung nyimpen program kana tape. Ngan bisi, kuring dipariksa kecap konci ngalawan méja. Sanajan kitu, hasilna éta écés négatip.

Kuring ogé pariksa kecap konci DASAR tina populér Atari, Commodore 64 sarta sababaraha komputer séjén waktu éta, nu kuring bisa manggihan dokuméntasi, tapi tanpa hasil - pangaweruh kuring ngeunaan jenis komputer retro tétéla teu jadi lega.

Saterusna kuring megatkeun pikeun indit daptar, lajeng gaze abdi murag kana nami produsén Radio Shack jeung komputer TRS-80. Ieu nami-nami anu diserat dina labél kasét anu ngagolér dina méja kuring! Kuring henteu terang nami-nami ieu sateuacanna sareng teu wawuh sareng komputer TRS-80, janten kuring sigana yén Radio Shack mangrupikeun produsén kaset audio sapertos BASF, Sony atanapi TDK, sareng TRS-80 mangrupikeun waktos playback. Naha henteu?

Komputer Tandy / Radio shack TRS-80

Kamungkinan pisan yén rékaman audio anu ditaroskeun, anu kuring masihan conto dina awal tulisan, dilakukeun dina komputer sapertos kieu:

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Tétéla yén komputer ieu sareng variétas na (Modél I / Modél III / Modél IV, jsb) éta pohara populér dina hiji waktu (tangtu, teu di Rusia). Éta noteworthy yén processor aranjeunna dipaké ogé Z80. Pikeun komputer ieu anjeun tiasa mendakan dina Internét loba informasi. Dina 80s, informasi komputer ieu disebarkeun di majalah. Di momen aya sababaraha émulator komputer pikeun platform béda.

Kuring ngundeur émulator trs80gp sarta pikeun kahiji kalina kuring bisa ningali kumaha komputer ieu jalan. Tangtosna, komputer henteu ngadukung kaluaran warna, resolusi layar ngan ukur 128x48 piksel, tapi aya seueur ekstensi sareng modifikasi anu tiasa ningkatkeun resolusi layar. Aya ogé seueur pilihan pikeun sistem operasi pikeun komputer ieu sareng pilihan pikeun nerapkeun basa BASIC (anu, teu sapertos ZX Spectrum, dina sababaraha modél henteu "dipasang" kana ROM sareng pilihan naon waé tiasa dimuat tina floppy disk, sapertos. OS sorangan)

Kuring ogé kapanggih utilitas pikeun ngarobih rékaman audio kana format CAS, anu dirojong ku émulator, tapi pikeun sababaraha alesan éta henteu tiasa maca rékaman tina kaset kuring ngagunakeunana.

Saatos ngartos format file CAS (anu tétéla ngan ukur salinan data bit-demi-bit tina kasét anu parantos aya dina panangan, iwal ti header kalayan ayana bait singkronisasi), kuring ngadamel sababaraha parobihan kana program kuring sareng tiasa ngaluarkeun file CAS anu tiasa dianggo dina émulator (TRS-80 Model III):

Kumaha kuring pulih data dina format anu teu dipikanyaho tina pita magnét

Kuring mendesain versi panganyarna tina utilitas konvérsi kalayan tekad otomatis tina pulsa munggaran sareng jarak antara pulsa rujukan salaku pakét GEM, kode sumberna sayogi di Github.

kacindekan

Jalan anu kami tempuh tétéla janten perjalanan anu pikaresepeun ka jaman baheula, sareng kuring bungah yén tungtungna kuring mendakan jawaban. Diantara hal séjén, kuring:

  • Kuring terang format pikeun nyimpen data dina ZX Spectrum sareng diajar rutin ROM anu diwangun pikeun nyimpen / maca data tina kaset audio.
  • Abdi kenal sareng komputer TRS-80 sareng variétasna, diajar sistem operasi, ningali program sampel sareng malah ngagaduhan kasempetan pikeun debugging dina kode mesin (sanggeus sadayana, sadaya mnemonik Z80 akrab pikeun kuring).
  • Nulis utilitas lengkep pikeun ngarobih rékaman audio kana format CAS, anu tiasa maca data anu henteu dikenal ku utilitas "resmi".

sumber: www.habr.com

Tambahkeun komentar