Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

prehistory

Ман дӯстдори сахтафзори ретро будам, ман боре аз фурӯшанда дар Британияи Кабир ZX Spectrum + харида будам. Ба худи компютер дохил шуда, ман якчанд кассетаҳои аудиоиро бо бозиҳо (дар бастаи аслӣ бо дастурҳо) ва инчунин барномаҳое, ки дар кассетаҳо бидуни аломатҳои махсус сабт шудаанд, гирифтам. Тааҷҷубовар аст, ки маълумот аз кассетаҳои 40-сола хуб хонда мешуд ва ман тавонистам қариб ҳама бозиҳо ва барномаҳоро аз онҳо зеркашӣ кунам.

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Бо вуҷуди ин, дар баъзе кассетаҳо ман сабтҳое пайдо кардам, ки аз ҷониби компютери ZX Spectrum сохта нашудаанд. Онҳо комилан дигар садо медоданд ва бар хилофи сабтҳои компютери зикршуда, онҳо бо боркунаки кӯтоҳи BASIC, ки одатан дар сабти ҳама барномаҳо ва бозиҳо мавҷуд аст, оғоз накардаанд.

Чанд муддат ин маро таъқиб мекард - ман дар ҳақиқат мехостам бифаҳмам, ки дар онҳо чӣ пинҳон аст. Агар шумо метавонед сигнали аудиоиро ҳамчун пайдарпаии байтҳо хонед, шумо метавонед аломатҳо ё чизеро ҷустуҷӯ кунед, ки пайдоиши сигналро нишон медиҳад. Як намуди ретро-археология.

Ҳоло, ки ман тамоми роҳро тай кардам ва ба тамғакоғазҳои худи кассетаҳо нигоҳ кардам, ман табассум мекунам, зеро

чавоб дар пеши назари ман буд
Дар лавҳаи кассетаи чап номи компютери TRS-80 ва дар поёни номи истеҳсолкунанда навишта шудааст: "Истехсоли аз ҷониби Radio Shack дар ИМА"

(Агар шумо хоҳед, ки интригаро то охир нигоҳ доред, зери спойлер нашавед)

Муқоисаи сигналҳои аудио

Пеш аз ҳама, биёед сабтҳои аудиоиро рақамӣ кунем. Шумо метавонед гӯш кунед, ки он чӣ гуна садо медиҳад:


Ва чун маъмулӣ сабт аз компютери ZX Spectrum садо медиҳад:


Дар ҳарду ҳолат, дар оғози сабт ба ном вуҷуд дорад оҳанги пилотӣ - садои басомади якхела (дар сабти аввал хеле кӯтоҳ <1 сония, вале фарқ кардан мумкин аст). Оҳанги пилотӣ ба компютер сигнал медиҳад, ки ба қабули маълумот омода шавад. Чун қоида, ҳар як компютер танҳо оҳанги пилотии «худ»-и худро аз рӯи шакли сигнал ва басомади он эътироф мекунад.

Дар бораи худи шакли сигнал чизе гуфтан лозим аст. Масалан, дар ZX Spectrum шакли он росткунҷаест:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Вақте ки оҳанги пилотӣ муайян карда мешавад, ZX Spectrum дар сарҳади экран сутунҳои сурх ва кабудро иваз мекунад, то нишон диҳад, ки сигнал эътироф шудааст. Оҳанги пилот ба охир мерасад набзи синхронӣ, ки ба компютер барои оғози қабули маълумот сигнал медиҳад. Он бо давомнокии кӯтоҳтар тавсиф мешавад (дар муқоиса бо оҳанги пилотӣ ва маълумоти минбаъда) (ниг. расм)

Пас аз қабули набзи синхронизатсия, компютер ҳар як болоравии/пастшавии сигналро сабт намуда, давомнокии онро чен мекунад. Агар давомнокӣ аз маҳдудияти муайян камтар бошад, бит 1 ба хотира навишта мешавад, дар акси ҳол 0. Битҳо ба байтҳо ҷамъ карда мешаванд ва раванд то гирифтани N байт такрор мешавад. Рақами N одатан аз сарлавҳаи файли зеркашида гирифта мешавад. Тартиби боркунӣ чунин аст:

  1. оҳанги пилотӣ
  2. сарлавҳа (дарозии собит), дорои андозаи маълумоти зеркашидашуда (N), номи файл ва навъи
  3. оҳанги пилотӣ
  4. худи маълумот

Барои боварӣ ҳосил кардан, ки маълумот дуруст бор карда шудааст, ZX Spectrum ба номро мехонад байт паритет (байти баробарӣ), ки ҳангоми захира кардани файл тавассути XORing ҳамаи байтҳои маълумоти хаттӣ ҳисоб карда мешавад. Ҳангоми хондани файл, компютер байти паритетро аз маълумоти гирифташуда ҳисоб мекунад ва агар натиҷа аз натиҷаи захирашуда фарқ кунад, паёми хатогии "R Tape loading error" -ро нишон медиҳад. Аниқтараш, компютер метавонад ин паёмро барвақттар диҳад, агар ҳангоми хондан набзро эътироф накунад (набояд ё давомнокии он ба ҳудуди муайян мувофиқат накунад)

Пас, биёед бубинем, ки сигнали номаълум чӣ гуна аст:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Ин оҳанги пилотӣ аст. Шакли сигнал ба таври назаррас фарқ мекунад, аммо маълум аст, ки сигнал аз такрори импулсҳои кӯтоҳи басомади муайян иборат аст. Дар басомади интихобкунии 44100 Гц, масофаи байни "қуллаҳо" тақрибан 48 намунаро ташкил медиҳад (ки ба басомади ~ 918 Гц мувофиқат мекунад). Биёед ин рақамро ба ёд орем.

Акнун биёед ба порчаи додаҳо назар андозем:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Агар масофаи байни импулсхои алохидаро чен кунем, маълум мешавад, ки масофаи байни импулсхои «дароз» хануз ~48 намуна ва байни импулсхои кутох — ~24 намуна мебошад. Каме ба пеш нигоҳ карда, ман мегӯям, ки дар ниҳоят маълум шуд, ки импулсҳои "истеъдод" бо басомади 918 Гц пайваста, аз аввал то охири файл пайравӣ мекунанд. Фарз кардан мумкин аст, ки њангоми интиќоли маълумот, агар дар байни импулсњои истинодї импулси иловагї рў ба рў шавад, мо онро бит 1, дар акси њол 0 њисоб мекунем.

Дар бораи набзи синхронизатсия чӣ гуфтан мумкин аст? Биёед ба ибтидои маълумот назар андозем:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Оҳанги пилотӣ ба итмом мерасад ва маълумот фавран оғоз меёбад. Каме дертар, пас аз таҳлили якчанд сабтҳои гуногуни аудио, мо тавонистем дарёфтем, ки байтҳои аввали маълумот ҳамеша якхелаанд (10100101b, A5h). Компютер пас аз гирифтани маълумот метавонад хондани маълумотро оғоз кунад.

Шумо инчунин метавонед ба тағирёбии набзи аввалини истинод фавран пас аз 1-уми охирин дар байти синхронизатсия диққат диҳед. Он хеле дертар дар раванди таҳияи барномаи шинохти додаҳо кашф карда шуд, вақте ки маълумот дар ибтидои файл устувор хонда намешавад.

Акнун биёед кӯшиш кунем, ки алгоритмеро тавсиф кунем, ки файли аудиоиро коркард мекунад ва маълумотро бор мекунад.

Боркунии маълумот

Аввалан, биёед якчанд фарзияҳоро барои содда нигоҳ доштани алгоритм дида бароем:

  1. Мо танҳо файлҳоро дар формати WAV баррасӣ хоҳем кард;
  2. Файли аудио бояд бо оҳанги пилотӣ оғоз шавад ва набояд дар аввал хомӯширо дар бар гирад
  3. Файли манбаъ бояд суръати интихобкунии 44100 Гц дошта бошад. Дар ин сурат масофаи байни импульсхои истинод-дихии 48 намуна аллакай муайян карда шудааст ва ба мо лозим нест, ки онро ба таври программавй хисоб кунем;
  4. Формати намуна метавонад ҳама гуна бошад (8/16 бит/нуқтаи шинокунанда) - зеро ҳангоми хондан мо метавонем онро ба формати дилхоҳ табдил диҳем;
  5. Мо тахмин мезанем, ки файли манбаъ бо амплитуда ба эътидол оварда шудааст, ки бояд натиҷаро устувор кунад;

Алгоритми хониш чунин хоҳад буд:

  1. Мо файлро ба хотира мехонем ва ҳамзамон формати намунаро ба 8 бит табдил медиҳем;
  2. Мавқеи набзи аввалро дар маълумоти аудио муайян кунед. Барои ин шумо бояд шумораи намунаро бо амплитудаи максималӣ ҳисоб кунед. Барои содда, мо онро як маротиба дастӣ ҳисоб мекунем. Биёед онро ба тағирёбандаи prev_pos захира кунем;
  3. Ба мавқеи набзи охирин 48 илова кунед (pos := prev_pos + 48)
  4. Азбаски 48 зиёд кардани мавқеъ кафолат намедиҳад, ки мо ба мавқеъи импульси истинодҳои навбатӣ мерасем (нуқсонҳои лента, кори ноустувори механизми интиқоли лента ва ғайра), ба мо лозим аст, ки мавқеи импулси посро танзим кунем. Барои ин як пораи хурди маълумотро (pos-8;pos+8) гиред ва арзиши максималии амплитударо дар он пайдо кунед. Мавқеи мувофиқ ба ҳадди аксар дар пос нигоҳ дошта мешавад. Дар ин ҷо 8 = 48/6 як доимии аз тариқи таҷриба гирифташуда мебошад, ки кафолат медиҳад, ки мо максимуми дурустро муайян мекунем ва ба импулсҳои дигаре, ки дар наздикӣ ҳастанд, таъсир намерасонем. Дар ҳолатҳои хеле бад, вақте ки масофаи байни импулсҳо аз 48 хеле камтар ё зиёдтар аст, шумо метавонед ҷустуҷӯи маҷбурии набзро амалӣ кунед, аммо дар доираи мақола ман инро дар алгоритм тавсиф намекунам;
  5. Дар қадами қаблӣ инчунин тафтиш кардан лозим буд, ки набзи истинод умуман ёфт шудааст. Яъне, агар шумо танҳо ҳадди аксарро ҷустуҷӯ кунед, ин кафолат намедиҳад, ки импулс дар ин сегмент мавҷуд аст. Дар татбиқи охирини барномаи хониш ман фарқияти байни арзишҳои максималӣ ва минималии амплитударо дар сегмент тафтиш мекунам ва агар он аз ҳадди муайян зиёд бошад, ман мавҷудияти импулсро ҳисоб мекунам. Савол ин аст, ки агар набзи истинод пайдо нашавад, чӣ бояд кард. 2 вариант вуҷуд дорад: ё маълумот ба охир расид ва хомӯшӣ паси сар мешавад, ё ин бояд хатои хониш ҳисобида шавад. Бо вуҷуди ин, мо барои содда кардани алгоритм инро сарфи назар мекунем;
  6. Дар қадами навбатӣ, мо бояд мавҷудияти импулси маълумотро муайян кунем (бит 0 ё 1), барои ин мо мобайни сегменти (prev_pos;pos) middle_posро ба миёна_pos := (prev_pos+pos)/2 мегирем ва дар баъзе маҳаллаи middle_pos дар сегмент (middle_pos-8;middle_pos +8) биёед амплитудаи максималӣ ва минималиро ҳисоб кунем. Агар фарқияти байни онҳо аз 10 зиёд бошад, ба натиҷа бит 1 менависем, дар акси ҳол 0. 10 доимист, ки бо роҳи таҷриба гирифта мешавад;
  7. Мавқеи ҷорӣро дар prev_pos захира кунед (prev_pos := pos)
  8. Аз қадами 3 то он даме ки мо тамоми файлро хонем, такрор кунед;
  9. Массиви битҳои натиҷавӣ бояд ҳамчун маҷмӯи байтҳо захира карда шавад. Азбаски мо байтҳои синхронизатсияро ҳангоми хондан ба назар нагирифтаем, шумораи битҳо метавонад чандкаратаи 8 набошад ва ҷуброни битҳои зарурӣ низ маълум нест. Дар татбиқи аввалини алгоритм, ман дар бораи мавҷудияти байти синхронизатсия намедонистам ва аз ин рӯ танҳо 8 файлро бо рақамҳои гуногуни битҳои офсетӣ захира кардам. Яке аз онҳо маълумоти дурустро дар бар мегирад. Дар алгоритми ниҳоӣ, ман танҳо ҳама битҳоро то A5h хориҷ мекунам, ки ин ба ман имкон медиҳад, ки фавран файли баромади дурустро гирам.

Алгоритм дар Ruby, барои онҳое, ки таваҷҷӯҳ доранд
Ман Рубиро ҳамчун забон барои навиштани барнома интихоб кардам, зеро... Ман аксар вақт онро барномарезӣ мекунам. Варианти баландсифат нест, аммо вазифаи ҳарчи зудтар кардани суръати хониш ба он намеарзад.

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

Дар натиҷа

Якчанд вариантҳои алгоритм ва константаҳоро санҷида, ман хушбахт будам, ки чизи бениҳоят ҷолибро ба даст овардам:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Ҳамин тавр, аз рӯи сатрҳои аломатҳо, мо барномаи тарҳрезии графикҳоро дорем. Аммо дар матни барнома калимаҳои калидӣ вуҷуд надоранд. Ҳама калимаҳои калидӣ ҳамчун байт рамзгузорӣ карда мешаванд (ҳар як арзиш > 80h). Ҳоло мо бояд бифаҳмем, ки кадом компютер аз солҳои 80-ум метавонад барномаҳоро дар ин формат захира кунад.

Дар асл, он ба барномаи BASIC хеле монанд аст. Компютери ZX Spectrum барномаҳоро тақрибан дар як формат дар хотира нигоҳ медорад ва барномаҳоро дар навор захира мекунад. Дар ҳар сурат, ман калимаҳои калидиро бар зидди тафтиш кардам ҷадвал. Бо вуҷуди ин, натиҷа баръало манфӣ буд.

Ман инчунин калимаҳои калидии BASIC-и машҳури Atari, Commodore 64 ва якчанд компютерҳои дигари он вақтро тафтиш кардам, ки ман тавонистам ҳуҷҷатҳоро пайдо кунам, аммо бе муваффақият - дониши ман дар бораи намудҳои компютерҳои ретро он қадар васеъ набуд.

Баъд ман қарор додам, ки равам рӯйхат, ва баъд нигоҳи ман ба номи истеҳсолкунанда Radio Shack ва компютери TRS-80 афтод. Инҳоянд номҳое, ки дар лавҳаҳои кассетаҳое, ки рӯи мизи ман хобидаанд, навишта шуда буданд! Ман қаблан ин номҳоро намедонистам ва бо компютери TRS-80 ошно набудам, аз ин рӯ, ба назарам чунин менамуд, ки Radio Shack як истеҳсолкунандаи кассетаи аудиоӣ ба мисли BASF, Sony ё TDK аст ва TRS-80 вақти навозиш аст. Барои чӣ не?

Компютер Tandy / Radio Shack TRS-80

Эҳтимол дорад, ки сабти аудиоии мавриди назар, ки ман онро дар аввали мақола ҳамчун намуна овардам, дар компютер чунин сохта шудааст:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Маълум шуд, ки ин компютер ва навъњои он (Модели I/Модели III/Модели IV ва ѓайра) як ваќтњо (албатта, на дар Русия) хеле маъмул буданд. Қобили зикр аст, ки протсессори онҳо истифодашуда низ Z80 буд. Барои ин компютер шумо метавонед дар Интернет пайдо кунед маълумоти зиёде. Дар солҳои 80-ум маълумоти компютерӣ паҳн карда шуд журналхо. Дар айни замон якчанд эмуляторҳо компютерҳо барои платформаҳои гуногун.

Ман эмуляторро зеркашӣ кардам trs80gp ва бори аввал ман тавонистам бубинам, ки ин компютер чӣ гуна кор мекунад. Албатта, компютер баромади рангҳоро дастгирӣ намекард, ҳалли экран ҳамагӣ 128x48 пиксел буд, аммо васеъшавӣ ва тағиротҳои зиёде мавҷуданд, ки ҳалли экранро зиёд карда метавонистанд. Инчунин имконоти зиёде барои системаҳои оператсионии ин компютер ва имконоти татбиқи забони BASIC мавҷуд буданд (ки бар хилофи ZX Spectrum, дар баъзе моделҳо ҳатто ба ROM "дурахш" нашуда буд ва ҳама гуна вариантро метавон аз диски нарм бор кард, ба мисли худи OS)

Ман ҳам ёфтам фоиданок барои табдил додани сабтҳои аудио ба формати CAS, ки онро эмуляторҳо дастгирӣ мекунанд, аммо бо баъзе сабабҳо бо истифода аз онҳо сабтҳоро аз кассетаҳои ман хондан имкон надошт.

Пас аз фаҳмидани формати файли CAS (ки он танҳо як нусхаи каме маълумот аз наворе буд, ки ман аллакай дар даст доштам, ба истиснои сарлавҳа бо мавҷудияти байти синхронизатсия), ман чанд тағирот ба барномаи ман ва тавонист файли кории CAS-ро, ки дар эмулятор кор мекард (TRS-80 Model III) баровардааст:

Чӣ тавр ман маълумотро дар формати номаълум аз лентаи магнитӣ барқарор кардам

Ман версияи охирини утилитаи табдилро бо муайян кардани автоматии набзи аввал ва масофаи байни импулсҳои истинод ҳамчун бастаи GEM тарҳрезӣ кардам, рамзи манбаъ дар ин ҷо дастрас аст Github.

хулоса

Рохе, ки мо тай кардем, саёхати ачоиб ба гузашта гардид ва ман шодам, ки дар охир чавоби онро ёфтам. Дар байни чизҳои дигар, ман:

  • Ман формати захира кардани маълумотро дар ZX Spectrum фаҳмидам ва реҷаҳои дарунсохташудаи ROM-ро барои захира кардан/хонидани маълумот аз кассетаҳои аудио омӯхтам.
  • Ман бо компютери TRS-80 ва навъҳои он шинос шудам, системаи оператсиониро омӯхтам, барномаҳои намунавиро дидам ва ҳатто имкони ислоҳи кодҳои мошинро доштам (охир, ҳама мнемоникаи Z80 ба ман шиносанд)
  • Як барномаи мукаммал барои табдил додани сабтҳои аудиоӣ ба формати CAS, ки метавонад маълумотеро, ки аз ҷониби утилитаи "расмӣ" эътироф нашудааст, хонд.

Манбаъ: will.com

Илова Эзоҳ