Звуковий сервер jack. Пишемо найпростіший клієнт: теорія

Відео: I can # 39; t start Jack from QJackctl even though I have an Alsa supported soundcard

Звуковий сервер JACK. Пишемо найпростіший клієнт: теорія
З ростом популярності звукового сервера JACK (https://jackaudio.org) вільні програми для створення музики вийшли на новий якісний рівень. Раніше було так, що програміст, забажав написати свій синтезатор, хвильової редактор або DAW (Digital Audio Workstation, робоча станція з обробки цифрового звуку), повинен був потурбуватися ще й введенням-виведенням звуку, створити свій код для спілкування з низкоуровневой звуковою підсистемою начебто ALSA або CoreAudio. А JACK набагато спростив цю справу.

На плечі JACK покладено не тільки спілкування зі звуковою підсистемою, але і можливість взаємодії між програмами, що використовують сервер JACK. Наприклад, можна одночасно запустити драм-машину Hydrogen і DAW Ardour, потім запустити в Ardour пісню на відтворення - при цьому почнеться відтворення партії ударних в Hydrogen. «Прокручуємо» матеріал в одній програмі - прокрутка передається і в іншу. Цю можливість дають транспортні функції JACK. Але більш відомі інші його функції - надання портів введення-виведення. Ці порти можна пов`язувати між собою, направляючи звукові потоки не тільки на виходи звукової карти, але і в інші програми - клієнти сервера JACK. Клієнти теж мають порти введення-виведення.

Зараз рідко зустрінеш велику «звукову» програму, яка б не підтримувала JACK. Судіть самі. Ardour працює через JACK - втім, не дивно, адже розробник-то один - легендарний Пол Девіс (Paul Davis), який почав писати Ardour десять років тому в підвалі, коли від нього пішла дружина. Rosegarden - це JACK. Qtractor - це JACK, крім того, автором Qtractor є rncbc aka Rui Nuno Capela, творець популярного графічного центру управління JACK - qJackCtl. MUSE - знову JACK. Інші кити звукового ПО, що працюють через цей сервер: Hydrogen, LMMS. Та що там казати - навіть деякі програвачі обзавелися підтримкою JACK.

Велика ймовірність, що якщо ви задумали писати навіть невелику звукову програму, то вирішите пов`язати її долю з JACK. Адже це не тільки полегшить вашу працю, а й автоматично зробить програму придатною для спільної роботи з іншими JACK-програмами. Припустимо, вам ліньки писати свої індикатори гучності, а хочеться бачити піки на власні очі. Всього парою клацань миші можна буде послати висновок з вашої програми в таку, де ці індикатори є. Більш того, існує окрема програма з індикаторами - Meterbridge (http: // plugin. Org.uk/meterbridge). Навіть якщо ваша програма - консольна, можна використовувати для виведення графіки інший JACK-клієнт, той же Meterbridge.

Отже, JACK. З чого почати? З скачування початкових кодів та документації з https://jackaudio.org. В архіві з кодами є приклади. На жаль, жоден з них не показує найважливішу річ: як завантажити хвильової файл і відтворити його через JACK.

У цій статті я заповню прогалину, а заодно на прикладі постараюся показати основи роботи JACK. Передбачається, що ви знаєте Сі або С ++. Приклад буде на С ++ з використанням бібліотеки Qt - втім, якщо ви з нею не працювали, не біда: замініть виклики qDebug на cout, і справа в шляпе- плюс невелика метушня з підключенням бібліотек. Ні в прикладі нічого такого, що не можна було б висловити і на звичайному Сі.

Крім Qt нам знадобиться, звичайно ж, сам JACK з заголовками файлами, а ще бібліотека libsndfile (http: // mega-nerd.com/libsndfile), яка забезпечить завантаження хвильових файлів (WAVE). Якщо у вас немає готових WAV-файлів - скачайте з freesound.org. Буде потрібно стереозвук будь розрядності з частотою оцифрування 44100 або 48000 герц.

Залежно від частоти оцифровки треба буде запустити сервер JACK. Його найпростіше запускати через утиліту qJackCtl і частоту оцифровки вибрати в настройках, але можна з консолі:
jackd -d alsa -r 44100

У цьому прикладі ми запускаємо сервер з бекенда ALSA і частотою оцифровки 44100 герц. Запуск JACK з мінімумом параметрів виглядає так:
jackd -d alsa

При цьому частота оцифровки буде дорівнює 48000 герц. У статті я не чіпаю тему запуску сервера в реальному часі і тонкої настройки різних параметрів - нам потрібен просто працює сервер. Перш ніж почати власне виклад прикладу, нагадаю, що таке цифровий звук і звідки він береться. Це потрібно для введення в подальший виклад деяких термінів, один з яких - «семпл» (в різних областях звукового світу трактується по-різному). Як оцифрований звук потрапляє в комп`ютер ззовні? Наприклад, людський голос? Як ви знаєте, звук, який ми чуємо, це коливання повітря - зміни його щільності. Ці коливання вловлюються мікрофоном і теж перетворюються в коливання, але вже електромагнітні - зміни напруги. Ці зміни надходять на АЦП - аналого-цифровий перетворювач звукової карти, завдання якого - ставити у відповідність вступнику рівнем напруги певні числа. Це і є оцифровка звуку.




Отже, числами можна висловити коливання. Які саме числа і в якому діапазоні - залежить від формату. Наприклад, при форматі оцифровки 16 біт зі знаком ми маємо для запису рівня сигналу числа від -32768 до +32767. А при беззнакову восьмібітного форматі у нас всього 256 чисел, від 0 до 255. Чим більший діапазон чисел, тим точніше можна виразити ними зміни рівня.

Звуковий сервер JACK. Пишемо найпростіший клієнт: теорія

АЦП вимірює (і перетворює в числа) надходять електромагнітні коливання стільки-то раз в секунду, знову ж таки - в залежності від обраної частоти оцифровки. Наприклад, коли говорять про частоту 44100 герц - це значить, що АЦП кожну секунду перетворює в числа по 44100 «вимірів». До речі, на звичайних музичних дисках, в більшості MP3 і Ogg саме така частота оцифровки. А в фільмах зазвичай інша - 48 кілогерц, або 48000 герц. Так ось, кожне таке «число-завмер» і називається семплом. Семплами також іменуються і цілі хвильові файли або навіть інструменти особливих форматів, але то вже семпл не з області програмування, що не низького рівня, а з-поміж музикантів-клавишников і діджеїв.

Крім цілочисельних значень семпл може бути представлений дробовим числом, в так званому форматі з плаваючою точкою - грубо кажучи, кожен семпл представлений змінною типу float. І при цьому число - «завмер» - піддано нормалізації, тобто належить в діапазон від -1.0 до +1.0. Наприклад, семпл при такому розкладі може бути дорівнює 0.324345, 0.2345, тощо. Навіщо все це, якщо цілі числа начебто простіше?

У цифровій обробці звуку значення семплів легко виходять за межі діапазонів, які охоплюються типами даних. Наприклад, у нас є два 16-бітних сигналу - дві послідовності 16-бітових семплів. Два масиву: А і Б. Ми хочемо їх змікширувати в один сигнал. Припустимо також, що A [4] = 30000, Б [4] = 20000.




Як микшируются сигнали? Просто складаються (хоча в справжніх, чи не умовних, цифрових мікшерах до сигналів ще застосовують купу операцій - в тому числі, з управління рівнем сигналу). Склавши 30000 і 20000, ми отримаємо 50000 - число, що виходить за межі діапазону, що надається 16 бітами (числа від -32768 до +32767). Очевидно, що в цьому місці мікшування звук буде зіпсований.

Подібний ефект називається clipping ^ і звучить як неприємний різкий звук. Звичайно, є і цілочисельні алгоритми обробки звуку, але в них багато хитрощів, а ось алгоритми з плаваючою точкою простіше. Там у нас більше свободи дії: складаючи числа від -1.0 до +1.0, ми якщо і виліземо за їх межі, то за межі самого типу float не вийдемо. Так, гучний звук все одно доведеться робити тихіше (це окремий разговор- коротко - діленням на ціле число або множенням на дробові), але у нас не відбувається цифрове Зашків-ливание, цей самий clipping.

Ось чому в JACK прийнятий саме цей спосіб представлення звуку - у вигляді семплів типу float, з нормалізацією. Як взагалі працює JACK?

Насамперед варто розповісти про портах. JACK надає порти: окремо для введення (input), окремо для виведення (output). Порти можуть бути пов`язані як з «залізною» звуковою картою (точніше, із звуковою підсистемою начебто ALSA), так і з JACK-клієнтами, у яких теж свої порти.

В контексті JACK вхідний порт - це порт, куди ми можемо посилати звук. Вхідні порти з іменами playback_1 і playback_2 відповідають, грубо кажучи, двом каналам лінійного виходу звукової карти.

Отже, вхідні порти JACK - це порти, куди ми посилаємо звук. А вихідні порти - то, звідки ми можемо отримувати звуковий сигнал. Звичайні такі порти - capture_1 і capture_2. Це, знову ж таки грубо кажучи, два канали лінійного входу звукової карти.

Якщо, наприклад, з`єднати capture_1 і playback_1, ми миттєво переспрямуємо звук з мікрофона на колонки. Та ж історія і при розробці мобільних додатків (https://kingbird.ru/mobilnye-prilozheniya/) даного класу, тільки роль колонок тут на себе бере динамік!

Коли ми пишемо JACK-клієнт, передбачаємо його підключення до портів - при цьому створюємо в клієнті свої порти, які стають доступні через JACK для інших клієнтів. Найпростіший JACK-клієнт для відтворення звукового сигналу діє так:
- підключається до сервера, створивши порти для спілкування з ним-
- Готує звукові дані (синтезує сигнал або завантажує з хвильового файлу) -
- частинами передає цей сигнал на вхідний порт JACK.

Всі три етапи ми розглянемо нижче докладно, але спочатку - пара слів про третій етап. Ви повинні надати движку JACK callback-функцію виду:
int process (jack _ nframes _ t nframes, void * arg) -

У цій функції ви будете передавати серверу свої звукові дані по частинах. JACK викликає функцію і в параметрі nframes вказує, скільки кадрів даних треба взяти з якогось вашого внутрішнього буфера і передати їх на вхідний порт JACK. Як саме передати - поговоримо далі. Але що таке «кадри»?

Припустимо, у нас є двоканальний (стерео) сигнал, кожен - з 777 семплів. Число умовно! А JACK просить - знову ж умовно - 3 кадри. Це означає, що сервера треба передати 3 семпли лівого каналу, і 3 семпли правого. Поточний кадр позначає не фізичну позицію в буфері, а скоріше абстрактну позицію, номер семпли, як якщо б у сигналі був тільки один канал. На ділі ж дані в буфері зберігаються так: семпли різних каналів йдуть один за одним послідовно, тобто перший семпл лівого каналу, потім перший семпл правого, потім другий лівого, потім другий правого, і так далі. Цей спосіб зберігання називається «переміжним» (interleaved).

У другій частині статті (в наступному випуску «Open Source») ми, озброївшись цими знаннями, напишемо простий клієнт, який вміє завантажувати хвильової файл, підключатися до вхідних портів JACK і відтворювати долучення.

ІНШЕ

Пол девіс: не тільки jack фото

Пол девіс: не тільки jack

Відео: Sean Spicer Press Conference (Melissa McCarthy) - SNL Однак досить про JACK. Інший внесок Пола Девіса у вільний…

Огляд музичного плеєра qmmp фото

Огляд музичного плеєра qmmp

Відео: Огляд MP3 плеєра з aliexpress QMMP - заснований на Qt плейер з елегантним сучасним видом і відмінно зробленим…

Cinelerra: цікаві можливості фото

Cinelerra: цікаві можливості

Відео: Приховані функції вашого iphone! Cinelerra підтримує розподілений рендеринг, який дозволяє прораховувати відео і…

Lumiera фото

Lumiera

Відео: Cosmic Break Lumiera Цю приречено-оптимістичну фразу «поживемо - побачимо» я застосовував і до…

Jack в linux: настройка фото

Jack в linux: настройка

Відео: Tutorial: JACK Audio Server: Basic Explanation, Install, and Setup Головне вікно qJackCtl Пора приступити до…

» » Звуковий сервер jack. Пишемо найпростіший клієнт: теорія