У мяне даўно ляжала нататка ў спісе ідэй: па гуле сеткі ў запісе можна сказаць, калі ён зроблены. Калі генерацыя вышэй за нагрузку, частата сеткі крыху падымаецца. Калі ніжэй, крыху апускаецца. Гэты дрэйф даходзіць да кожнай разеткі ў сетцы адначасова. Мікрафон побач з праводкай або з прыборам, які гудзе, яго запісвае, таму гул працуе як гадзіннік. Крыміналістычныя артыкулы пра гэта ёсць з 2005 года. Я лічыў пытанне вырашаным і ні разу не правяраў, ці чуе тэлефон гэты гул насамрэч і якой даўжыні мусіць быць запіс.
NESO публікуе частату брытанскай сеткі за кожную секунду, таму спачатку я спампаваў жнівень 2026 года. Самае нізкае значэнне было 49,747 Гц 31 жніўня а 17:30 па гадзінніку файла, самае высокае 50,242 Гц а 22:01 таго ж дня. Толькі 40% секунд ляжалі ў межах 50 мГц ад наміналу.
Даныя
Запісы ўзятыя з набору ENF-WHU, які сабралі Гуан Хуа і суаўтары, пад ліцэнзіяй MIT. Гэта 130 запісаў, зробленых ва Уханьскім універсітэце і побач з ім на смартфон і дыктафон: у аўдыторыях, кабінетах, інтэрнатах і на дарожках кампуса. Па маім падліку яны доўжацца ад 4,5 да 16 хвілін, 8 кГц, мона. Да кожнага запісу дадаецца сігнал сеткі за ўсе суткі, у якія ён зроблены, зняты з разеткі з частатой дыскрэтызацыі 400 Гц. Гэта 28 сутачных файлаў. Яшчэ ў наборы ёсць 10 запісаў наогул без гулу, іх я пакінуў як кантрольную групу. У Кітаі, як і ў Еўропе, сетка на 50 Гц. Другім наборам стаў месяц NESO з акругленнем да 1 мГц. Поле пошуку ў ім у 31 раз большае за сутачнае.
Метад я напісаў самы просты, які змог. Python 3.12, numpy 2.5.3, scipy 1.18.1. Акно ў 16 секунд ссоўваецца з крокам у 1 секунду. У кожным акне я знаходжу пік спектра каля частаты гулу і ўдакладняю яго парабалай, так атрымліваецца адна частата на секунду. Гэтая крывая слізгае па сутках. Перамагае становішча з найвышэйшай карэляцыяй Пірсана. Сапраўднае становішча дае чысты эталон таго ж запісу, як раіць README набору. Трапленнем лічыцца адказ не далей за 5 секунд ад яго.
На 50 Гц гулу амаль няма
Першай здагадкай былі самі 50 Гц. Там пошук знайшоў правільнае становішча для 4 запісаў са 130.
Гул ёсць, але вышэй. На 100 Гц, другой гармоніцы, той жа пошук знайшоў 116. Магчыма, мікрафон тэлефона дрэнна бярэ 50 Гц, бо для маўлення такія нізкія частоты не патрэбныя, але прылады я не правяраў. Выбраць 100 Гц, ужо пабачыўшы вынік, значыць махляваць. Таму праграма бярэ тую гармоніку ад 50 да 350 Гц, у якой пік найбольш вылучаецца над суседнімі частотамі. Часцей за ўсё яна выбірала 100 Гц, але 41 раз узяла 200 Гц і 6 разоў 300 Гц.
З гэтым правілам 113 запісаў са 130 трапілі не далей за 5 секунд ад сапраўднага часу. Аўтаматычны выбар страціў 3 запісы ў параўнанні з фіксаванымі 100 Гц, усе на 200 Гц, дзе знайшліся толькі 29 з 41. На трапленнях медыянная памылка крывой была 3,4 мГц, а сама сетка ўнутры тыповага запісу змянялася прыкладна на 19 мГц.
Промах, які быў не мой
У ранняй версіі скрыпта самым дзіўным промахам быў запіс 91. Карэляцыя 0,991, ідэальнае супадзенне па ўсіх паказчыках, якія ў мяне былі, але адказ адстаяў ад сапраўднага на 2 гадзіны. Спачатку я шукаў памылку ў сваім пошуку. Толькі потым параўнаў сутачны эталон сам з сабой.
У 089-107_ref.wav гадзіна файла з 1:00 да 2:00 стаіць 6 разоў запар, да 7:00. Адлікі тыя самыя, толькі кожная копія зрушаная на 4 адлікі пазней за папярэднюю, гэта значыць на 10 мс пры 400 Гц. Спачатку мне здалося, што гэта 2 гадзіны, паўтораныя 3 разы, бо зрух на 2 гадзіны таксама супадае. Другая праверка знайшла перыяд у 1 гадзіну. Пазней я праверыў увесь файл на паўторы з любым зрухам. Тая ж гадзіна знайшлася яшчэ раз, з 9:00 да 10:00, пасля 2 гадзін нармальных даных. У README напісана, што сутачныя файлы доўжацца 24 гадзіны. Гэты доўжыцца 23 гадзіны, сваіх з іх толькі каля 17. Як так выйшла, я сказаць не магу. У астатніх 27 сутачных файлах паўтораў няма наогул.
Для запісаў з гэтых гадзін у эталоне ёсць 7 амаль аднолькава добрых становішчаў. Сапраўднае становішча знаходзіцца тым жа пошукам, значыць гэта адна з тых жа 7 копій. У выніковым прагоне запіс 91 трапіў на тую ж копію, што і яго чысты эталон. Запіс 90 таксама з гэтых гадзін і трапіў за 4 секунды ад месца свайго эталона. Абодва залічаныя як трапленні, але толькі таму, што запіс і чысты эталон абодва выбіраюць самую раннюю копію, а ад астатніх яна адрозніваецца толькі ў пятым знаку пасля коскі. Ніводнага з іх праверыць нельга, таму я лічу 111 з 128.
2 промахі памыліліся на 7 і 8 секунд, гэта амаль трапленні. Астатнія 15 памыліліся на гадзіну і больш. 12 з іх былі запісамі, дзе праграма выбрала 200 Гц. Запіс 85 супаў з карэляцыяй 0,877 і памыліўся на 6 гадзін. 10 запісаў без гулу далі максімум 0,506 з любымі з 28 сутак, так што 0,877 выглядае пераканаўча.
Промах выдае адрыў ад наступнага лепшага месца, якое ляжыць далей чым за хвіліну ад першага. У гэтых 15 ён быў не больш за 0,035, у трапленняў медыяна 0,18. Правіла “верыць адказу, толькі калі адрыў большы за 0,04” пакідае 103 трапленні са 113 і адкідае запісы 90 і 91. Яно прапускае 1 промах, той, што на 8 секунд. Але 0,04 я выбраў, гледзячы на гэтыя ж 130 запісаў. Другога набору, на якім можна праверыць парог, у мяне няма.
Якой даўжыні хапае
Потым я абрэзаў кожны запіс да першых N секунд і шукаў зноў. Гармоніка па-ранейшаму выбіралася па ўсім запісе. 30 секунд не знайшлі амаль нічога, 16 са 130. З 2 хвілінамі знайшлося 89, з гэтага ўжо можна працаваць. 5 хвілін знайшлі 103 са 129 запісаў, якім на гэта хапіла даўжыні. Акно з’ядае 15 секунд, таму поўныя 10 хвілін крывой даюць толькі 49 запісаў. З іх знайшліся 42.
Далей быў месяц. Гэтым разам памылка была ў маім кодзе. Першы прагон паказаў, што чысты кавалак сігналу сеткі даўжынёй 30 секунд знаходзіць сваё месца толькі 53 разы з 200. Тут я ўбачыў карэляцыі, большыя за 1, да 2,67. Сумы значэнняў каля 50 за 2,7 млн секунд губляюць дакладнасць, у ціхіх вокнаў дысперсія выходзіла амаль нулявой. Калі я пачаў цэнтраваць эталон перад сумаваннем, усе 200 чыстых кавалкаў знайшлі сваё месца.
Для сумленнай праверкі я дадаў да выпадковых вокнаў кавалкі рэальнай памылкі вымання частаты, гэта значыць розніцу паміж запісам WHU і яго эталонам. Тут трапленне стражэйшае, у межах 2 секунд. З памылкамі 10 хвілін знайшлі 160 з 200, а 1 хвіліна каля паловы. Яшчэ я ўзяў памылкі толькі з тых запісаў, што былі трапленнямі. Тады 10 хвілін знайшлі 183.
На 5 і 10 хвілінах месяц выйшаў прыкладна на 6 працэнтных пунктаў ніжэй за суткі, гэта ў межах шуму пры 200 вокнах. На 30 секундах месяц быў наперадзе, 80 з 200 супраць 16 са 130. Так што за большае поле пошуку прыкметна плаціць не давялося. Я думаю, што чысціня гулу вырашае больш, але тут склееныя 2 розныя сеткі. Унутры 10 хвілін брытанская частата ходзіць мацней, медыянны раскід 26 мГц супраць 19. Наколькі гэта дапамагае, я не мераў.
Чаго я не правяраў
Свайго запісу з вядомым часам у мяне няма. Запісы з аднаго кампуса, прылады я ведаю толькі па апісанні. У аўтараў набору ёсць дасканалейшыя метады з узмацненнем гармонік. Яны, напэўна, прыбралі б частку з гэтых 15 промахаў. Відэа я не спрабаваў, там гул прыходзіць праз мігценне святла. Яшчэ я не правяраў змантаваныя запісы, хоць той жа метад ужываюць і для пошуку склеек.