Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

cynhanes

Gan fy mod yn hoff o galedwedd retro, prynais ZX Spectrum+ unwaith gan werthwr yn y DU. Wedi'i gynnwys gyda'r cyfrifiadur ei hun, derbyniais nifer o gasetiau sain gyda gemau (yn y pecyn gwreiddiol gyda chyfarwyddiadau), yn ogystal â rhaglenni wedi'u recordio ar gasetiau heb farciau arbennig. Yn syndod, roedd data o gasetiau 40 oed yn ddarllenadwy'n dda ac roeddwn i'n gallu lawrlwytho bron pob un o'r gemau a'r rhaglenni ohonyn nhw.

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Fodd bynnag, ar rai casetiau canfûm recordiadau a oedd yn amlwg heb eu gwneud gan gyfrifiadur ZX Spectrum. Roeddent yn swnio'n hollol wahanol ac, yn wahanol i'r recordiadau o'r cyfrifiadur a grybwyllwyd, ni wnaethant ddechrau gyda bootloader SYLFAENOL byr, sydd fel arfer yn bresennol yn y recordiadau o'r holl raglenni a gemau.

Am beth amser roedd hyn yn fy mhoeni - roeddwn i wir eisiau darganfod beth oedd yn cuddio ynddynt. Pe baech chi'n gallu darllen y signal sain fel dilyniant o beit, fe allech chi chwilio am nodau neu unrhyw beth sy'n dynodi tarddiad y signal. Math o ôl-archaeoleg.

Nawr fy mod i wedi mynd yr holl ffordd ac edrych ar labeli'r casetiau eu hunain, dwi'n gwenu oherwydd

roedd yr ateb reit o flaen fy llygaid ar hyd yr amser
Ar label y casét chwith mae enw'r cyfrifiadur TRS-80, ac ychydig o dan enw'r gwneuthurwr: "Wedi'i gynhyrchu gan Radio Shack yn UDA"

(Os ydych chi am gadw'r dirgelwch tan y diwedd, peidiwch â mynd o dan y sbwyliwr)

Cymharu signalau sain

Yn gyntaf oll, gadewch i ni ddigideiddio'r recordiadau sain. Gallwch chi wrando ar sut mae'n swnio:


Ac yn ôl yr arfer mae'r recordiad o gyfrifiadur ZX Spectrum yn swnio:


Yn y ddau achos, ar ddechrau'r recordiad mae hyn a elwir tôn peilot - sain o'r un amledd (yn y recordiad cyntaf mae'n fyr iawn <1 eiliad, ond gellir ei gwahaniaethu). Mae naws y peilot yn arwydd i'r cyfrifiadur baratoi i dderbyn data. Fel rheol, dim ond ei naws peilot “ei hun” y mae pob cyfrifiadur yn ei adnabod yn ôl siâp y signal a'i amlder.

Mae angen dweud rhywbeth am y siâp signal ei hun. Er enghraifft, ar y Sbectrwm ZX mae ei siâp yn hirsgwar:

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Pan ganfyddir naws peilot, mae'r Sbectrwm ZX yn dangos bariau coch a glas bob yn ail ar ffin y sgrin i ddangos bod y signal wedi'i gydnabod. Tôn peilot yn dod i ben pwls synchro, sy'n arwydd i'r cyfrifiadur ddechrau derbyn data. Fe'i nodweddir gan gyfnod byrrach (o'i gymharu â naws y peilot a'r data dilynol) (gweler y ffigur)

Ar ôl derbyn y pwls cysoni, mae'r cyfrifiadur yn cofnodi pob codiad/cwymp y signal, gan fesur ei hyd. Os yw'r hyd yn llai na therfyn penodol, ysgrifennir did 1 i'r cof, fel arall 0. Cesglir y didau yn beit ac ailadroddir y broses nes derbynnir N beit. Mae'r rhif N fel arfer yn cael ei gymryd o bennawd y ffeil a lawrlwythwyd. Mae'r dilyniant llwytho fel a ganlyn:

  1. tôn peilot
  2. pennawd (hyd sefydlog), yn cynnwys maint y data wedi'i lawrlwytho (N), enw ffeil a math
  3. tôn peilot
  4. y data ei hun

Er mwyn sicrhau bod y data'n cael ei lwytho'n gywir, mae'r Sbectrwm ZX yn darllen yr hyn a elwir beit cydraddoldeb (parity beit), sy'n cael ei gyfrifo wrth arbed ffeil trwy XORing pob beit o'r data ysgrifenedig. Wrth ddarllen ffeil, mae'r cyfrifiadur yn cyfrifo'r beit cydraddoldeb o'r data a dderbyniwyd ac, os yw'r canlyniad yn wahanol i'r un a arbedwyd, mae'n dangos y neges gwall "Gwall llwytho Tâp R". A siarad yn fanwl gywir, gall y cyfrifiadur gyhoeddi'r neges hon yn gynharach os na all, wrth ddarllen, adnabod pwls (wedi'i golli neu nid yw ei hyd yn cyfateb i derfynau penodol)

Felly, gadewch i ni nawr weld sut olwg sydd ar signal anhysbys:

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Dyma naws y peilot. Mae siâp y signal yn sylweddol wahanol, ond mae'n amlwg bod y signal yn cynnwys ailadrodd corbys byr o amledd penodol. Ar amledd samplu o 44100 Hz, mae’r pellter rhwng y “copaon” tua 48 sampl (sy’n cyfateb i amledd o ~918 Hz). Gadewch i ni gofio’r ffigwr hwn.

Edrychwn yn awr ar y darn data:

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Os byddwn yn mesur y pellter rhwng corbys unigol, mae'n ymddangos bod y pellter rhwng corbys “hir” yn dal i fod yn ~48 sampl, a rhwng rhai byr - ~24. Wrth edrych ymlaen ychydig, dywedaf ei fod yn y diwedd wedi troi allan bod corbys “cyfeirio” ag amledd o 918 Hz yn dilyn yn barhaus, o ddechrau i ddiwedd y ffeil. Gellir tybio, wrth drosglwyddo data, os deuir ar draws pwls ychwanegol rhwng y corbys cyfeirio, ein bod yn ei ystyried fel did 1, fel arall 0.

Beth am y pwls cysoni? Edrychwn ar ddechrau'r data:

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Daw tôn y peilot i ben ac mae'r data'n dechrau ar unwaith. Ychydig yn ddiweddarach, ar ôl dadansoddi sawl recordiad sain gwahanol, roeddem yn gallu darganfod bod y beit cyntaf o ddata bob amser yr un peth (10100101b, A5h). Efallai y bydd y cyfrifiadur yn dechrau darllen data ar ôl iddo ei dderbyn.

Gallwch hefyd roi sylw i newid y pwls cyfeirio cyntaf yn syth ar ôl y 1af olaf yn y beit cydamseru. Fe'i darganfuwyd yn ddiweddarach o lawer yn y broses o ddatblygu rhaglen adnabod data, pan nad oedd modd darllen y data ar ddechrau'r ffeil yn sefydlog.

Nawr, gadewch i ni geisio disgrifio algorithm a fydd yn prosesu ffeil sain a llwytho data.

Llwytho Data

Yn gyntaf, gadewch i ni edrych ar ychydig o ragdybiaethau i gadw'r algorithm yn syml:

  1. Dim ond ffeiliau ar fformat WAV y byddwn yn eu hystyried;
  2. Rhaid i'r ffeil sain ddechrau gyda thôn peilot ac ni ddylai gynnwys tawelwch ar y dechrau
  3. Rhaid i'r ffeil ffynhonnell fod â chyfradd samplu o 44100 Hz. Yn yr achos hwn, mae'r pellter rhwng corbys cyfeirio 48 o samplau eisoes wedi'i bennu ac nid oes angen i ni ei gyfrifo'n rhaglennol;
  4. Gall fformat y sampl fod yn unrhyw un (8/16 did / pwynt arnawf) - oherwydd wrth ddarllen gallwn ei drosi i'r un a ddymunir;
  5. Tybiwn fod y ffeil ffynhonnell yn cael ei normaleiddio gan osgled, a ddylai sefydlogi'r canlyniad;

Bydd yr algorithm darllen fel a ganlyn:

  1. Rydym yn darllen y ffeil i'r cof, ar yr un pryd yn trosi'r fformat sampl i 8 did;
  2. Darganfyddwch leoliad y pwls cyntaf yn y data sain. I wneud hyn, mae angen i chi gyfrifo nifer y sampl gyda'r osgled mwyaf. Er mwyn symlrwydd, byddwn yn ei gyfrifo unwaith â llaw. Gadewch i ni ei gadw i'r newidyn prev_pos;
  3. Ychwanegu 48 at safle'r curiad olaf (pos := prev_pos + 48)
  4. Gan nad yw cynyddu'r sefyllfa o 48 yn gwarantu y byddwn yn cyrraedd sefyllfa'r pwls cyfeirio nesaf (diffygion tâp, gweithrediad ansefydlog y mecanwaith gyriant tâp, ac ati), mae angen inni addasu lleoliad y pwls post. I wneud hyn, cymerwch ddarn bach o ddata (pos-8; pos + 8) a darganfyddwch y gwerth amplitude uchaf arno. Bydd y safle sy'n cyfateb i'r uchafswm yn cael ei storio mewn pos. Yma mae 8 = 48/6 yn gysonyn a gafwyd yn arbrofol, sy'n gwarantu y byddwn yn pennu'r uchafswm cywir ac na fydd yn effeithio ar ysgogiadau eraill a allai fod gerllaw. Mewn achosion gwael iawn, pan fo'r pellter rhwng corbys yn llawer llai na neu'n fwy na 48, gallwch chi wneud chwiliad gorfodol am bwls, ond o fewn cwmpas yr erthygl ni fyddaf yn disgrifio hyn yn yr algorithm;
  5. Yn y cam blaenorol, byddai hefyd angen gwirio bod y pwls cyfeirio wedi'i ganfod o gwbl. Hynny yw, os edrychwch am yr uchafswm yn unig, nid yw hyn yn gwarantu bod yr ysgogiad yn bresennol yn y gylchran hon. Yn fy ngweithrediad diweddaraf o'r rhaglen ddarllen, rwy'n gwirio'r gwahaniaeth rhwng y gwerthoedd amplitude uchaf ac isaf ar segment, ac os yw'n fwy na therfyn penodol, rwy'n cyfrif presenoldeb ysgogiad. Y cwestiwn hefyd yw beth i'w wneud os na cheir hyd i'r pwls cyfeirio. Mae 2 opsiwn: naill ai mae’r data wedi dod i ben ac mae distawrwydd yn dilyn, neu dylid ystyried hyn yn gamgymeriad darllen. Fodd bynnag, byddwn yn hepgor hyn er mwyn symleiddio'r algorithm;
  6. Ar y cam nesaf, mae angen i ni bennu presenoldeb pwls data (did 0 neu 1), ar gyfer hyn rydym yn cymryd canol y segment (prev_pos;pos) middle_pos hafal i middle_pos := (prev_pos + pos)/2 a mewn rhyw gymdogaeth o middle_pos ar y segment (middle_pos-8; middle_pos +8) gadewch i ni gyfrifo'r osgled uchaf ac isaf. Os yw'r gwahaniaeth rhyngddynt yn fwy na 10, rydym yn ysgrifennu did 1 i'r canlyniad, fel arall mae 0. 10 yn gysonyn a gafwyd yn arbrofol;
  7. Cadw'r sefyllfa bresennol yn prev_pos (prev_pos := pos)
  8. Ailadroddwch gan ddechrau o gam 3 nes i ni ddarllen y ffeil gyfan;
  9. Rhaid cadw'r arae didau canlyniadol fel set o beit. Gan na wnaethom gymryd y beit cysoni i ystyriaeth wrth ddarllen, efallai na fydd nifer y didau yn lluosrif o 8, ac nid yw'r gwrthbwyso didau gofynnol hefyd yn hysbys. Wrth weithredu'r algorithm am y tro cyntaf, doeddwn i ddim yn gwybod am fodolaeth y beit cydamseru ac felly'n arbed 8 ffeil gyda gwahanol niferoedd o ddarnau gwrthbwyso. Roedd un ohonynt yn cynnwys data cywir. Yn yr algorithm terfynol, rwy'n tynnu'r holl ddarnau hyd at A5h, sy'n fy ngalluogi i gael y ffeil allbwn gywir ar unwaith

Algorithm yn Ruby, i'r rhai sydd â diddordeb
Dewisais Ruby fel yr iaith ar gyfer ysgrifennu'r rhaglen, oherwydd... Rwy'n rhaglennu arno y rhan fwyaf o'r amser. Nid yw'r opsiwn yn berfformiad uchel, ond nid yw'r dasg o wneud y cyflymder darllen mor gyflym â phosibl yn werth chweil.

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

Canlyniad

Ar ôl rhoi cynnig ar sawl amrywiad o'r algorithm a'r cysonion, roeddwn yn ffodus i gael rhywbeth hynod ddiddorol:

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Felly, a barnu yn ôl y llinynnau nodau, mae gennym raglen ar gyfer plotio graffiau. Fodd bynnag, nid oes unrhyw eiriau allweddol yn nhestun y rhaglen. Mae'r holl eiriau allweddol wedi'u hamgodio fel bytes (pob gwerth> 80h). Nawr mae angen i ni ddarganfod pa gyfrifiadur o'r 80au allai arbed rhaglenni yn y fformat hwn.

Mewn gwirionedd, mae'n debyg iawn i raglen SYLFAENOL. Mae'r cyfrifiadur ZX Spectrum yn storio rhaglenni mewn tua'r un fformat yn y cof ac yn arbed rhaglenni i dâp. Rhag ofn, gwiriais yr allweddeiriau yn erbyn bwrdd. Fodd bynnag, roedd y canlyniad yn amlwg yn negyddol.

Fe wnes i hefyd wirio allweddeiriau SYLFAENOL yr Atari, Commodore 64 poblogaidd a nifer o gyfrifiaduron eraill yr amser hwnnw, yr oeddwn yn gallu dod o hyd i ddogfennaeth ar eu cyfer, ond heb lwyddiant - nid oedd fy ngwybodaeth am y mathau o gyfrifiaduron retro mor eang.

Yna penderfynais fynd y rhestr, ac yna syrthiodd fy syllu ar enw'r gwneuthurwr Radio Shack a'r cyfrifiadur TRS-80. Dyma'r enwau a ysgrifennwyd ar labeli'r casetiau oedd yn gorwedd ar fy mwrdd! Nid oeddwn yn gwybod yr enwau hyn o'r blaen ac nid oeddwn yn gyfarwydd â'r cyfrifiadur TRS-80, felly roedd yn ymddangos i mi fod Radio Shack yn wneuthurwr casét sain fel BASF, Sony neu TDK, a'r TRS-80 oedd yr amser chwarae. Pam ddim?

Tandy Cyfrifiadur/Shack Radio TRS-80

Mae’n debygol iawn bod y recordiad sain dan sylw, a roddais fel enghraifft ar ddechrau’r erthygl, wedi’i wneud ar gyfrifiadur fel hyn:

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Mae'n troi allan bod y cyfrifiadur hwn a'i amrywiaethau (Model I / Model III / Model IV, ac ati) yn boblogaidd iawn ar un adeg (wrth gwrs, nid yn Rwsia). Mae'n werth nodi mai'r prosesydd a ddefnyddiwyd ganddynt hefyd oedd Z80. Ar gyfer y cyfrifiadur hwn gallwch ddod o hyd ar y Rhyngrwyd llawer o wybodaeth. Yn yr 80au, dosbarthwyd gwybodaeth gyfrifiadurol yn cylchgronau. Ar hyn o bryd mae yna sawl un efelychwyr cyfrifiaduron ar gyfer gwahanol lwyfannau.

Fe wnes i lawrlwytho'r efelychydd trs80gp ac am y tro cyntaf roeddwn yn gallu gweld sut roedd y cyfrifiadur hwn yn gweithio. Wrth gwrs, nid oedd y cyfrifiadur yn cefnogi allbwn lliw; dim ond 128x48 picsel oedd cydraniad y sgrin, ond roedd llawer o estyniadau ac addasiadau a allai gynyddu cydraniad y sgrin. Roedd yna hefyd lawer o opsiynau ar gyfer systemau gweithredu ar gyfer y cyfrifiadur hwn ac opsiynau ar gyfer gweithredu'r iaith SYLFAENOL (nad oedd, yn wahanol i'r Sbectrwm ZX, mewn rhai modelau hyd yn oed wedi'i "fflachio" i ROM a gellid llwytho unrhyw opsiwn o ddisg hyblyg, yn union fel yr OS ei hun)

canfyddais hefyd cyfleustodau i drosi recordiadau sain i fformat CAS, sy'n cael ei gefnogi gan efelychwyr, ond am ryw reswm nid oedd yn bosibl darllen recordiadau o fy nghasetiau gan eu defnyddio.

Ar ôl cyfrifo'r fformat ffeil CAS (a drodd allan i fod yn ddim ond copi fesul tipyn o'r data o'r tâp oedd gennyf eisoes wrth law, heblaw am y pennawd gyda phresenoldeb sync beit), fe wnes i a ychydig o newidiadau i'm rhaglen ac roedd yn gallu allbynnu ffeil CAS sy'n gweithio a oedd yn gweithio yn yr efelychydd (TRS-80 Model III):

Sut wnes i adennill data mewn fformat anhysbys o dâp magnetig

Dyluniais y fersiwn diweddaraf o'r cyfleustodau trosi gyda phenderfyniad awtomatig o'r curiad cyntaf a'r pellter rhwng corbys cyfeirio fel pecyn GEM, mae'r cod ffynhonnell ar gael yn Github.

Casgliad

Trodd y llwybr yr ydym wedi'i deithio yn daith hynod ddiddorol i'r gorffennol, ac rwy'n falch fy mod wedi dod o hyd i'r ateb yn y diwedd. Ymhlith pethau eraill, rydw i:

  • Fe wnes i gyfrifo'r fformat ar gyfer arbed data yn y Sbectrwm ZX ac astudiais y gweithdrefnau ROM adeiledig ar gyfer arbed / darllen data o gasetiau sain
  • Deuthum yn gyfarwydd â'r cyfrifiadur TRS-80 a'i amrywiaethau, astudiais y system weithredu, edrychais ar raglenni sampl a hyd yn oed y cyfle i wneud dadfygio mewn codau peiriant (wedi'r cyfan, mae holl gofebau Z80 yn gyfarwydd i mi)
  • Ysgrifennu cyfleustodau llawn ar gyfer trosi recordiadau sain i fformat CAS, sy'n gallu darllen data nad yw'n cael ei gydnabod gan y cyfleustodau “swyddogol”

Ffynhonnell: hab.com

Ychwanegu sylw