15 lipiec 2010

Używanie klienta Ventrilo na Linuksie pod Wine

Kategorie:  Wine  Linux  IM  Gentoo

Jak zmusić klienta Ventrilo do poprawnej pracy pod Linuksem używając wine

Użytkownicy Linuksa nie mogą przebierać w grupowych komunikatorach głosowych. Tak naprawdę jest tylko własnościowy TeamSpeak3, który działa całkiem przyzwoicie. Najpopularniejszy program Ventrilo wciąż nie jest dostępny dla Linuksa. Oficjalna strona Ventrilo informuje użytkowników, że klient dla Linuksa jest w trakcie tworzenia (ta informacja wisi na stronie od około 3 lat). Straciłem już nadzieję, że w końcu zakończą pracę na Linuksowym klientem. Niemniej znalazłem sposób aby używać Ventrilo w moim systemie wykorzystując Wine wolną implementację API Windows dla systemów *nix. Włożyłem sporo w pracy w testowanie i odniosłem sukces ale nie było to proste zadanie. Jeśli znasz lepszy sposób aby uruchomić program klienta Ventrilo w Linuksie proszę daj mi o tym znać.

Zanim wyjaśnię jak udało mi się wykorzystać Ventrilo pracujące obok innych uruchomionych programów na moim komputerze z Linuksem, zwięźle wyjaśnię jakie są wymagania aby udało się to osiągnąć. Moje rozwiązanie nie jest w 100% idealne jako, że wymaga ono przynajmniej dwóch oddzielnych urządzeń dźwiękowych (jednego wyjściowego i jednego wejściowego). Na szczęście posiadam dwie karty dźwiękowe w systemie a także dodatkowy mikrofon w mojej kamerce Internetowej Logitech QuickCam Pro. Moje rozwiązanie wymaga także aby twój system był skonfigurowany z czystym systemem dźwięku ALSA. Jako użytkownik Gentoo Linuksa nigdy nie wykorzystywałem w moim systemie pulsaudio, i nie mam pojęcie czy moje rozwiązanie zadziała z pulseaudio. Jeśli posiadasz wiedzę na ten temat proszę podziel się nią ze mną. Teraz postaram się wyjaśnić jak zmusiłem Ventrilo do przyzwoitej pracy na moim Linuksie. Wyjaśnię to krok po kroku, rozpoczynając od instalacji i przechodząc przez wszystkie problemy jakie napotkałem po drodze. Muszę z góry ostrzec, że jeśli nie jesteś użytkownikiem dystrybucji opartej na Gentoo Linuksie powtórzenie mojego rozwiązania może być dość bolesnym procesem, jako że będzie ono wymagało ręcznego patchowania i kompilacji kodu źródłowego. Dla użytkowników Gentoo Linuksa stworzyłem ebuildy, które zajmą się patchowaniem i kompilacją.

Instalacja Ventrilo na Linuksie

Przed zainstalowaniem Ventrilo na Linuksie musisz się upewnić, że nie zainstalujesz go w standardowym prefiksie Wine, który jest wykorzystywany przez inne aplikacje (na przykład gry, które chcesz uruchamiać razem z Ventrilo). Pierwszą rzeczą będzie instalacja Ventrilo w osobnym prefiksie Wine nazwanym wine-ventrilo. Możesz tego dokonać wykonując następującą komendę:

WINEPREFIX=~/.wine-ventrilo wine /ścieżka_do_pobranego_klienta/ventrilo-3.0.5-Windows-i386.exe

To polecenie utworzy nowy prefiks wine i uruchomi instalator programu. Zainstaluj program i upewnij się, że sciągniesz i umieścisz w nowym prefiksie wine wymagany kodek GSM audio. Plik z kodekiem jest nazwany msgsm32.acm i może zostać pobrany tutaj. Umieść go w katalogu ~/.wine-ventrilo/drive_c/windows/system. Następnie poddaj edycji plik ~/.wine-ventrilo/drive_c/windows/system.ini i dodaj do niego następującą linie w sekcji drivers32: MSACM.msgsm610=msgsm32.acm. Dodatkowo możesz zainstalować SpeechSDK51.exe jeśli chcesz wykorzystywać funkcję TTS wykonując następującą komendę:

WINEPREFIX=~/.wine-ventrilo wine /ścieżka_do_pobranego_pliku/SpeechSDK51.exe

Problem 1 Wybranie właściwego systemu dźwięku

Oficjalna strona WineHQ AppDB dotycząca programu Ventrilo zaleca, wybór systemu ALSA w trybie emulacji. Spędziłem całe godziny testując wszystkie możliwe ustawienia dźwięku ALSA i Jack i bez względu na to jakich opcji konfiguracyjnych nie wybrałem w winecfg, serwerze dźwięku Jack czy kliencie Ventrilo nie potrafiłem sprawić aby moje urządzenia wejściowe zaczęły działać. Sprawdzałem mikrofon podłączony do pierwszej i drugiej karty dźwiękowej i mój mikrofon wbudowany w kamerę internetową ale z ALSA i Jackiem po prostu zawsze urządzenia wejściowe były wyciszone, kompletny brak dźwięku (wyjściowe urządzenia działały bez zarzutu). Tak więc zarówno ALSA jak i Jack nie były właściwym dla mnie rozwiązaniem. Niemniej okazało się, że kiedy ustawiam system dźwięku OSS w winecfg moje urządzane wejściowe (wszystkie) działają bez zarzutu. Tak więc kolejna rzecz jaką należy zrobić to uruchomić winecfg. Upewnij się, że uruchomisz winecfg w twoim nowo utworzonym prefiksie wine wykonując następującą komendę:

WINEPREFIX=~/.wine-ventrilo winecfg

Następnie wybierz system dźwięku OSS w winecfg. W polu przyśpieszenia sprzętowego wybierz Pełne. Porównaj z poniższym zrzutem ekranu.

Winecfg

Wcześniejsza instalacja Ventrilo w osobnym prefiskie wine pozwoli nam uruchamiać go w środowisku odizolowanym od innych programów czy gier. W ten sposób dla innych apliakcaji możemy nadal wykorzystywać system dźwięku ALSA czy Jack.

Problem 2 Wyciszanie urządzenia PCM w Wine z wybranym systemem dźwięku OSS

Począwszy od wersji 1.1.6 w Wine występuje znany błąd powodujący wyciszanie urządzenia PCM zaraz po uruchomieniu w środowisku Wine programu używającego sytemu dźwięku OSS. Więcej informacji na temat tego błędu znajdziesz podążając za tym linkiem. Ten błąd jest niezauważalny dla większości użytkowników Wine, jako że używają oni dźwięku ALSA. Jak już napisałem nie mogłem zmusić urządzeń wejściowych do poprawnej pracy w Ventrilo z systemem dźwięku ALSA i dla tego błąd ten był dla mnie niezwykle denerwujący. Za każdym razem gdy uruchamiałem Ventrolo mój dźwięk stawał się totalnie wyciszony. Jeśli dokładnie przeczytasz informacje zamieszczone w raporcie błędu przekonasz się, że istnieje rozwiązanie tego problemu. To rozwiązanie wymaga usunięcia przez użytkownika dwóch linii kodu, które wywołują ten problem z kodu źródłowego Wine i rekompilacji Wine. Opierając się na tych informacjach stworzyłem patch do kodu źródłowego wine. Poniżej możesz zobaczyć ten patch:

Wyświetl źródło patcha prevent_oss_muting.patch
  1. --- wine/a/wine-1.1.6/dlls/dsound/primary.c 2008-10-10 16:57:22.000000000 +0200
  2. +++ wine/b/wine-1.1.6/dlls/dsound/primary.c 2009-05-18 19:37:01.000000000 +0200
  3. @@ -169,8 +169,6 @@
  4. return err;
  5. }
  6. }
  7. - if (device->hwbuf)
  8. - IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
  9.  
  10. DSOUND_RecalcPrimary(device);
  11. device->prebuf = ds_snd_queue_max;

Możesz uzyskać dostęp do pliku z patchem na moim serwerze svn podążając za tym linkiem.

Jako, że jestem użytkownikiem Gentoo Linuksa zaktualizowałem ebuild do wine aby ułatwić sobie nieco patchowanie kodu źródłowego wine. Używając tego ebuilda mogę zainstalować w systemie wine, pozbawione opisanego powyżej problemu. Zdecydowałem się na umieszczenie tego ebuilda w moim prywatnym overlayu wiec jeśli jesteś użytkownikiem dystrybucji opartej na Gentoo Linuksie możesz dodać mój overlay do swojego systemu i skompilować wine wykorzystując znajdujące się tam ebuildy. Zapobiegnie to wyciszaniu urządzeń PCM dla OSS. Na bieżąco aktualizuje ebuildy Wine z każdym nowym wydaniem i zamierzam robić to do czasu aż błąd ten zniknie lub znajdę lepszy sposób na uruchamianie Ventrilo. Więcej informacji jak dodać mój overlay i jak wykorzystać ebuildy z wine znajdziesz podążając za tym linkiem. Jeśli nie jesteś użytkownikiem dystrybucji opartej na Gentoo Linuksie możesz spatchować i skompilować wine ręcznie. Mniej traumatyczne może być jednakże pamiętanie o tym aby przy każdym uruchomieniu Ventrilo otworzyć mikser i przywrócić dźwięk w urządzeniu PCM.

Problem 3 Sprawienia aby zadziałała funkcja wciśnij aby mówić

Najprawdopodobniej będziesz chciał wykorzystać Ventrilo wraz innym programem na przykład grą, i chciałbyś móc komunikować się z przyjaciółmi podczas gry używając funkcji Ventrilo Wciśnij Aby Mówić. Ta funkcja nie będzie działała kiedy okno Ventrilo straci fokus. Jako że wine jest odrębnym środowiskiem od twojego pulpitu Linuksa, programy pracujące pod Wine są kompletnie nieświadome faktu, że wciskasz jakieś klawisze na klawiaturze czy używasz myszy, do czasu aż okno programu uzyska fokus. Istnieje prosty program, który pomoże ci poradzić sobie z tym problemem. Przekaże on kod klawisza A do okna programu Ventrilo ilekroć wciśniesz zdefiniowane klawisze na myszy czy klawiaturze. Możesz pobrać ten program tutaj i skompilować go ręcznie. Po kompilacji upewnij się, że po uruchomieniu programu Ventrilo ustawisz przycisk A jako przycisk wciśnij aby mówić. Porównaj z poniższym zrzutem ekranu.

Ventrilo PTT

Kolejna rzecz to powiązanie przycisku Wciśnij Aby Mówić z naszym małym programem pomocniczym. Aby zidentyfikować prawidłowy kod klawisz musimy uruchomić program przekazując jako pierwszy jego parametr nasze urządzenie wejściowe (klawiaturę albo mysz). Możesz tego dokonać wydając następującą komendę:

ventriloctrl /dev/input/by-id/usb-Logitech_USB_Receiver-event-mouse

Jak widzisz przekazuję identyfikator mojej myszy. Możesz łatwo zidentyfikować swoje urządzenie wchodząc do katalogu /dev/input/by-id/. Następnie wciśnij pożądany przycisk a program wydrukuje jego kod na ekranie. Zapamiętaj ten kod ponieważ wykorzystamy go w skrypcie uruchamiającym program Ventrilo. Tak więc kolejny krok to stworzenie skryptu uruchamiającego Ventrilo i program pomocniczy dla funkcji Wciśnij Aby Mówić. Mój skrypt ventrilo.sh wygląda następująco:

  1. #!/bin/bash
  2. env WINEPREFIX="~/.wine-ventrilo" wine "C:\Program Files\Ventrilo\Ventrilo.exe" &
  3. sleep 30
  4. /usr/bin/ventriloctrl /dev/input/by-id/usb-Logitech_USB_Receiver-event-mouse 274

Mój skrypt uruchamia Ventrilo we właściwym prefiksie WINEPREFIX następnie odczekuje chwilę i uruchamia program pomocniczy. Pamiętaj, że program pomocniczy nie będzie działał bez okna Ventrilo dostępnego w systemie. Silnie zalecam użycie węzła urządzenia posiadającego jasną nazwę dostępną w katalogu /dev/input/by-id jako, że czyste węzły /dev/input/event* mogą zmieniać swoje przyporządkowanie do urządzeń pomiędzy poszczególnymi uruchomieniami systemu. Na pewno będą się one zmieniać jeśli będziesz podłączał dodatkowe urządzenia wejściowe USB do systemu. Upewnij się, że uczynisz skrypt wykonywalnym wykonując następującą komendę:

chmod +x /scieżka_do_skryptu/ventrilo.sh

Teraz byłem w stanie wykorzystać Ventrilo wraz z funkcją Wciśnij aby Mówić podczas grania w gry. Wciąż jednak nie było to doskonałe rozwiązanie napotkałem jeszcze jeden problem.

Problem 4 Większość serwerów Ventrilo przenosiła mnie z aktywnego kanału do kanału AFK (z dala od klawiatury)

Ten problem powtarzał się ilekroć zapominałem o regularnym używaniu funkcji Wciśnij Aby Mówić. Dlaczego? Z tego samego powodu dla którego Wciśnij Aby Mówić nie działa bez programu pomocniczego. Program pomocniczy też nie jest doskonały. Mógłby on na przykład przekazywać do okna Ventrilo każde zdarzenie. Rozwiązałem ten problem tworząc patch do programu ventriloctrl. Poniżej możesz obejrzeć ten patch:

Wyświetl kod źródłowy patcha ventriloctrl
  1. --- a/ventriloctrl-0.5/ventriloctrl.c 2008-08-23 10:23:03.000000000 +0200
  2. +++ b/ventriloctrl-0.5/ventriloctrl.c 2009-06-20 01:40:40.000000000 +0200
  3. @@ -16,6 +16,7 @@
  4. /* Configuration */
  5. #define SIMULATEKEY XK_A // Simulate Key Press
  6. #define VENTRILO "Ventrilo" // Ventrilo Window Name
  7. +#define OTHERKEY XK_B //Key send to Ventrillo if other key is being pressed
  8.  
  9. /* Global Variables */
  10. Display *display;
  11. @@ -54,14 +55,14 @@
  12. {
  13. // Variables
  14. int i;
  15. -
  16. +
  17. // Get the "Window" Tree
  18. Window root;
  19. Window parent;
  20. Window *children = 0;
  21. unsigned int childrenCount = 0;
  22. XQueryTree(display, parentWindow, &root, &parent, &children, &childrenCount);
  23. -
  24. +
  25. // Crawl the "Window" Tree
  26. char *window_name = 0;
  27. Window *window = 0;
  28. @@ -74,7 +75,7 @@
  29. }
  30. XFree(window_name);
  31. }
  32. -
  33. +
  34. // Crawl the Child and Look For "windowName"
  35. window = find_window(display, children[i], windowName);
  36. if (window != 0) {
  37. @@ -82,10 +83,10 @@
  38. return window;
  39. }
  40. }
  41. -
  42. +
  43. // Free the Children! lol
  44. if (children != 0) XFree(children);
  45. -
  46. +
  47. // Return
  48. return 0;
  49. }
  50. @@ -94,42 +95,43 @@
  51. {
  52. // Usage
  53. printf("\n");
  54. -
  55. +
  56. // Initialize "Display"
  57. display = XOpenDisplay(0);
  58. if (display == NULL) {
  59. printf("Error: Could not open display!\n");
  60. return 1;
  61. }
  62. -
  63. +
  64. // Initialize Root "Window"
  65. window = XDefaultRootWindow(display);
  66. if (!window) {
  67. printf("Error: Could not grab root window!\n");
  68. return 2;
  69. }
  70. -
  71. +
  72. // Initialize Ventrilo "Window"
  73. windowVentrilo = find_window(display, window, VENTRILO);
  74. if (!windowVentrilo) {
  75. printf("Error: Could not find Ventrilo window!\n");
  76. return 3;
  77. }
  78. -
  79. +
  80. // Convert Key String to Number
  81. unsigned int key = atoi(argv[2]);
  82. unsigned int simulatekey = XKeysymToKeycode(display, SIMULATEKEY);
  83. -
  84. + unsigned int otherkey = XKeysymToKeycode(display, OTHERKEY);
  85. +
  86. // Open the Input
  87. int device = open(argv[1], O_RDONLY);
  88. -
  89. +
  90. // Loop
  91. struct input_event ev;
  92. XKeyEvent event;
  93. while (ventrilo_still_running()) {
  94. // Read from the Input
  95. read(device, &ev, sizeof(struct input_event));
  96. -
  97. +
  98. // Check Input
  99. if (ev.type == 1 && ev.code == key) {
  100. // Simulate Key Press/Release
  101. @@ -141,8 +143,18 @@
  102. }
  103. XFlush(display);
  104. }
  105. + else if (ev.type == 1 && ev.code != key) {
  106. + // Send other key (this should prevent putting the user on afk status)
  107. + event = create_key_event(display, *windowVentrilo, window, ev.value, otherkey, 0);
  108. + if (ev.value == 1) {
  109. + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *) &event);
  110. + } else {
  111. + XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *) &event);
  112. + }
  113. + XFlush(display);
  114. + }
  115. }
  116. -
  117. +
  118. // Return
  119. return 0;
  120. }
  121. @@ -156,20 +168,20 @@
  122. printf("then execute the command listed.\n");
  123. printf("Press Ctrl+C when finished.\n");
  124. printf("\n");
  125. -
  126. +
  127. // Open the Input
  128. int device = open(argv[1], O_RDONLY);
  129. -
  130. +
  131. // Loop
  132. struct input_event ev;
  133. while (1) {
  134. // Read from the Input
  135. read(device, &ev, sizeof(struct input_event));
  136. -
  137. +
  138. // Print the Command
  139. if (ev.type == 1 && ev.value == 1) printf("%s %s %i\n", argv[0], argv[1], ev.code);
  140. }
  141. -
  142. +
  143. // Return
  144. return 0;
  145. }
  146. @@ -180,7 +192,7 @@
  147. // Programs
  148. if(argc == 2) return findkey(argc, argv); // Find Key
  149. if(argc == 3) return ventriloctl(argc, argv); // Ventrilo Ctrl
  150. -
  151. +
  152. // Usage
  153. printf("\n");
  154. printf("Usage: %s <device> [key]\n", argv[0]);
  155. @@ -188,7 +200,7 @@
  156. printf("Running this program without 'key' specified\n");
  157. printf("will run the 'FindKey' sub-program.\n");
  158. printf("\n");
  159. -
  160. +
  161. // Return
  162. return 0;
  163. }

Możesz uzyskać dostęp do pliku z patchem na moim serwerze svn podążając za tym linkiem.

Ten patch robi prostą rzecz. Za każdym razem gdy urządzenie przekazane jako parametr generuje jakieś zdarzenie program przekazuje to zdarzenie do okna Ventrilo jako wciśniętą literę B. Patch nie zmienia domyślnego zachowania programu więc przycisk Wciśnij Aby Mówić nadal będzie działaj przekazując kod klawisza A. W ten sposób tak długo jak korzystam z mojej myszy ventriloctrl przekazuje kod klawisza B do okna Ventrilo i serwer nie zakłada już, że oddaliłem się od klawiatury.

Stworzyłem ebuild Gentoo Linuksa, który instaluje program ventrilovtrl z zamieszczonym powyżej patchem w moim systemie. Mój ebuild jest dostępny w moim prywatnym overlayu więc jeśli jesteś użytkownikiem dystrybucji opartej na Gentoo Linuksie możesz dodać mój overlay do twojego systemu i skompilować ventriloctrl używając mojego ebuilda. Jeśli nie jesteś użytkownikiem Gentoo Linuksa możesz spatchować i skompilować program ręcznie.

Konfiguracja i użytkowanie Ventrilo na Linuksie

Aby mieć pewność, że wszystko będzie pracowało we właściwy sposób zawsze uruchamiaj Ventrilo używając skryptu zamieszczonego powyżej. Upewnij się także, że uruchomisz Ventrilo przed jakąkolwiek inną aplikacją pracującą pod Wine. System dźwięku OSS (nawet ten emulowany w ALSA) wymaga dostępu na wyłączność do urządzenia wejściowego dźwięku. Kiedy jakiś inny program będzie go używał może ono nie działać. Nie mam żadnych problemów gdyż używam mojej głównej karty Sound Blaster Audigy 4 jako urządzenia wyjściowego dla Ventrilo z OSS i dla innych aplikacji Wine pracujących w ALSA. Jako urządzenia wejściowego używam mikrofonu mojej internetowej kamery USB i to rozwiązanie działa bez zarzutu na moim komputerze. Testowałem je wiele razy i nie miałem najmniejszych problemów z komunikowaniem się z ludźmi.

Kiedy będziesz chciał wybrać urządzenia dźwiękowe w Ventrlo możesz nie znaleźć ich nazw na liście ale nie martw się powinieneś móc je wybrać jako puste wpisy na liście. Jako że pamiętam, że mój mikrofon w kamerze to trzecie urządzenie dźwiękowe w systemie wybrałem ostatnią pustą pozycję listy. Pamiętaj, że pierwsza pozycja to urządzenie domyślne. Poniżej możesz zobaczyć dowód, że to działa na moim komputerze. Zwróć uwagę na część monitorującą okna. Wartości dodatnie świadczą o tym, że wejście dźwięku działa

Ventrilo Input

Źródła:




Komentarze

Jeśli znalazłeś jakieś błędy w powyższej informacji lub po prostu chcesz wypowiedzieć swoje zdanie na jej temat, będę wdzięczny za pozostawienie komentarza.
Wszystkie komentarze będą pokazywać się na stronie po tym jak zostaną zatwierdzone. Przepraszam za to ale chcę mieć pewność, że moja strona będzie wolna od obraźliwych lub wulgarnych treści. Nie mam nic przeciwko krytyce ale zrób to właściwie dobierając słowa.

Pozostaw komentarz