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.
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:
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:
- tôn peilot
- pennawd (hyd sefydlog), yn cynnwys maint y data wedi'i lawrlwytho (N), enw ffeil a math
- tôn peilot
- 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:
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:
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:
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:
- Dim ond ffeiliau ar fformat WAV y byddwn yn eu hystyried;
- Rhaid i'r ffeil sain ddechrau gyda thôn peilot ac ni ddylai gynnwys tawelwch ar y dechrau
- 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;
- Gall fformat y sampl fod yn unrhyw un (8/16 did / pwynt arnawf) - oherwydd wrth ddarllen gallwn ei drosi i'r un a ddymunir;
- Tybiwn fod y ffeil ffynhonnell yn cael ei normaleiddio gan osgled, a ddylai sefydlogi'r canlyniad;
Bydd yr algorithm darllen fel a ganlyn:
- Rydym yn darllen y ffeil i'r cof, ar yr un pryd yn trosi'r fformat sampl i 8 did;
- 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;
- Ychwanegu 48 at safle'r curiad olaf (pos := prev_pos + 48)
- 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;
- 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;
- 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;
- Cadw'r sefyllfa bresennol yn prev_pos (prev_pos := pos)
- Ailadroddwch gan ddechrau o gam 3 nes i ni ddarllen y ffeil gyfan;
- 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:
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
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
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:
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
Fe wnes i lawrlwytho'r efelychydd
canfyddais hefyd
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):
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
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