Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

prehistory

ʻOiai he mea aloha i ka ʻenehana retro, ua kūʻai aku au i kahi ZX Spectrum + mai kahi mea kūʻai aku ma UK. Hoʻohui pū me ka kamepiula ponoʻī, ua loaʻa iaʻu nā cassette leo me nā pāʻani (i loko o ka pahu mua me nā kuhikuhi), a me nā papahana i hoʻopaʻa ʻia ma nā cassette me ka ʻole o nā hōʻailona kūikawā. ʻO ka mea kupanaha, hiki ke heluhelu maikaʻi ʻia ka ʻikepili mai nā cassette 40 makahiki a ua hiki iaʻu ke hoʻoiho i nā pāʻani a me nā papahana āpau mai ia mau mea.

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

Eia naʻe, ma kekahi mau cassette ua ʻike au i nā hoʻopaʻa leo ʻaʻole i hana ʻia e ka kamepiula ZX Spectrum. Ua kani ʻokoʻa lākou a, ʻaʻole e like me nā hoʻopaʻa ʻana mai ka kamepiula i ʻōlelo ʻia, ʻaʻole lākou i hoʻomaka me kahi bootloader BASIC pōkole, ka mea maʻamau i nā leo o nā papahana a me nā pāʻani.

No kekahi manawa ua hauʻoli kēia iaʻu - makemake nui wau e ʻike i nā mea huna i loko o lākou. Inā hiki iā ʻoe ke heluhelu i ka hōʻailona leo ma ke ʻano he kaʻina paita, hiki iā ʻoe ke ʻimi i nā huaʻōlelo a i ʻole kekahi mea e hōʻike ana i ke kumu o ka hōʻailona. He ʻano retro-archeology.

I kēia manawa ua hele au a nānā i nā lepili o nā cassette iā lākou iho, ʻakaʻaka wau no ka mea

aia ka pane i mua o koʻu mau maka a pau
Aia ma ka lepili o ka cassette hema ka inoa o ke kamepiula TRS-80, a ma lalo iho o ka inoa o ka mea hana: "Hana 'ia e Radio Shack ma USA"

(Inā makemake ʻoe e hoʻomau i ka manaʻo a hiki i ka hopena, mai hele i lalo o ka mea hao.)

Hoʻohālikelike o nā hōʻailona leo

ʻO ka mea mua, e hoʻopaʻa helu i nā leo leo. Hiki iā ʻoe ke hoʻolohe i ke kani ʻana:


A e like me ke kani mau ʻana mai ka kamepiula ZX Spectrum:


I nā hihia ʻelua, i ka hoʻomaka ʻana o ka hoʻopaʻa ʻana aia kahi mea i kapa ʻia leo pailaka - he kani o ke alapine like (ma ka hoʻopaʻa mua ʻana he pōkole loa <1 kekona, akā hiki ke ʻike ʻia). Hōʻailona ka leo pailaka i ke kamepiula e hoʻomākaukau no ka loaʻa ʻana o ka ʻikepili. Ma ke ʻano maʻamau, ʻike kēlā me kēia kamepiula i kāna leo hoʻokele "ponoʻī" ma ke ʻano o ka hōʻailona a me kona alapine.

Pono e ʻōlelo i kekahi mea e pili ana i ke ʻano hōʻailona ponoʻī. No ka laʻana, ma ka ZX Spectrum kona ʻano he ʻehā:

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

Ke ʻike ʻia kahi leo hoʻokele, hōʻike ka ZX Spectrum i nā pahu ʻulaʻula a me polū ma ka palena o ka pale e hōʻike ai ua ʻike ʻia ka hōʻailona. Pau ka leo pailaka puʻupuʻu syncro, e hōʻailona ana i ke kamepiula e hoʻomaka i ka loaʻa ʻana o ka ʻikepili. Hōʻike ʻia ia e ka lōʻihi pōkole (hoʻohālikelike ʻia me ka leo pilote a me nā ʻikepili ma hope) (e ʻike i ke kiʻi)

Ma hope o ka loaʻa ʻana o ka pulse sync, hoʻopaʻa ke kamepiula i kēlā me kēia piʻi a hāʻule o ka hōʻailona, ​​e ana ana i kona lōʻihi. Inā liʻiliʻi ka lōʻihi ma mua o kahi palena, kākau ʻia ka bit 1 i ka hoʻomanaʻo, inā ʻaʻole 0. E hōʻiliʻili ʻia nā bits i loko o nā bytes a hana hou ʻia ke kaʻina hana a hiki i ka loaʻa ʻana o N bytes. Lawe ʻia ka helu N mai ke poʻo o ka faila i hoʻoiho ʻia. Penei ka hoouka ana.

  1. leo pailaka
  2. header (lōʻihi paʻa), loaʻa ka nui o ka ʻikepili i hoʻoiho ʻia (N), inoa faila a me ke ʻano
  3. leo pailaka
  4. ka ʻikepili ponoʻī

No ka hōʻoia i ka hoʻouka pono ʻana o ka ʻikepili, heluhelu ka ZX Spectrum i ka mea i kapa ʻia parity byte (parity byte), i helu ʻia i ka wā e mālama ai i kahi faila ma ka XORing i nā bytes āpau o ka ʻikepili i kākau ʻia. I ka heluhelu ʻana i kahi faila, helu ka lolouila i ka parity byte mai ka ʻikepili i loaʻa a, inā ʻokoʻa ka hopena mai ka mea i mālama ʻia, hōʻike i ka memo hewa "R Tape loading error". ʻO ka ʻōlelo koʻikoʻi, hiki i ke kamepiula ke hoʻopuka i kēia memo ma mua inā, i ka heluhelu ʻana, ʻaʻole hiki iā ia ke ʻike i kahi pulse (ʻaʻole i kūpono a i ʻole kona lōʻihi i kekahi mau palena)

No laila, e ʻike kākou i ke ʻano o kahi hōʻailona ʻike ʻole ʻia:

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

ʻO kēia ka leo hoʻokele. He ʻokoʻa loa ke ʻano o ka hōʻailona, ​​​​akā ua maopopo ka hōʻailona o ka hana hou ʻana i nā pulu pōkole o kahi alapine. Ma ke alapine sampling o 44100 Hz, ʻo ka mamao ma waena o nā "puʻu" ma kahi o 48 mau laʻana (e like me ke alapine o ~918 Hz). E hoʻomanaʻo kākou i kēia kiʻi.

E nānā kākou i ka ʻāpana ʻikepili:

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

Inā mākou e ana i ka mamao ma waena o kēlā me kēia pulses, ʻike ʻia ʻo ka mamao ma waena o nā pulses "lōʻihi" mau ~ 48 mau laʻana, a ma waena o nā mea pōkole - ~ 24. Ke nānā iki nei i mua, e ʻōlelo wau i ka hopena ua ʻike ʻia nā pulses "kuʻi" me ke alapine o 918 Hz e hahai mau ana, mai ka hoʻomaka a i ka hopena o ka faila. Hiki ke manaʻo ʻia i ka wā e hoʻouna ai i ka ʻikepili, inā loaʻa kahi pulse hou ma waena o nā pulses referral, manaʻo mākou he bit 1, a i ʻole 0.

Pehea e pili ana i ka pulse sync? E nānā kākou i ka hoʻomaka o ka ʻikepili:

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

Hoʻopau ka leo hoʻokele a hoʻomaka koke ka ʻikepili. Ma hope iki mai, ma hope o ka nānā ʻana i kekahi mau leo ​​leo like ʻole, ua hiki iā mākou ke ʻike he like mau ka byte mua o ka ʻikepili (10100101b, A5h). Hiki i ke kamepiula ke hoʻomaka e heluhelu i ka ʻikepili ma hope o ka loaʻa ʻana.

Hiki iā ʻoe ke hoʻolohe i ka neʻe ʻana o ka pulse kuhikuhi mua ma hope koke o ka 1 hope i ka byte sync. Ua ʻike ʻia ma hope loa ma ke kaʻina o ka hoʻomohala ʻana i kahi papahana ʻike ʻikepili, ke hiki ʻole ke heluhelu paʻa i ka ʻikepili i ka hoʻomaka ʻana o ka faila.

I kēia manawa e ho'āʻo kākou e wehewehe i kahi algorithm e hoʻoponopono i kahi faila leo a hoʻouka i ka ʻikepili.

Hoʻouka ʻikepili

ʻO ka mea mua, e nānā i kekahi mau manaʻo e mālama i ka algorithm maʻalahi:

  1. E noʻonoʻo wale mākou i nā faila ma ke ʻano WAV;
  2. Pono e hoʻomaka ka waihona leo me ka leo hoʻokele a ʻaʻole pono e hāmau ma ka hoʻomaka
  3. Pono ka waihona kumu i ka la'ana o 44100 Hz. I kēia hihia, ua hoʻoholo mua ʻia ka mamao ma waena o nā pulses kuhikuhi o 48 a ʻaʻole pono mākou e helu i ka programmatically;
  4. ʻO ka hōʻailona hōʻailona hiki ke lilo i kekahi (8/16 bits/floating point) - mai ka heluhelu ʻana hiki iā mākou ke hoʻololi iā ia i ka mea i makemake ʻia;
  5. Manaʻo mākou ua maʻamau ka faila kumu e ka amplitude, pono e hoʻopaʻa i ka hopena;

Penei ka heluhelu algorithm:

  1. Heluhelu mākou i ka faila i ka hoʻomanaʻo, i ka manawa like me ka hoʻololi ʻana i ke ʻano hoʻohālike i 8 mau bits;
  2. E hoʻoholo i ke kūlana o ka pulse mua i ka ʻikepili leo. No ka hana ʻana i kēia, pono ʻoe e helu i ka helu o ka hāpana me ka amplitude kiʻekiʻe. No ka maʻalahi, e helu mākou i hoʻokahi manawa me ka lima. E mālama kākou i ka prev_pos variable;
  3. Hoʻohui i ka 48 i ke kūlana o ka pulse hope (pos := prev_pos + 48)
  4. Ma muli o ka hoʻonui ʻana i ke kūlana e 48 ʻaʻole ia e hōʻoiaʻiʻo e hiki mākou i ke kūlana o ka pulse kuhikuhi e hiki mai ana (nā kīnā ʻole, ka hana paʻa ʻole o ka mīkini hoʻokele tape, a me nā mea ʻē aʻe), pono mākou e hoʻoponopono i ke kūlana o ka pulse post. No ka hana ʻana i kēia, e lawe i kahi ʻāpana liʻiliʻi o ka ʻikepili (pos-8; pos+8) a e ʻimi i ka waiwai amplitude kiʻekiʻe ma luna. E mālama ʻia ke kūlana e pili ana i ka nui ma ka pos. Maʻaneʻi 8 = 48/6 kahi hoʻokolohua i loaʻa mau, e hōʻoiaʻiʻo ana e hoʻoholo mākou i ka palena kūpono a ʻaʻole e hoʻopilikia i nā manaʻo ʻē aʻe e kokoke ana. I nā hihia maikaʻi loa, inā ʻoi aku ka liʻiliʻi o ka mamao ma waena o nā pulses ma mua o 48, hiki iā ʻoe ke hoʻokō i kahi ʻimi koi no ka pulse, akā i loko o ke ʻano o ka ʻatikala ʻaʻole wau e wehewehe i kēia ma ka algorithm;
  5. Ma ka hana mua, pono e nānā i ka loaʻa ʻana o ka pulse kuhikuhi. ʻO ia hoʻi, inā ʻoe e ʻimi wale i ka palena kiʻekiʻe, ʻaʻole ia e hōʻoiaʻiʻo aia ka impulse i kēia māhele. I koʻu hoʻokō hou ʻana i ka papahana heluhelu, nānā au i ka ʻokoʻa ma waena o ka nui a me ka liʻiliʻi amplitude waiwai ma kahi ʻāpana, a inā ʻoi aku ia ma mua o kahi palena, helu wau i ka hiki ʻana o kahi manaʻo. ʻO ka nīnau ka mea e hana ai inā ʻaʻole ʻike ʻia ka pulse kuhikuhi. Aia nā koho 2: ua pau ka ʻikepili a ua hāmau ʻia, a i ʻole e manaʻo ʻia he hewa heluhelu. Eia naʻe, e haʻalele mākou i kēia e hoʻomaʻamaʻa i ka algorithm;
  6. I ka pae aʻe, pono mākou e hoʻoholo i ka hiki ʻana o kahi pulse data (bit 0 a i ʻole 1), no kēia mākou e lawe i ka waena o ka māhele (prev_pos;pos) middle_pos e like me middle_pos := (prev_pos+pos)/2 a ma kekahi wahi o middle_pos ma ka mahele (middle_pos-8;middle_pos +8) e helu kakou i ka amplitude kiʻekiʻe a me ka palena iki. Inā ʻoi aku ka ʻokoʻa ma waena o lākou ma mua o 10, kākau mākou i ka bit 1 i loko o ka hopena, inā ʻaʻole 0. ʻO 10 ka mea mau i loaʻa i ka hoʻokolohua;
  7. E mālama i ke kūlana o kēia manawa ma prev_pos (prev_pos := pos)
  8. E hana hou mai ka ʻanuʻu 3 a hiki i ka heluhelu ʻana i ka faila holoʻokoʻa;
  9. Pono e mālama ʻia ke ʻano bit array ma ke ʻano he set of bytes. No ka mea ʻaʻole mākou i noʻonoʻo i ka byte sync i ka wā e heluhelu ai, ʻaʻole paha he nui o ka 8 ka helu o nā bits, a ʻaʻole ʻike ʻia ka bit offset. I ka hoʻokō mua ʻana o ka algorithm, ʻaʻole wau i ʻike e pili ana i ke ola ʻana o ka sync byte a no laila ua mālama wale i nā faila 8 me nā helu like ʻole o nā bits offset. Aia kekahi o ia mau ʻikepili pololei. Ma ka algorithm hope loa, wehe wale au i nā ʻāpana āpau a hiki i A5h, e hiki ai iaʻu ke kiʻi koke i ka faila hoʻopuka pololei

Algorithm ma Ruby, no ka poe hoihoi
Ua koho au iā Ruby i ʻōlelo no ke kākau ʻana i ka papahana, no ka mea... Hoʻolālā wau iā ia i ka hapa nui o ka manawa. ʻAʻole maikaʻi ka koho, akā ʻaʻole pono ka hana o ka wikiwiki ʻana o ka heluhelu ʻana.

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

hopena

I ka ho'āʻo ʻana i nā ʻano like ʻole o ka algorithm a me nā mea mau, ua laki wau i ka loaʻa ʻana o kahi mea hoihoi loa:

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

No laila, i ka hoʻoholo ʻana i nā kaula kikoʻī, loaʻa iā mākou kahi papahana no ka hoʻolālā ʻana i nā kiʻi. Eia naʻe, ʻaʻohe huaʻōlelo ma ka kikokikona papahana. Hoʻopili ʻia nā huaʻōlelo a pau ma ke ʻano he bytes (kekahi waiwai> 80h). I kēia manawa pono mākou e ʻike i ka kamepiula mai ka 80s hiki ke mālama i nā polokalamu ma kēia ʻano.

ʻOiaʻiʻo, ua like loa ia me kahi papahana BASIC. Mālama ka lolouila ZX Spectrum i nā polokalamu ma kahi like like o ka hoʻomanaʻo a mālama i nā polokalamu i ka lipine. No ka hihia, ua nānā au i nā huaʻōlelo kūʻē papaʻaina. Akā naʻe, ʻaʻole maopopo ka hopena.

Ua nānā hoʻi au i nā huaʻōlelo BASIC o ka mea kaulana ʻo Atari, Commodore 64 a me nā kamepiula ʻē aʻe o ia manawa, kahi i hiki ai iaʻu ke loaʻa i nā palapala, akā ʻaʻole kūleʻa - ʻaʻole ākea koʻu ʻike i nā ʻano kamepiula retro.

A laila hoʻoholo wau e hele ka papa inoa, a laila hāʻule koʻu maka i ka inoa o ka mea hana Radio Shack a me ka kamepiula TRS-80. ʻO ia nā inoa i kākau ʻia ma nā lepili o nā pīkī e waiho ana ma luna o koʻu papa ʻaina! ʻAʻole wau i ʻike i kēia mau inoa ma mua a ʻaʻole wau i kamaʻāina i ka kamepiula TRS-80, no laila, me he mea lā iaʻu he mea hana cassette leo ʻo Radio Shack e like me BASF, Sony a i ʻole TDK, a ʻo TRS-80 ka manawa pāʻani. Kainō?

Kamepiula Tandy/Radio Shack TRS-80

Malia paha ua hana ʻia ka leo leo i nīnau ʻia, aʻu i hāʻawi ai i kumu hoʻohālike ma ka hoʻomaka ʻana o ka ʻatikala, i hana ʻia ma ke kamepiula e like me kēia:

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

Uaʻikeʻia he mea kaulana loa kēia kamepiula a me kona mauʻano (Model I/Model III/Model IV, etc.) i ka manawa hoʻokahi (ʻoiaʻiʻo,ʻaʻole i Rusia). He mea nui ka mea i hoʻohana ʻia ʻo Z80. No kēia kamepiula hiki iā ʻoe ke loaʻa ma ka Pūnaewele nui ka ʻike. I ka makahiki 80, ua hoʻolaha ʻia ka ʻike kamepiula ma nā nūpepa. I kēia manawa he nui nā emulators nā kamepiula no nā paepae like ʻole.

Ua hoʻoiho au i ka emulator trs80gp a no ka manawa mua aʻu i ʻike ai i ka hana ʻana o kēia kamepiula. ʻOiaʻiʻo, ʻaʻole i kākoʻo ka lolouila i ka hoʻopuka kala; ʻo ka hoʻonā pale he 128x48 pixels wale nō, akā nui nā hoʻonui a me nā hoʻololi e hiki ke hoʻonui i ka hoʻonā pale. Nui nō hoʻi nā koho no nā ʻōnaehana hana no kēia kamepiula a me nā koho no ka hoʻokō ʻana i ka ʻōlelo BASIC (ʻo ia, ʻaʻole like me ka ZX Spectrum, i kekahi mau hiʻohiʻona ʻaʻole i "flashed" i ROM a hiki ke hoʻouka ʻia kekahi koho mai kahi diski floppy, e like me ka OS pono'ī)

Ua loaa no hoi ia'u pono e hoʻohuli i nā leo leo i ka CAS format, i kākoʻo ʻia e nā emulators, akā no kekahi kumu ʻaʻole hiki ke heluhelu i nā leo mai kaʻu mau cassette me ka hoʻohana ʻana iā lākou.

I ka noʻonoʻo ʻana i ke ʻano o ka faila CAS (ʻo ia ka mea i hoʻololi ʻia he kope liʻiliʻi wale nō o ka ʻikepili mai ka lipine i loaʻa iaʻu ma ka lima, koe wale nō ke poʻo me ka loaʻa ʻana o kahi byte sync), ua hana wau i kahi. he mau hoʻololi i kaʻu papahana a ua hiki iā ia ke hoʻopuka i kahi faila CAS hana i hana i ka emulator (TRS-80 Model III):

Pehea wau i hoʻihoʻi ai i ka ʻikepili i kahi ʻano ʻike ʻole mai ka tape magnetic

Ua hoʻolālā au i ka mana hou o ka pono hoʻololi me ka hoʻoholo maʻalahi o ka pulse mua a me ka mamao ma waena o nā pulses kuhikuhi ma ke ʻano he pūʻulu GEM, loaʻa ke code kumu ma Github.

hopena

ʻO ke ala a mākou i hele ai, ua lilo ia i huakaʻi hoihoi i ka wā i hala, a hauʻoli wau i ka hopena ua loaʻa iaʻu ka pane. Ma waena o nā mea ʻē aʻe, ʻo wau:

  • Ua noʻonoʻo au i ke ʻano no ka mālama ʻana i ka ʻikepili i ka ZX Spectrum a ua aʻo i nā hana maʻamau ROM i kūkulu ʻia no ka mālama ʻana/heluhelu ʻikepili mai nā cassette leo.
  • Ua kamaʻāina wau i ka kamepiula TRS-80 a me kāna mau ʻano, aʻo i ka ʻōnaehana hana, nānā i nā papahana hoʻohālike a loaʻa nō hoʻi ka manawa e hana ai i ka debugging i nā code mīkini (ma hope o nā mea āpau, ʻike ʻia nā mnemonic Z80 a pau iaʻu)
  • Ua kākau i kahi pono piha no ka hoʻololi ʻana i nā leo leo i ka palapala CAS, hiki ke heluhelu i ka ʻikepili i ʻike ʻole ʻia e ka pono "official".

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka