Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

prehistory

Kasancewa mai son kayan aikin retro, Na taɓa siyan ZX Spectrum+ daga mai siyarwa a Burtaniya. Haɗe da kwamfutar kanta, na karɓi kaset ɗin sauti da yawa tare da wasanni (a cikin marufi na asali tare da umarni), da kuma shirye-shiryen da aka rubuta akan kaset ɗin ba tare da alamun musamman ba. Abin mamaki, bayanai daga kaset na shekaru 40 ana iya karanta su sosai kuma na sami damar sauke kusan dukkanin wasanni da shirye-shirye daga gare su.

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Duk da haka, a wasu kaset na sami rikodin da ba a yi su a fili ta hanyar ZX Spectrum ba. Sun yi sauti daban-daban kuma, ba kamar faifan rikodin daga kwamfutar da aka ambata ba, ba su fara da ɗan gajeren bootloader na BASIC ba, wanda yawanci ke kasancewa a cikin rikodin duk shirye-shiryen da wasanni.

Na ɗan lokaci wannan ya dame ni - Ina so in gano abin da ke ɓoye a cikinsu. Idan zaka iya karanta siginar mai jiwuwa azaman jeri na bytes, zaku iya nemo haruffa ko duk wani abu da ke nuna asalin siginar. Wani irin retro-archaeology.

Yanzu da na bi hanya na duba lakabin kaset ɗin da kansu, na yi murmushi saboda

amsar tana gaban idona gaba daya
A kan lakabin kaset na hagu akwai sunan kwamfutar TRS-80, kuma a ƙasa da sunan masana'anta: "Radiyo Shack ne ya kera a Amurka"

(Idan kuna son kiyaye makircin har zuwa ƙarshe, kar ku shiga ƙarƙashin mai ɓarna)

Kwatanta siginar sauti

Da farko, bari mu yi digitize rikodin sauti. Kuna iya sauraron yadda sauti yake:


Kuma kamar yadda aka saba rikodi daga kwamfutar ZX Spectrum yana sauti:


A cikin lokuta biyu, a farkon rikodin akwai abin da ake kira sautin matukin jirgi - sautin mita iri ɗaya (a cikin rikodin farko yana da ɗan gajeren lokaci <1 seconds, amma ana iya bambanta). Sautin matukin jirgi yana sigina kwamfutar don shirya don karɓar bayanai. A matsayinka na mai mulki, kowace kwamfuta tana gane sautin matukinta na “nata” ne kawai ta hanyar siginar da mitar ta.

Wajibi ne a faɗi wani abu game da siginar siginar kanta. Misali, akan ZX Spectrum siffarsa tana da rectangular:

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Lokacin da aka gano sautin matukin jirgi, ZX Spectrum yana nuna madaidaicin sanduna ja da shuɗi a kan iyakar allo don nuna cewa an gane siginar. Sautin matukin jirgi ya ƙare bugun jini synchro, wanda ke nuna alamar kwamfutar ta fara karɓar bayanai. Yana da ɗan gajeren lokaci (idan aka kwatanta da sautin matukin jirgi da bayanan da ke gaba) (duba adadi)

Bayan an karɓi bugun bugun sync, kwamfutar tana yin rikodin kowace tashi/faɗuwar siginar, tana auna tsawon lokacinta. Idan tsawon lokacin bai wuce ƙayyadaddun iyaka ba, an rubuta bit 1 zuwa ƙwaƙwalwar ajiya, in ba haka ba 0. Ana tattara raƙuman raƙuman ruwa zuwa bytes kuma ana maimaita tsari har sai an karɓi N bytes. Yawanci ana ɗaukar lambar N daga taken fayil ɗin da aka sauke. Jerin loading shine kamar haka:

  1. sautin matukin jirgi
  2. header (tsawon kafaffen), ya ƙunshi girman bayanan da aka sauke (N), sunan fayil da nau'in
  3. sautin matukin jirgi
  4. data kanta

Don tabbatar da cewa an loda bayanan daidai, ZX Spectrum yana karanta abin da ake kira parity byte (Parity byte), wanda ake ƙididdigewa lokacin adana fayil ta hanyar XORing duk bytes na bayanan da aka rubuta. Lokacin karanta fayil, kwamfutar tana ƙididdige byte na daidaito daga bayanan da aka karɓa kuma, idan sakamakon ya bambanta da wanda aka ajiye, yana nuna saƙon kuskure "R Tape loading error". A taƙaice, kwamfutar za ta iya fitar da wannan saƙon a baya idan, lokacin karantawa, ba za ta iya gane bugun bugun jini ba (wanda aka rasa ko tsawon lokacinsa bai dace da wasu iyaka ba).

Don haka, bari yanzu mu ga yadda siginar da ba a sani ba yayi kama:

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Wannan shine sautin matukin jirgi. Siffar siginar ta bambanta sosai, amma a bayyane yake cewa siginar ya ƙunshi maimaita gajerun bugun jini na wani mitar. A mitar samfurin 44100 Hz, nisa tsakanin "kololuwa" shine kusan samfurori 48 (wanda ya dace da mita ~ 918 Hz) Bari mu tuna wannan adadi.

Yanzu bari mu kalli guntun bayanan:

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Idan muka auna nesa tsakanin mutum ya wuce, sai ya juya cewa nisa tsakanin "doguwar" sasples, da kuma tsakanin gajere - ~ 48. Neman gaba kaɗan, zan faɗi cewa a ƙarshe ya juya cewa "nassoshi" bugun jini tare da mitar 24 Hz suna ci gaba da bi, daga farkon zuwa ƙarshen fayil ɗin. Ana iya ɗauka cewa lokacin watsa bayanai, idan an sami ƙarin bugun jini tsakanin bugun jini, muna ɗaukar shi a matsayin bit 918, in ba haka ba 1.

Me game da bugun jini na sync? Bari mu kalli farkon bayanan:

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Sautin matukin jirgi ya ƙare kuma bayanan sun fara nan da nan. Bayan ɗan lokaci kaɗan, bayan nazarin rikodin rikodin sauti daban-daban, mun sami damar gano cewa byte na farko na bayanai koyaushe iri ɗaya ne (10100101b, A5h). Kwamfuta na iya fara karanta bayanai bayan ta karba.

Hakanan zaka iya kula da motsi na bugun bugun farko kai tsaye bayan 1st na ƙarshe a cikin byte daidaitawa. An gano shi da yawa daga baya a cikin aiwatar da haɓaka shirin tantance bayanai, lokacin da bayanan da ke farkon fayil ɗin ba a iya karanta su a tsaye.

Yanzu bari mu yi ƙoƙarin bayyana algorithm wanda zai aiwatar da fayil mai jiwuwa da loda bayanai.

Loading Data

Da farko, bari mu kalli wasu zato don kiyaye algorithm mai sauƙi:

  1. Za mu yi la'akari kawai fayiloli a cikin WAV format;
  2. Fayil mai jiwuwa dole ne ya fara da sautin matukin jirgi kuma kada ya ƙunshi shiru a farkon
  3. Dole ne fayil ɗin tushen ya kasance yana da ƙimar samfurin 44100 Hz. A wannan yanayin, an riga an ƙaddara nisa tsakanin nau'ikan nau'ikan nau'ikan nau'ikan nau'ikan 48 kuma ba mu buƙatar lissafta shi ta hanyar shirye-shirye;
  4. Tsarin samfurin zai iya zama kowane (8/16 bits / floating point) - tun lokacin karantawa za mu iya canza shi zuwa wanda ake so;
  5. Muna ɗauka cewa fayil ɗin tushen yana daidaitawa ta hanyar girma, wanda yakamata ya daidaita sakamakon;

Algorithm na karatun zai kasance kamar haka:

  1. Mun karanta fayil ɗin zuwa ƙwaƙwalwar ajiya, a lokaci guda muna canza tsarin samfurin zuwa 8 rago;
  2. Ƙayyade matsayin bugun bugun farko a cikin bayanan mai jiwuwa. Don yin wannan, kuna buƙatar ƙididdige adadin samfurin tare da matsakaicin girman girman. Don sauƙi, za mu lissafta shi sau ɗaya da hannu. Bari mu ajiye shi zuwa ga m prev_pos;
  3. Ƙara 48 zuwa matsayi na bugun jini na ƙarshe (pos: = prev_pos + 48)
  4. Tun da karuwar matsayi ta 48 ba ya bada garantin cewa za mu kai ga matsayi na bugun jini na gaba (lalacewar tef, aiki maras kyau na kayan aikin tef, da dai sauransu), muna buƙatar daidaita matsayi na bugun jini. Don yin wannan, ɗauki ƙaramin yanki na bayanai (pos-8;pos + 8) kuma nemo matsakaicin ƙimar girman girmansa. Matsayin da ya dace da matsakaicin za a adana shi a cikin pos. Anan 8 = 48/6 shine gwajin gwaji da aka samu akai-akai, wanda ke ba da tabbacin cewa za mu tantance iyakar daidai kuma ba zai shafi wasu abubuwan da za su iya kasancewa a kusa ba. A cikin mummunan yanayi, lokacin da nisa tsakanin bugun jini ya fi ƙasa da ko mafi girma fiye da 48, za ku iya aiwatar da bincike na tilasta bugun jini, amma a cikin iyakokin labarin ba zan kwatanta wannan a cikin algorithm ba;
  5. A mataki na baya, zai kuma zama dole a duba cewa an sami bugun jini kwata-kwata. Wato, idan kawai ka nemo mafi girma, wannan baya bada garantin cewa sha'awar ta kasance a cikin wannan sashin. A cikin sabon aiwatarwa na shirin karatun, na bincika bambanci tsakanin matsakaicin matsakaicin matsakaicin ƙimar girma akan wani yanki, kuma idan ya wuce ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun ƙayyadaddun abubuwa, Ina ƙididdige kasancewar buguwa. Tambayar ita ce kuma abin da za a yi idan ba a sami bugun bugun jini ba. Akwai zaɓuɓɓuka guda 2: ko dai bayanan sun ƙare kuma shiru ya biyo baya, ko kuma ya kamata a ɗauki wannan a matsayin kuskuren karatu. Duk da haka, za mu bar wannan don sauƙaƙe algorithm;
  6. A mataki na gaba, muna buƙatar sanin kasancewar bugun jini (bit 0 ko 1), saboda wannan muna ɗaukar tsakiyar ɓangaren (prev_pos; pos) middle_pos daidai da middle_pos : = (prev_pos + pos) / 2 da a wasu unguwannin middle_pos akan sashin (middle_pos-8; middle_pos +8) bari mu ƙididdige mafi girma da mafi ƙarancin girma. Idan bambancin da ke tsakanin su ya fi 10, za mu rubuta bit 1 a cikin sakamakon, in ba haka ba 0. 10 ne akai-akai samu ta hanyar gwaji;
  7. Ajiye matsayi na yanzu a prev_pos (prev_pos : = pos)
  8. Maimaita farawa daga mataki na 3 har sai mun karanta dukan fayil ɗin;
  9. Dole ne a adana sakamakon bit array azaman saitin bytes. Tun da ba mu yi la'akari da byte na daidaitawa lokacin karantawa ba, adadin ragowa bazai zama mahara na 8 ba, kuma abin da ake buƙata shi ma ba a san shi ba. A farkon aiwatar da algorithm, ban sani ba game da wanzuwar byte sync don haka kawai adana fayiloli 8 tare da lambobi daban-daban na ragi. Daya daga cikinsu ya ƙunshi daidai bayanai. A cikin algorithm na ƙarshe, Ina kawai cire duk ragi har zuwa A5h, wanda ke ba ni damar samun ainihin fayil ɗin fitarwa nan da nan

Algorithm a cikin Ruby, ga masu sha'awar
Na zabi Ruby a matsayin yaren rubuta shirin, saboda... Ina shirye-shirye akai akai. Zaɓin ba babban aiki ba ne, amma aikin yin saurin karantawa da sauri ba shi da daraja.

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

sakamakon

Bayan gwada bambance-bambancen bambance-bambancen algorithm da madaidaicin, na yi sa'a don samun wani abu mai ban sha'awa sosai:

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Don haka, yin la'akari da kirtani, muna da shirin tsara zane-zane. Koyaya, babu mahimman kalmomi a cikin rubutun shirin. Ana sanya duk mahimman kalmomi azaman bytes (kowace ƙimar> 80h). Yanzu muna buƙatar gano ko wace kwamfuta daga shekarun 80s za ta iya adana shirye-shirye ta wannan tsari.

A zahiri, yayi kama da shirin BASIC. Kwamfutar ZX Spectrum tana adana shirye-shirye a kusan tsari iri ɗaya a ƙwaƙwalwar ajiya kuma tana adana shirye-shirye zuwa tef. Kawai idan, na duba kalmomin gaba da su tebur. Duk da haka, sakamakon ya kasance mara kyau.

Na kuma duba mahimman kalmomin BASIC na mashahurin Atari, Commodore 64 da sauran kwamfutoci da dama na wancan lokacin, wanda na sami damar samun takardu, amma ban yi nasara ba - ilimina na nau'ikan kwamfutoci na retro sun zama ba su da faɗi sosai.

Sai na yanke shawarar tafiya jerin, sannan kallo na ya fadi kan sunan kamfanin da ke kera Radio Shack da kuma kwamfutar TRS-80. Waɗannan su ne sunayen da aka rubuta a kan tambarin kaset ɗin da ke kwance akan teburina! Ban san wadannan sunaye a da ba kuma ban saba da kwamfuta ta TRS-80 ba, don haka sai na ga kamar Rediyo Shack na yin kaset ne irin na BASF, Sony ko TDK, kuma TRS-80 ne lokacin sake kunnawa. Me ya sa?

Computer Tandy/Radio Shack TRS-80

Da alama an yi rikodin sautin da ake magana a kai, wanda na bayar a matsayin misali a farkon labarin, an yi shi ne a kan kwamfuta kamar haka:

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Ya bayyana cewa wannan kwamfuta da nau'ikanta (Model I/Model III/Model IV, da dai sauransu) sun shahara sosai a lokaci guda (hakika, ba a Rasha ba). Abin lura shi ne cewa processor din da suka yi amfani da shi shima Z80 ne. Don wannan kwamfutar za ku iya samun a Intanet bayanai da yawa. A cikin 80s, an rarraba bayanan kwamfuta a ciki mujallu. A halin yanzu akwai da dama emulators kwamfutoci don dandamali daban-daban.

Na zazzage abin koyi ku 80gp kuma a karon farko na iya ganin yadda wannan kwamfutar ke aiki. Tabbas, kwamfutar ba ta goyi bayan fitowar launi ba, ƙudurin allo ya kasance 128x48 pixels kawai, amma akwai haɓakawa da gyare-gyare da yawa waɗanda zasu iya ƙara ƙudurin allo. Hakanan akwai zaɓuɓɓuka da yawa don tsarin aiki na wannan kwamfutar da zaɓuɓɓukan aiwatar da yaren BASIC (wanda, ba kamar ZX Spectrum ba, a wasu samfuran ba a ma “flashed” cikin ROM ba kuma kowane zaɓi za a iya loda shi daga faifan floppy, kamar dai yadda yake. OS kanta)

Na samu kuma mai amfani don canza faifan sauti zuwa tsarin CAS, wanda masu kwaikwaya ke goyan bayansu, amma saboda wasu dalilai bai yiwu a karanta rikodi daga kaset na ta amfani da su ba.

Bayan gano tsarin fayil ɗin CAS (wanda ya zama kwafin bayanan kaɗan-by-bit daga tef ɗin da na riga na riƙe a hannu, sai dai mai taken tare da kasancewar sync byte), na yi ƴan canje-canje ga shirina kuma na sami damar fitar da fayil ɗin CAS mai aiki wanda ke aiki a cikin mai kwaikwayon (TRS-80 Model III):

Yadda na kwato bayanai a tsarin da ba a sani ba daga kaset na maganadisu

Na tsara sabon juzu'in mai amfani na jujjuya tare da ƙaddara ta atomatik na bugun bugun farko da nisa tsakanin bugun jini a matsayin fakitin GEM, lambar tushe tana samuwa a Github.

ƙarshe

Hanyar da muka bi ta zama tafiya mai ban sha'awa a baya, kuma na yi farin ciki cewa a ƙarshe na sami amsar. Daga cikin wasu abubuwa, I:

  • Na gano tsarin adana bayanai a cikin ZX Spectrum kuma na yi nazarin ginanniyar ayyukan ROM don adanawa / karanta bayanai daga kaset na sauti.
  • Na saba da kwamfutar TRS-80 da nau'ikan ta, na yi nazarin tsarin aiki, na duba shirye-shiryen samfurin har ma na sami damar yin lalata a cikin lambobin injin (bayan haka, duk Z80 mnemonics sun saba da ni)
  • Ya rubuta cikakken kayan aiki don canza rikodin sauti zuwa tsarin CAS, wanda zai iya karanta bayanan da ba a gane su ta hanyar amfani da “official” ba.

source: www.habr.com

Add a comment