Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

preistorja

Peress li dilettant tal-ħardwer retro, darba xtrajt ZX Spectrum+ mingħand bejjiegħ fir-Renju Unit. Inkluż mal-kompjuter innifsu, irċevejt bosta cassettes awdjo b'logħob (fl-imballaġġ oriġinali bl-istruzzjonijiet), kif ukoll programmi rreġistrati fuq cassettes mingħajr marki speċjali. B'mod sorprendenti, data minn cassettes ta '40 sena kienet tinqara tajjeb u stajt inniżżel kważi l-logħob u l-programmi kollha minnhom.

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Madankollu, fuq xi cassettes sibt reġistrazzjonijiet li b'mod ċar ma sarux mill-kompjuter ZX Spectrum. Dawn ħossu kompletament differenti u, b'differenza mir-reġistrazzjonijiet mill-kompjuter imsemmi, ma bdewx b'bootloader BASIC qasir, li normalment ikun preżenti fir-reġistrazzjonijiet tal-programmi u l-logħob kollha.

Għal xi żmien dan għamilli - ridt ħafna nsib x'kien moħbi fihom. Jekk tista' taqra s-sinjal tal-awdjo bħala sekwenza ta' bytes, tista' tfittex karattri jew xi ħaġa li tindika l-oriġini tas-sinjal. Tip ta’ retro-arkeoloġija.

Issa li mort it-triq kollha u nħares lejn it-tikketti tal-cassettes infushom, nitbissem għax

it-tweġiba kienet dritt quddiem għajnejja kollha kemm hi
Fuq it-tikketta tal-cassette tax-xellug hemm l-isem tal-kompjuter TRS-80, u eżatt taħt l-isem tal-manifattur: "Mmanifatturat minn Radio Shack fl-Istati Uniti"

(Jekk trid iżżomm l-intrigue sal-aħħar, tmurx taħt l-ispoiler)

Tqabbil ta 'sinjali awdjo

L-ewwelnett, ejja diġitalizzaw ir-reġistrazzjonijiet awdjo. Tista' tisma' kif tinstema':


U bħas-soltu l-irrekordjar mill-kompjuter ZX Spectrum ħsejjes:


Fiż-żewġ każijiet, fil-bidu tar-reġistrazzjoni hemm hekk imsejħa ton pilota - ħoss ta' l-istess frekwenza (fl-ewwel reġistrazzjoni huwa qasir ħafna <1 sekonda, iżda jingħaraf). It-ton pilota jindika lill-kompjuter biex jipprepara biex jirċievi data. Bħala regola, kull kompjuter jirrikonoxxi biss it-ton pilota "proprju" tiegħu mill-forma tas-sinjal u l-frekwenza tiegħu.

Huwa meħtieġ li tgħid xi ħaġa dwar il-forma tas-sinjal innifsu. Pereżempju, fuq iż-ZX Spectrum il-forma tiegħu hija rettangolari:

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Meta tone pilota jiġi skopert, iż-ZX Spectrum juri vireg ħomor u blu alternanti fuq il-fruntiera tal-iskrin biex jindika li s-sinjal ġie rikonoxxut. It-ton pilota jintemm polz synchro, li jindika lill-kompjuter biex jibda jirċievi data. Huwa kkaratterizzat minn tul iqsar (meta mqabbel mat-ton pilota u d-dejta sussegwenti) (ara l-figura)

Wara li jiġi riċevut il-polz tas-sinkronizzazzjoni, il-kompjuter jirreġistra kull żieda/waqgħa tas-sinjal, u jkejjel it-tul tiegħu. Jekk it-tul ikun inqas minn ċertu limitu, il-bit 1 jinkiteb fil-memorja, inkella 0. Il-bits jinġabru f'bytes u l-proċess jiġi ripetut sakemm jiġu riċevuti N bytes. In-numru N normalment jittieħed mill-header tal-fajl imniżżel. Is-sekwenza tat-tagħbija hija kif ġej:

  1. ton pilota
  2. header (tul fiss), fih id-daqs tad-data mniżżla (N), l-isem tal-fajl u t-tip
  3. ton pilota
  4. id-data nnifisha

Biex tiżgura li d-dejta titgħabba b'mod korrett, iż-ZX Spectrum jaqra l-hekk imsejjaħ byte ta' parità (byte tal-parità), li jiġi kkalkulat meta jiġi salvat fajl billi XORing il-bytes kollha tad-dejta miktuba. Meta jaqra fajl, il-kompjuter jikkalkula l-byte tal-parità mid-dejta riċevuta u, jekk ir-riżultat ikun differenti minn dak salvat, juri l-messaġġ ta 'żball "R Tape loading error". Strettament, il-kompjuter jista' joħroġ dan il-messaġġ aktar kmieni jekk, meta jaqra, ma jkunx jista' jagħraf polz (mitluf jew it-tul tiegħu ma jikkorrispondix għal ċerti limiti)

Allura, ejja issa naraw kif jidher sinjal mhux magħruf:

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Dan huwa t-ton pilota. Il-forma tas-sinjal hija differenti b'mod sinifikanti, iżda huwa ċar li s-sinjal jikkonsisti f'repetizzjoni ta 'impulsi qosra ta' ċerta frekwenza. Fi frekwenza ta 'kampjunar ta' 44100 Hz, id-distanza bejn il-"qċaċet" hija ta 'madwar 48 kampjun (li tikkorrispondi għal frekwenza ta' ~ 918 Hz). Ejja niftakru din il-figura.

Ejja issa nħarsu lejn il-framment tad-dejta:

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Jekk inkejlu d-distanza bejn impulsi individwali, jirriżulta li d-distanza bejn impulsi "twil" għadha ~ 48 kampjun, u bejn dawk qosra - ~ 24. Meta nħares 'il quddiem ftit, se ngħid li fl-aħħar irriżulta li impulsi ta' "referenza" bi frekwenza ta '918 Hz isegwu kontinwament, mill-bidu sat-tmiem tal-fajl. Wieħed jista' jassumi li meta tittrażmetti d-data, jekk jiltaqa 'ma' polz addizzjonali bejn l-impulsi ta' referenza, inqisuha bħala bit 1, inkella 0.

Xi ngħidu dwar il-polz tas-sinkronizzazzjoni? Ejja nħarsu lejn il-bidu tad-dejta:

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

It-ton pilota jintemm u d-data tibda immedjatament. Ftit aktar tard, wara li analizzajna diversi reġistrazzjonijiet awdjo differenti, stajna niskopru li l-ewwel byte tad-dejta huwa dejjem l-istess (10100101b, A5h). Il-kompjuter jista' jibda jaqra d-dejta wara li jirċeviha.

Tista 'wkoll tagħti attenzjoni għaċ-ċaqliq tal-ewwel polz ta' referenza immedjatament wara l-aħħar 1 fil-byte tas-sinkronizzazzjoni. Ġie skopert ħafna aktar tard fil-proċess tal-iżvilupp ta 'programm ta' rikonoxximent tad-dejta, meta d-dejta fil-bidu tal-fajl ma setgħetx tinqara b'mod stabbli.

Issa ejja nippruvaw niddeskrivu algoritmu li se jipproċessa fajl awdjo u tagħbija data.

Tagħbija tad-Dejta

L-ewwel, ejja nħarsu lejn ftit suppożizzjonijiet biex iżommu l-algoritmu sempliċi:

  1. Aħna se nikkunsidraw biss fajls fil-format WAV;
  2. Il-fajl awdjo għandu jibda b'ton pilota u m'għandux ikun fih silenzju fil-bidu
  3. Il-fajl tas-sors għandu jkollu rata ta' kampjunar ta' 44100 Hz. F'dan il-każ, id-distanza bejn il-polz ta 'referenza ta' 48 kampjun hija diġà determinata u m'għandniex bżonn nikkalkulawha b'mod programmatiku;
  4. Il-format tal-kampjun jista 'jkun kwalunkwe (8/16 bits/floating point) - peress li meta naqraw nistgħu jaqilbuh għal dak mixtieq;
  5. Nassumu li l-fajl tas-sors huwa normalizzat bl-amplitudni, li għandha tistabbilizza r-riżultat;

L-algoritmu tal-qari se jkun kif ġej:

  1. Naqraw il-fajl fil-memorja, fl-istess ħin nikkonverti l-format tal-kampjun għal 8 bits;
  2. Iddetermina l-pożizzjoni tal-ewwel polz fid-dejta tal-awdjo. Biex tagħmel dan, għandek bżonn tikkalkula n-numru tal-kampjun bl-amplitudni massima. Għal sempliċità, aħna se nikkalkulawha darba manwalment. Ejja nissejvjah fil-varjabbli prev_pos;
  3. Żid 48 mal-pożizzjoni tal-aħħar polz (pos := prev_pos + 48)
  4. Peress li ż-żieda tal-pożizzjoni bi 48 ma tiggarantixxix li se naslu għall-pożizzjoni tal-polz ta 'referenza li jmiss (difetti tat-tejp, tħaddim instabbli tal-mekkaniżmu tas-sewqan tat-tejp, eċċ.), għandna bżonn naġġustaw il-pożizzjoni tal-polz pos. Biex tagħmel dan, ħu biċċa żgħira ta 'dejta (pos-8;pos+8) u sib il-valur massimu tal-amplitudni fuqha. Il-pożizzjoni li tikkorrispondi għall-massimu se tkun maħżuna f'pos. Hawnhekk 8 = 48/6 hija kostanti miksuba b'mod sperimentali, li tiggarantixxi li se niddeterminaw il-massimu korrett u mhux se taffettwa impulsi oħra li jistgħu jkunu fil-qrib. F'każijiet ħżiena ħafna, meta d-distanza bejn il-polz hija ħafna inqas minn jew akbar minn 48, tista 'timplimenta tfittxija sfurzata għal polz, iżda fl-ambitu tal-artikolu mhux se niddeskrivi dan fl-algoritmu;
  5. Fil-pass preċedenti, ikun meħtieġ ukoll li jiġi ċċekkjat li l-polz ta 'referenza instab għal kollox. Jiġifieri, jekk sempliċement tfittex il-massimu, dan ma jiggarantixxix li l-impuls ikun preżenti f'dan is-segment. Fl-aħħar implimentazzjoni tiegħi tal-programm tal-qari, niċċekkja d-differenza bejn il-valuri ta 'amplitudni massimi u minimi fuq segment, u jekk taqbeż ċertu limitu, ngħodd il-preżenza ta' impuls. Il-mistoqsija hija wkoll x'għandek tagħmel jekk il-polz ta 'referenza ma jinstabx. Hemm 2 għażliet: jew id-data tkun intemmet u wara s-silenzju, jew dan għandu jitqies bħala żball tal-qari. Madankollu, aħna se nħallu dan biex nissimplifikaw l-algoritmu;
  6. Fil-pass li jmiss, irridu niddeterminaw il-preżenza ta 'polz tad-data (bit 0 jew 1), għal dan nieħdu n-nofs tas-segment (prev_pos;pos) middle_pos ugwali għal middle_pos := (prev_pos+pos)/2 u f'xi lokal ta 'middle_pos fuq is-segment (middle_pos-8; middle_pos +8) ejja nikkalkulaw l-amplitudni massima u minima. Jekk id-differenza bejniethom hija aktar minn 10, niktbu bit 1 fir-riżultat, inkella 0. 10 hija kostanti miksuba b'mod sperimentali;
  7. Issejvja l-pożizzjoni attwali fi prev_pos (prev_pos := pos)
  8. Irrepeti billi tibda mill-pass 3 sakemm naqraw il-fajl kollu;
  9. L-array tal-bit li jirriżulta għandu jiġi ssejvjat bħala sett ta' bytes. Peress li aħna ma qisniex is-sinkronizzazzjoni tal-byte meta qari, in-numru ta 'bits jista' ma jkunx multiplu ta '8, u l-offset tal-bit meħtieġ huwa wkoll mhux magħruf. Fl-ewwel implimentazzjoni tal-algoritmu, ma kontx naf dwar l-eżistenza tal-byte tas-sinkronizzazzjoni u għalhekk sempliċement salvajt 8 fajls b'numri differenti ta 'offset bits. Wieħed minnhom kien fih data korretta. Fl-algoritmu finali, sempliċement inneħħi l-bits kollha sa A5h, li jippermettili li nġib immedjatament il-fajl tal-output korrett

Algoritmu f'Ruby, għal dawk interessati
Għażilt Ruby bħala l-lingwa għall-kitba tal-programm, għax... Nipprogramma fuqha ħafna mill-ħin. L-għażla mhix ta 'prestazzjoni għolja, iżda l-kompitu li tagħmel il-veloċità tal-qari malajr kemm jista' jkun mhix worth it.

# Используем 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*")

Riżultat

Wara li ppruvajt diversi varjanti tal-algoritmu u l-kostanti, kont xortik tajba li ġġib xi ħaġa estremament interessanti:

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Allura, meta wieħed jiġġudika mill-kordi tal-karattri, għandna programm għall-plotting graphs. Madankollu, m'hemm l-ebda kliem ewlieni fit-test tal-programm. Il-kliem kjavi kollha huma kodifikati bħala bytes (kull valur > 80h). Issa għandna bżonn insibu liema kompjuter mis-snin 80 jista 'jiffranka programmi f'dan il-format.

Fil-fatt, huwa simili ħafna għal programm BAŻIKU. Il-kompjuter ZX Spectrum jaħżen programmi bejn wieħed u ieħor fl-istess format fil-memorja u jiffranka programmi fuq tejp. Fil-każ, ikkontrollajt il-kliem kjavi kontra mejda. Madankollu, ir-riżultat kien ovvjament negattiv.

Iċċekkjajt ukoll il-kliem ewlieni BAŻIKU tal-Atari popolari, Commodore 64 u diversi kompjuters oħra ta 'dak iż-żmien, li għalihom stajt insib dokumentazzjoni, iżda mingħajr suċċess - l-għarfien tiegħi tat-tipi ta' kompjuters retro irriżulta li ma kienx daqshekk wiesa '.

Imbagħad iddeċidejt li mmur il-lista, u mbagħad ħarsa tiegħi waqgħet fuq l-isem tal-manifattur Radio Shack u l-kompjuter TRS-80. Dawn huma l-ismijiet li kienu miktuba fuq it-tikketti tal-cassettes li kienu fuq il-mejda tiegħi! Ma kontx naf dawn l-ismijiet qabel u ma kontx familjari mal-kompjuter TRS-80, għalhekk deherli li Radio Shack kien manifattur tal-cassettes tal-awdjo bħal BASF, Sony jew TDK, u t-TRS-80 kien il-ħin tal-plejbek. Għaliex le?

Kompjuter Tandy/Radio Shack TRS-80

Huwa probabbli ħafna li r-reġistrazzjoni tal-awdjo inkwistjoni, li tajt bħala eżempju fil-bidu tal-artiklu, saret fuq kompjuter bħal dan:

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Irriżulta li dan il-kompjuter u l-varjetajiet tiegħu (Mudell I/Mudell III/Mudell IV, eċċ.) Kienu popolari ħafna f'ħin wieħed (naturalment, mhux fir-Russja). Ta’ min jinnota li l-proċessur li użaw kien ukoll Z80. Għal dan il-kompjuter tista 'ssib fuq l-Internet ħafna informazzjoni. Fis-snin 80, l-informazzjoni tal-kompjuter kienet imqassma fi rivisti. Bħalissa hemm diversi emulaturi kompjuters għal pjattaformi differenti.

Niżżilt l-emulatur trs80gp u għall-ewwel darba stajt nara kif jaħdem dan il-kompjuter. Naturalment, il-kompjuter ma appoġġax l-output tal-kulur; ir-riżoluzzjoni tal-iskrin kienet biss 128x48 pixel, iżda kien hemm ħafna estensjonijiet u modifiki li setgħu jżidu r-riżoluzzjoni tal-iskrin. Kien hemm ukoll ħafna għażliet għal sistemi operattivi għal dan il-kompjuter u għażliet għall-implimentazzjoni tal-lingwa BAŻIKA (li, b'differenza mill-ZX Spectrum, f'xi mudelli lanqas biss kienet "flashed" f'ROM u kwalunkwe għażla setgħet titgħabba minn floppy disk, bħal l-OS innifsu)

sibt ukoll utilità biex tikkonverti reġistrazzjonijiet awdjo f'format CAS, li huwa appoġġjat minn emulaturi, iżda għal xi raġuni ma kienx possibbli li taqra reġistrazzjonijiet mill-cassettes tiegħi bl-użu tagħhom.

Wara li sibt il-format tal-fajl CAS (li rriżulta li kien biss kopja bit-bit tad-dejta mit-tejp li diġà kelli f'idejna, ħlief għall-header bil-preżenza ta 'byte tas-sinkronizzazzjoni), għamilt ftit bidliet fil-programm tiegħi u setgħet toħroġ fajl CAS li jaħdem li ħadem fl-emulator (TRS-80 Mudell III):

Kif irkuprajt data f'format mhux magħruf minn tejp manjetiku

Iddisinja l-aħħar verżjoni tal-utilità ta 'konverżjoni b'determinazzjoni awtomatika tal-ewwel polz u d-distanza bejn impulsi ta' referenza bħala pakkett GEM, il-kodiċi tas-sors huwa disponibbli fuq GitHub.

Konklużjoni

It-triq li vvjaġġajna rriżultat bħala vjaġġ affaxxinanti fil-passat, u ninsab ferħan li fl-aħħar sibt it-tweġiba. Fost affarijiet oħra, jien:

  • I dehret il-format għall-iffrankar tad-dejta fiż-ZX Spectrum u studjajt ir-rutini ROM integrati għall-iffrankar/qari tad-dejta minn kasetts awdjo
  • Sirt familjari mal-kompjuter TRS-80 u l-varjetajiet tiegħu, studjajt is-sistema operattiva, ħares lejn programmi ta 'kampjun u anke kelli l-opportunità li nagħmel debugging f'kodiċijiet tal-magni (wara kollox, l-mnemoniċi Z80 kollha huma familjari għalija)
  • Kitbet utilità sħiħa għall-konverżjoni ta 'reġistrazzjonijiet awdjo f'format CAS, li tista' taqra data li mhix rikonoxxuta mill-utilità "uffiċjali"

Sors: www.habr.com

Żid kumment