Джерело
Стендап Сьогодні | Аудіо — дуже складно, насправдіСьогодні пост не про LLM! Я теж радий.Я...
360 Охват/переглядів
2026-06-09 15:27
Повідомлення №1460
Аудіо — дуже складно, насправдіСьогодні пост не про LLM! Я теж радий.Я тут роблю застосунок для розбору пісень для танців. Кілька місяців тому зробив онлайн варіант, але зараз переробляю у вигляді мобільного застосунку. Традиційно, 80% зусиль пішло на аспект, який здавався мені тривіальною базою, яка сама по собі нікому й не потрібна.Отже, в серці застосунку лежить те, що інтерфейс рухається в такт пісні. Насамперед рахує удари — як метроном. Для того ми визначаємо BPM - удари на хвилину, привʼязуємо перший удар, і потім в момент часу T нескладна математика каже нам, що грає удар N вісімки M, ну з цим проблем ніяких.Але виявилося несподівано складно відтворити це в інтерфейсі. Здавалося б, будь-який програвач таке вміє. Не зовсім. Біт на екрані розповзався від звуків пісні. Я довгий час думав, що то в мене нема хисту визначити BPM та оскільки помітити десинхронізацію треба на око (та вухо), це було дуже важко підтвердити. Але без нормальної привʼязки до аудіо решту функцій можна було не будувати.Першим чином я думав, що гальмує React Native? (Ну бо це те, з чим знайомий.) Трішечки такого ефекту було, але насправді біт в пісні це близько 500 мс, та ніякий RN настільки не гальмує. Звісно, оптимізувати було що, бо екран пісні, як бачите, жирний та весь його перемальовувати не гарно. Тут нічого особливого.Друге — затримка аудіовиходу. Така затримка є, особливо якщо програвати через Bluetooth вона сягає 200 мс та більше... Але то теж навіть не один удар. Втім, дізнався, що принаймні в iOS є вбудована можливість дізнатися тривалість затримки поточного виходу. (Та звісно — в кожного виходу власна затримка.) Що й потрібно для того, щоб відповідно затримувати оновлення інтерфейсу. На щастя, це одноразове та автоматичне покращення, та хоч я зробив інтерфейс для редагування цієї затримки, базових налаштувань достатньо.Справжні цікавинки почалися, як закопався у формат файлів. Власне, помітив, що на відміну від моєї замученої піддослідної пісні, інша грає та перемотується без жодних проблем. Між піснями знайшлася важлива технічна різниця. Отже: для точної перемотки потрібне кодування з CBR, тобто сталим бітрейтом, (а не VBR - змінним). Оскільки не бачу сенсу вимагати CBR від користувачів, впровадив перекодування в CBR на вході. Зберігав я у формат AAC.(Змінний бітрейт суттєво ефективніше, я памʼятаю ще як перекодовував власну колекцію MP3, щоб більше влізло в плеєр. Суть його в тому, що простіші місця пісні будуть стиснуті більше.)Перехід до CBR відразу зробив перемотку стабільною. Це був очевидний успіх. Але зʼявилася нова дивна річ: певні місця в пісні завжди перемотувалися неправильно. Ну, наприклад, в той час, як перемотуєш на другий удар, грає ще перший. Причому, тільки після певної перемотки! Якщо грати з початку пісні, такого не було.Тут я дізнався ще один нюанс: файл AAC не "проіндексований", це плаский потік даних. Тому, хоч перемотка і працювала стабільно, але не завжди вона була точною. (А мені, на відміну від типового програвача, потрібна ідеально точна перемотка.) Виявилося, що залишається загортати потік AAC в контейнер M4A. M4A як раз додає індекс, метадані тощо. От ніколи не думав про медіакодеки та медіаконтейнери, а довелося.Та, о щастя, пісні в CBR M4A відтворюються так, як треба! База, про яку ніхто й не подумає, закріплена надійно.👑 Patreon ︙ ☕ BuyMeACoffee