Апаратне перехитрування затримки §
Якщо ви маєте підсилювач та інше потрібне обладнання, і, наприклад, ви просто хочете записати партію, а потім зробити реампінг чи додати ще якісь ефекти, то ви можете розділити сигнал (використавши чи подвійний кабель, чи ABY-педаль, чи самостійно спаяти розгалужувач), і один вивід записувати на комп’ютері, а інший пропустити через свою апаратуру та слухати. Це набагато зручніше.
Але якщо ви замінили все гітарне обладнання комп’ютером, то прийдеться боротися з затримкою, що я й описуватиму нижче.
Далі про те, як узагалі відбувається обробка й від чого затримка, бо я свого часу хотів це знати і не мав простого пояснення. Якщо вам то не цікаво, можете перейти до #конкретно змінюємо значення.
Рахуємо затримку §
Під час оцифровування з неперервної звукової хвилі з фіксованим інтервалом зберігають значення її амплітуди — семпл (зразок). Таке перетворення сигналу називається дискретизацією. Найчастіше в комп’ютерному аудіо використовується частота дискретизації 48 кГц (48000 семплів на секунду).
- Кадр
- це розмір семплу (в байтах), помножений на кількість каналів аудіо (у стерео 2 канали, в моно — 1).
- Наприклад, для стереосистеми, 16-біт, 44.1 кГц, маємо семпл 16 бітів — 2 байти, тож кадр буде
2*2=4
(байти). - Період
- кількість кадрів між кожним апаратним перериванням.
Більше про це тут і за посиланнями в кінці сторінки.
Затримка у процесі захоплення 1 §
Lc = n / f
- Lc — затримка захоплення (мс),
- n — розмір буфера (розмір періоду * кількість періодів, наприклад, 2 періоди по 1024 кадри дадуть розмір буфера 2048),
- f — частота дискретизації (sample rate) в кілогерцах (кГц).
Затримка програвання зважає ще на кількість періодів p:
Lp = n * p / f
Наприклад, ми обрали розмір буфера n=256, періодів p=2, і частота дискретизації f=48 кГц:
Lc = 256/48=5.(3), Lp = 256 * 2/48=10.(6), тоді весь час затримки буде дорівнювати 16 мс
Що за буфер? §
Мова про циклічний (кільцевий) буфер. Це структура даних, яка якраз тут використовується.
Уявіть кільце, поділене на сегменти, в які ми записуємо або з яких читаємо дані по колу (як у перегонах, можна уявити, що одне авто замальовує сектори на замкненій дорозі, а інше фотографує їх). Очевидно, коли ми запишемо дані у всі сегменти, то повернемось на початок і будемо перезаписувати старі сектори.
Повернімося до наших авто — якщо фотограф малюнків не встигатиме за художником, то він не збереже всі малюнки, адже авто, яке малює, просто перемалює деякі з них до того, як вони будуть зняті. Іншими словами, вказівник запису обжене вказівник зчитування, тому встигатиме переписати сегменти до того, як вони будуть зчитані. Так само, якщо запис відстане від читання, то теж будуть глюки, бо не буде, що читати.
Отже, чим менший розмір буфера, тим більший ризик такої фігні, але й менше часу витрачається на прохід одного кола, тому затримка сигналу менша.
Конкретно змінюємо значення §
Тепер ми знаємо, що для скорочення затримки нам потрібно зменшити розмір буфера та збільшити частоту дискретизації так, щоб при цьому не виникало X-run-ів.
- X-run
- скорочення від buffer over- або underrun, тобто пере- або недоповнення буферу. тобто програма не встигла або обробити дані з буферу, або надіслати їх у буфер. Вони звучать як різка просадка звуку (ляскання, клацання, тріск), та їх, очевидно, варто уникати.
Сучасні аудіоінтерфейси можуть працювати на високих частотах (до 192 Гц), і це, як бачимо, зручно, хоча варто зважати, що деякі плагіни/програми не працюють на певних частотах дискретизації, тому якщо щось не працює, повертайте, як було (зазвичай 41 чи 48 кГц). Також, очевидно, чим менша затримка звуку, тим більше енергії витрачається на його обробку.
Налаштувати все можна, наприклад, у конфігураційному файлі PipeWire:
default.clock.rate = значення # частота дискретизації (44100, 48000, 96000, 192000)
default.clock.quantum = значення # розмір буфера (..., 1024, 512, 256, 128, ..., 16, 8)
У графічних програмах зазвичай легко знайти потрібні кнопки buffer (buffer size, frames/period)
та sample rate
.
Мої експерименти показали, що розмір буфера 64 і нижче за частоти 96 кГц уже файно. 128 ще відчувається конкретно.
Що ще можна зробити? §
- Можна спробувати ядро “low latency” (чи realtime, забув). Але в більшості випадків воно не потрібне. Можете також використовувати збірку, де все вже чудово налаштоване, наприклад, із перелічених тут
- Також варто встановити пакунок
realtime-privileges
в Арчі й додати свого користувача до групиrealtime
. - Повід’єднувати різні пристрої (так, юсб, відеокарти, будь-що). Чим менше переривань відбувається, тим більше у процесора ресурсів для обробки звуку. Заміна HDD на SSD та відмова від шифрування диску ніби теж може допомогти, але якщо комп’ютер не суто для роботи з аудіо, то все-таки я б пожертвував швидкістю обробки звуку на користь захисту даних.
Корисно почитати §
- https://wiki.linuxaudio.org/wiki/system_configuration
- https://wiki.archlinux.org/title/JACK_Audio_Connection_Kit
- https://wiki.archlinux.org/title/Realtime_process_management
- https://youtube.com/watch?v=GUsLLEkswzE кльове відео
- https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Audio_concepts
- вимірювання затримки (для нердів).
- https://treefallsound.com/wiki/doku.php?id=performance_tests