четвъртък, 20 септември 2007 г.

Стерео към 5+1 звук и... Linux

Много се писа напоследък, как да накараме звука на системата да тече през всичките 4,6 или повече канали на аудиокартата (кой с каквото се е сдобил). Вече сме 2007 година и много хора имат на разположение съвременни висококачествени възпроизвеждащи устройства тъй, че "обикновеното" стерео вече не задоволява капризните вкусове. Аз имам Creative Inspire P5800, примерно...
В началото предполагам, че разполагате все пак и със съответната многоканална аудиокарта - повечето правени през последните 2-4 години дъна са с вградени такива. От опита който имам, поне с моята, обаче те не винаги се разпознават напълно коректно, поради специфични хардуерни особености... друга тема, която не ми се захваща.
Отбелязвам, че няма да се спра тук на просвирване на DVD, или аудио файлове кодирани направо с DTS и AC3. Материята е много сходна, но все пак е друга... Т.е. - тук ще коментирам само просвирването на mp3, ogg, m4a, wav, flac и всички видове avi файлове, кодирани в "обикновено 2-канално стерео".
Отбелязвам, че това което ще се получи ще е значително по-скромно от възможностите, които ви предоставя оригиналния драйвер на аудиокартата, написан за Win... там с различните имитации на звук - на открито, в пещера, в зала и пр (той не ви е предоставен безплатно, нали?). Но все пак ще си имате звук през всичките си колонки и то не лош... Както ви харесва... Тук само ще вметна, че подобни ефекти (за тези които не могат без тях) много сполучливо се получават в Audacious, използувайки вградените му плъгини.
Всички давани примери са за конфигурацията на моята "щайга", а тя с течение на времето придоби доста екзотичен вид - вградена карта на дъното с чип C-Media, Creative sound blaster- външна USB и аудио хардуера (микрофончето...) на уебкамерата ми Labtec :
# cat /proc/asound/cards
0 [SI7012 ]: ICH - SiS SI7012
SiS SI7012 with CMI9761 at 0xdc00, irq 201
1 [External ]: USB-Audio - SB Live! 24-bit External
Creative Technology SB Live! 24-bit External at usb-0000:00:03.1-1,
full speed
2 [U0x46d0x8a2 ]: USB-Audio - USB Device 0x46d:0x8a2
USB Device 0x46d:0x8a2 at usb-0000:00:03.0-2, full speed

Поради причина, спомената по-горе, счетох за най-добре за мен да не използувам изобщо вградената на дъното карта. В крайна сметка конфигурацията на аудио устройствата останаха тези :

$ cat /proc/asound/cards
0 [External ]: USB-Audio - SB Live! 24-bit External
Creative Technology SB Live! 24-bit External at usb-0000:00:03.1-1, full speed
1 [U0x46d0x8a2 ]: USB-Audio - USB Device 0x46d:0x8a2
USB Device 0x46d:0x8a2 at usb-0000:00:03.0-2, full speed

Също така, предполагам че поддръжката на звука в ядрото ви се основава на ALSA - възможно най-последна версия, че при стартиране в ядрото ви са вмъкнати всички необходими модули (при инсталирането това би трябвало да е станало автоматично - не съм попадал на дистрибуция, която да не го прави, а тези които сериозно се занимават с компилиране на собствено ядро, обикновено са наясно с тънкостите).

При всеки може да е различно - пак както съм отбелязвал преди : комбинациите на хардуерни компоненти в PC са много.
Проверявате дали са ви там устройствата :

$cat /proc/asound/devices
0: [ 0] : control
1: : sequencer
4: [ 0- 0]: hardware dependent
16: [ 0- 0]: digital audio playback
24: [ 0- 0]: digital audio capture

32: [ 1] : control
33: : timer
56: [ 1- 0]: digital audio capture

Общо взето, проблемите със звука в Linux опират до няколко неща: приоритета на процесите свързани със звука и конфигурирането на системата така, че повече приложения да могат да използуват звуковата карта наведнъж. Начините са няколко. Това с приоритета вече не е толкова актуално, въпреки че доста дистрибуции предлагат специално компилирани ядра за работа със звук и мултимедия в реално време - но това е за професионални музиканти, в общия случай ние не сме...
По принцип "големите" десктоп среди използуват sound server (в KDE arts, в GNOME - esd), чиято цел е да координира работата на отделните приложения с аудиокартата така, че да няма конфликти. Но за жалост тези елементи от средите останаха най-несъвършени... неприятно, но факт. Все пак без въпросните сървъри засега не се минава. Най-малкото няма да имате системни звуци и някои приложения няма да можете да използувате докато слушате музика, примерно... Единственото пожелание е те да са конфигурирани(компилирани) с поддръжка на ALSA. Нямам опит с arts, но не вярвам проблемите с него да са по-различни от тези с ESD. От друга страна е ALSA - подразбиращата се sound-система на ядрото с непрекъснато усъвършенствуващите и се възможности. В конкретния случай нас ни касае dmix - това е дигиталния миксер на alsa... ето ви още една възможност за координация на аудиопотоците и приложенията (пример за многовариантността в света на Linux, може би в не най-добрата си светлина, или по-простичко казано - липсата на стандартизация). Става каша - пак пример: до неотдавна Skype използуваше OSS, което ви принуждаваше да останете на ниво OSS емулация в ALSA, с всичките произтичащи от това проблеми - пускате си плейър, ама в това време не можете да приказвате и обратното.
Но... да не се отклоняваме от темата: цялата дандания опира в крайна сметка до едно миниатюрно скрито файлче намиращо се в домашната ви директория на име .asoundrc.
Естествено, ако желаете тези настройки може да ги сложите на глобално ниво в основния кофигурационен файл на alsa - /etc/alsa.conf, въпрос на избор...
Синтаксиса на файла /home/xxx/.asoundrc е следният:

pcm.<име на устройство> {
type hw # или друг плъгин тип
card 0 # или 1
}

ctl.<име на устройство> {
type hw
card 0 # или 1
}


Паралелно с излагането на материала ще се опитвам да обяснявам някои термини и специфичен синтаксис. Ще вметна само, че документацията на ALSA е доста добра, но и доста лаконично изложена. Костваше ми доста време и опити да "хвана" логиката, тъй като в мрежата е пълно с примери, които ви сервират решение във вид на готов текст и никой не обяснява защо това се прови точно така, а не иначе... И все пак всички тези примери, поне лично на мен помогнаха много, най-малкото с насока, къде да дълбая.
PCM - (Pulse Code Modulaton) устройство - в случая общо казано - устройство за цифрова обработка на звук, като между големите скоби определяме какъв плъгин ще се използува - hw в случая и за точно кое хардуерно устройство се отнася - card 0 (виж по-горе списъка на картите от /proc ); hw - alsa плъгин, който комуникира директно с модула на ядрото, без каквото и да е преобразуване на данните, тук може и да е друго, както ще видитe по-долу.
Естествено, това е само грубата конструкция, за постигане на по-добри резултати ще трябва да понапишем още неща. Какво всъщност правим ? С помощтта на този конфигурационен файл дефинираме едно или няколко виртуални устройства на които можем да назначим възможности, "надграждащи" тези, които ви осигурява стандартния модул. Започваме...
Първо - дефинираме си наличните устройства като PCM :

pcm.usb-audio {
type hw
card 0 # това е първата ми карта

}

pcm.usb-webcam {
type hw
card 1 # това - втората (микрофончето на webcam)
}


Както казах, Алса има вградено приложение за софтуерно миксиране на звуци - dmix. Ще дефинираме с помощта на него и няколко други плъгина 6-канално цифрово устройство :

# 6 channel dmix:
pcm.dmix6 {
type dmix
ipc_key 1024 # това е уникален идентификатор
ipc_key_add_uid false # тук указваме, че повече от 1 потребител може да го ползува
ipc_perm 0660 # правата на въпросните потребители
slave {
pcm "hw:0,0" # виж по-горе
rate 96000
channels 6
period_time 0
period_size 1024 # може и 2048 опитвате...
buffer_time 0
buffer_size 5120 # дефинирате размера на буфера, при проблеми го коментирате, или намаляте
#стойността
}
}


Тук чрез dmix -> slave плъгин типовете дефинираме повечето параметри, които искаме да има нашето цифрово устройство. Искам да обърна внимание на slave плъгина, защото точно с негова помощ се "приписват" качества от едно на друго устройство - в случая dmix6, което има тези и тези параметри се привързва (робува, ако искате) към устройството указано като slave... Именно чрез него става навръзването на всички тези различни виртуални устройства, които описваме - това е важно да се разбере, като механизъм.
Сега ще укажем как да се разпределя звука към различните канали, за целта използуваме плъгина Route & Volume.

# upmixing:
pcm.ch51dup {
type route
slave.pcm "dmix6"
slave.channels 6
ttable.0.0 1 # канал 0 - front-left
ttable.1.1 1 # канал 1 - front-right
ttable.0.2 1 # канал 2 - rear-left на него подаваме сигнала от 0 със стойнос 1 (тук може да е от #0.0 до 1
ttable.1.3 1 # канал 3 - rear-right - пак така
ttable.0.4 0.5 # канал 4 - center като тук разпределяме поравно сигнала от предните канали
ttable.1.4 0.5
ttable.0.5 0.5 # канал 5 - subbufer - както при center
ttable.1.5 0.5
}


Тук, най-грубо казано, чрез инструкцията ttable на route сигнала от предните два канала копираме върху задните едноименни, а за центъра и суббуфера миксираме звука от двата. Първите две цифрички след ttable указват даващия и приемащия канал, третата е число от 0 до 1, указващо процентното съотношение но миксирането (в случай на миксиране на сигнал от повече от един канал към трети).
Същия резултат може да се постигне и чрез определяне на режима на plug - плъгин за автоматично преобразуване :

# upmixing:
pcm.ch51dup {

type plug
slave.pcm "dmix6"
route_policy duplicate # route policy for automatic ttable generation
# STR can be 'default', 'average', 'copy', 'duplicate'
# average: result is average of input channels
# copy: only first channels are copied to destination
# duplicate: duplicate first set of channels
# default: copy policy, except for mono capture - sum

}


Лично аз предпочитам първия вариант, като по-детайлен и ясен.
Сега бих искал да дефинирам устройството така, че да работи в дуплексен режим, т.е. да може да записва и просвирва едновременно. Използуваме плъгина asym :

pcm.duplex {
type asym
playback.pcm "ch51dup" # първо за просвирване
capture.pcm "usb-webcam" # записване - тук който микрофон ще ползувате
}


Най-накрая трябва да дефинираме подразбиращото се устройство, след всичките тези дефиниции :

# change default device:
pcm.!default {
type plug
slave.pcm "duplex"
}


И ето как изглежда целия файл :

pcm.usb-audio {
type hw
card 0 # това е първата ми карта
}

pcm.usb-webcam {
type hw
card 1 # това - втората (микрофончето на webcam)
}

# 6 channel dmix:
pcm.dmix6 {
type dmix
ipc_key 1024 # това е уникален идентификатор
ipc_key_add_uid false # тук указваме, че повече от 1 потребител може да го ползува
ipc_perm 0660 # правата на въпросните потребители
slave {
pcm "hw:0,0" # виж по-горе
rate 96000
channels 6
period_time 0
period_size 1024 # може и 2048 опитвате...
buffer_time 0
buffer_size 5120 # дефинирате размера на буфера, при проблеми го коментирате, или намаляте
#стойността
}
}

# upmixing:
pcm.ch51dup {
type route
slave.pcm "dmix6"
slave.channels 6
ttable.0.0 1 # канал 0 - front-left
ttable.1.1 1 # канал 1 - front-right
ttable.0.2 1 # канал 2 - rear-left на него подаваме сигнала от 0 със стойнос 1 (тук може да е от #0.0 до 1
ttable.1.3 1 # канал 3 - rear-right - пак така
ttable.0.4 0.5 # канал 4 - center като тук разпределяме поравно сигнала отпредните канали
ttable.1.4 0.5
ttable.0.5 0.5 # канал 5 - subbufer - както при center
ttable.1.5 0.5
}

pcm.duplex {
type asym
playback.pcm "ch51dup" # първо за просвирване
capture.pcm "usb-webcam" # записване - тук който микрофон ще ползувате
}

# change default device:
pcm.!default {
type plug
slave.pcm "duplex"
}


С риск да елементаризирам много, ще се опитам да "преразкажа" действието което имаме : имаме две аудиокарти, правим си дигитален миксер с 6 канала, който връзваме за първата аудиокарта (dmix6 -> slave hw 0:0), после 5+1 дупликатор, който ще разпределя звука от 2-та стерео канала към 6-те, както сме казали (ch51dup -> slave dmix6), ще прокарваме звука "нагоре и надолу" паралелно, т.е. ще можем да просвирваме и да записваме едновременно (playback... capture...) чрез устройството duplex и това ще е подразбиращото се (default!).

Само искам да отбележа накрая, че това не е единствения начин да постигнете същия резултат. Ровейки се в документацията на ALSA човек открива неподозирани възможности ! Всичко това което набелязах в този материал е само някаква отправна точка за тези, които биха искали още. Желая успех !

Няма коментари:

Публикуване на коментар