Anatoly Vorobey (avva) wrote,
Anatoly Vorobey
avva

Category:

skype-2, или возвращение скайпа

Ох, как меня заебал этот скайп за последние сутки, это просто слов нет.

В общем, не хочет он нормально работать в Линуксе. Очень плохое качество звука, шипит и прыгает ужасно. Сначала я грешил на качество связи, потом поковырялся немного и понял, что дело в том, как он работает со звуковой системой Линукса.


Техническая информация (незнакомые с Юниксом спокойно могут пропустить):
Линукс поддерживает два интерфейса к звуку: OSS (старый) и ALSA (новый). OSS — общеюниксовый интерфейс, самый популярный, в нём происходит общение программ с девайсами /dev/dsp и /dev/mixer (в типичной конфигурации). Программа открывает их, настраивает с помощью ioctl'ов, с их же помощью читает/пишет громкость в /dev/mixer, а сам звук читает/пишет в /dev/dsp (речь здесь везде идёт об интерфейсе нижнего уровня, если это вдруг неясно; т.е. в/из /dev/dsp идут никакие не mp3-файлы, а чистый звук, т.е. то, что записано в .wav-файлах, например). Новая звуковая система в Линуксе, ALSA, куда лучше и круче, но относительно мало программ умеют с ней общаться (в принципе её файлы сидят в /dev/snd, но есть хорошая стандартная библиотека, все идут через неё). Поэтому ALSA умеет эмулировать OSS, причём двумя способами. Один - через ядро, с помощью модулей snd-pcm-oss, snd-mixer-oss итп. Они автоматически переправляют обращения к /dev/dsp к себе и эмулируют интерфейс OSS внутри ядра с помощью внутренних вызовов ALSA. Это работает очень хорошо обычно; собственно, у меня так всегда бежит xmms и другие звукопроигрыватели (как я теперь понял). Есть ещё один способ, супер-извращённый. Программа запускается с помощью скрипта aoss, который добавляет в среду переменную LD_PRELOAD, заставляющую динамический сборщик Линукса подключить несколько специальных библиотек ALSA перед всеми остальными библиотеками данной программы. Эти специальные библиотеки переопределяют стандартные функции типа open(), ioctl() итп., и в случае, когда программа пытается работать именно с /dev/dsp и /dev/mixer, подменяют их своими ALSA-вскими вызовами. К /dev/dsp в результате реально никто не обращается. Это работает, но не всегда и не всегда хорошо.

Но и это ещё не всё. Как у KDE, так и у GNOME (которым я обычно пользуюсь) есть свои sound manager'ы: это демоны, которым другие программы посылают звуковые потоки, а они умеют микшировать (?) несколько потоков одновременно при необходимости, и результат посылают уже на звуковую карту. У KDE это artsd, у GNOME — esd (пакет esound). Оба они умеют на своём выходе говорить как с OSS, так и с ALSA (ясно, что если в системе бежит ALSA, то лучше их настроить так, чтобы они говорили прямо с ней). На входе же к ним умеет обращаться только небольшое количество программ: собственно те, что есть в пакетах KDE и GNOME в основном. Как же заставить все остальные звуковые программы (ту же xmms, например) посылать свой выход не на /dev/dsp, а этим менеджерам? С помощью того же трюка с LD_PRELOAD; для этого у artsd есть программа artsdsp, а у esd программа esddsp. Вместе с вышеупомянутой aoss это уже три разные программы (совершенно разные исходники), которые пытаются перехватить обращение к OSS и перенаправить каждая в свою сторону. Плюс ещё эмуляция OSS на уровне ядра.

Короче, Скайп. Он как-то очень извращённо работает с /dev/dsp, так, что эмуляция ядра с этим не справляется, и на выход попадает ломаный, шипящий звук с пропусками и дырками. Вход тоже корёжится. В этой эмуляции есть любопытная возможность менять некоторые параметры для одной конкретной программы, но всё, чего я добился — смены одного вида помех на другой, потом на третий, и так далее. Запустить чистый OSS (т.е. старый драйвер OSS для моей карты и вырубить ALSA) я не могу, т.к. он у меня не работает просто, нет звука; только ALSA работает с моей картой. aoss (ALSA-вский метод эмуляции в userspace) со Скайпом вообще не бежит, выдаёт Segmentation fault. Остальные два способа эмуляции в userspace (artsdsp, esddsp) бегут, но не приносят никаких результатов. Особенно с esddsp мистика: я покопался в нём как следует, разобрался в том, какие опции нужны, он теперь хорошо всё перехватывает, и открытие девайсов, и все ioctl'ы, и всю запись/чтение, и всё это посылает демону esd, который всё это принимает и вроде бы обрабатывает. Но почему-то skype при этом посылает одни нули, т.е. тишину, хотя сам при этом на экране рисует, что подключился, и явно получает звук (я тестировал с помощью подключения к юзеру echo123, он специально для этого существует). Я полночи протрахался, простите, с этой гадиной, пропустил её через десятки strace'ов, просмотрел логи системных функций. Когда он говорит с “настоящим” /dev/dsp (т.е. всё равно эмулированным ALSA, но через ядро), то посылает живой звук, только он выходит с помехами, а когда то же самое, но его вызовы перехватываются esddsp, то он теми же функциями write() посылает одни нули, а читать с микрофона даже не пытается. Значит, эмуляция esddsp в чём-то неубедительно ему врёт, но в чём именно, я так и не разобрался. Зато я узнал о программе skype такие прелести, что, например, сразу после запуска она создаёт одновременно 1000 сокетов, и сразу их все закрывает. Это типа такой high-tech способ максимальное кол-во дескрипторов проверить, догадался Штирлиц. Мастера!



В общем, я сдался пока что. На днях попробую ещё в эмуляторе (Wine), но не питаю особых надежд. Может, они выпустят новую версию для Линукса, получше. Пока что я запустил skype в Windows на соседнем компьютере (качество отличное, как и ожидалось, лучше телефона) и буду его там некоторое время держать — наушники с микрофоном под рукой, так что пересаживаться не нужно. Если кто-то хочет — звоните. Боюсь, правда, что если не найду способа запустить в Линуксе, то плюну через несколько дней.
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 26 comments