====== SoundSwap ====== ===== Das Problem ===== Wer mehrere Soundkarten in seinem Windows-Rechner installiert hat kennt das Problem: Manche Programme benutzen einfach immer die Standard-Soundkarte und es gibt keine Auswahl. In meinem Fall war es besonders nervig: Im System eine 7.1-Karte mit angeschlossener Surround-Anlage sowie eine "High-End" Stereo-Karte die intern auf den Line-In der 7.1-Karte gebrückt ist sowie mit dem zweiten Ausgang auf die HiFi-Anlage geht. Mit der Surround-Karte als Standardkarte funktionieren zwar Spiele mit Surround-Sound aber z.B. der Flash-Player dudelt ausschließlich auf den vorderen zwei Satelliten - ohne Woofer sehr fiepsig... also Murks. Mit der Stereo-Karte als Standardkarte landet das Line-In-Signal der 7.1-Karte bei allen Lautsprechern - dafür sind Spiele nur Stereo... also auch Murks. Verwender von Usb-Audio-Geräten kennen das Problem auch: steckt man eine Logitech-Webcam mit Mikrofon ein stellt sich die Aufnahme automatisch auf die Cam und die Widergabe automatisch auf das erste Ausgabegerät - Murks! Usb-Soundkarten produzieren ähnlich ungewolltes Verhalten... ===== Wie funktioniert das eigentlich...? ===== Programme die die Standard-Soundkarte verwenden benutzen den Sound Mapper (Device-ID -1). Dieser verweist dann auf die eigentliche Karte (ID 0). Jede weitere Karte erhält ID 1, ID 2, ... Öffnet ein Programm die Standard-Karte wird die Ausgabe nicht umgebogen oder abgebrochen wenn die Standardkarte geändert wird - es reicht also die gewünschte Standardkarte eingestellt zu haben solange das Programm die Audioausgabe (oder Aufnahme) initialisiert. Die Einstellungen hierfür finden sich in der Registry unter: //HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper\Record// und //HKEY_CURRENT_USER\Software\Microsoft\Multimedia\Sound Mapper\Playback// und enthalten den Device-Namen im Klartext: {{ :projekte:soundswap_registry.jpg|Schlüssel im Registry-Editor }} Also sind folgende Schritte nötig um ein Programm das selber keine Einstellungen zur Soundkartenwahl bietet "umzubiegen": - Einstellungen merken - gewünschte Soundkarte(n) setzen - Programm starten, warten bis das Audio-Device zur Wiedergabe/Aufnahme geöffnet ist - Einstellungen wiederherstellen Jawoll - Pfusch vom feinsten =) Eine sauberere Lösung wäre das Hooken des Öffnens des Audio-Device und somit eine Zentrale Liste Programm <-> Soundkarte... Nuja was solls... Für die Registry-Variante gibt es bereits Lösungen: * [[http://www.quicksoundswitch.toflo.de/]] * [[http://markuskirschmann.de/wordpress/?tag=sound-mapper]] Allerdings stellten mich beide nicht so recht zufrieden - quicksoundswitch ist mir nicht quick genug - es gibt einerseits zu viele Funktionen, andererseits bietet es nicht die Rücksetz-Funktion die ich so gerne hätte... die Lösung für VirtualPC ist einerseits schön simpel, andererseits auch nicht so wirklich überzeugend... ===== Die Lösung: SoundSwap ===== Wenn man nicht alles selber macht... Hilfescreen des Tools: SoundSwap 1.0 - Runs a proggie on the specifed soundcard(s) Usage: soundswap.exe playback-id record-id [exec [timeout]] Examples: soundswap.exe 1 -1 "D:\Spiele\Mirror's Edge\Binaries\MirrorsEdge.exe" 10 soundswap.exe 1 1 "D:\Spiele\Steam\Steam.exe -applaunch 380" -30 soundswap.exe 1 -1 sndrec32 1 Parameters: playback-id: Device-ID from Playback-Devices-List, -1 = dont change record-id: Device-ID from Record-Devices-List, -1 = dont change exec: command / program to run with changed audio-device, optional timeout: seconds until recovery of old settings, 0 = wait infinite, negative = force timeout, optional Recording Devices ================= 0: Realtek HD Audio Input 1: kX Wave CT4620 10k1 [6000] 0/1 Default: kX Wave CT4620 10k1 [8000] 0/1 Playback Devices ================ 0: kX Wave CT4620 10k1 [6000] 0/1 1: Realtek HD Audio output Default: kX Wave CT4620 10k1 [6000] 0/1 So ist es also möglich ein Programm auf Soundkarte X zu starten, via Verknüpfung auch schön in klickibunti. Das wechseln der aktiven Soundausgabe lässt sich auch bequem via Verknüpfung, z.B. im QuickLaunch realisieren. ==== Codeschnipsel: ==== Ermitteln der Devices, selbiges geht natürlich auch für //"IN"// statt //"OUT"//: int outnumdevs = waveOutGetNumDevs(); WAVEOUTCAPS waveoutcap; for(int i=0;i Setzen eines REG_SZ: void setRegistryKey(std::string path, std::string key,std::string value) { HKEY hKey=0; DWORD dwType=REG_SZ; DWORD dwSize=value.length(); RegOpenKeyEx(HKEY_CURRENT_USER, path.c_str(), 0L, KEY_ALL_ACCESS, &hKey); RegSetValueEx(hKey,key.c_str(), NULL, (DWORD)dwType, (LPBYTE)value.c_str(),value.length()+1); RegCloseKey(hKey); } Programm starten und auf seine Beendigung / Timeout warten: SHELLEXECUTEINFO ShExecInfo; ZeroMemory (&ShExecInfo, sizeof (SHELLEXECUTEINFO)); ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = (ULONG)SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = NULL; ShExecInfo.lpFile = "notepad.exe"; ShExecInfo.lpParameters = NULL; ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_SHOW; ShExecInfo.hInstApp = NULL; ShellExecuteEx(&ShExecInfo); WaitForSingleObject(ShExecInfo.hProcess,1000); // warten bis Programmende, oder 1 Sekunde, alternativ INFINITE ==== Kompatibilitätsfoo ==== Hier einige Programme mit denen Soundswap erfolgreich getestet wurde: ^ Programm ^ Funktion ^ Öffnen des Device ^ Timeout-Wert ^ | Firefox 3.5 + Flash-Player | Eingeschränkt | beim ersten Aufruf einer Seite mit Flash, bleibt dann offen, allerdings pro Tab | am besten Manuell / -20 | | Audiorecorder (sndrec32.exe) | ja | beim Programmstart | 1 | | VLC 1.01 | ja | beim Programmstart (oder umstellen in den Optionen) | 3 | | Mirrors Edge | ja | einige Sekunden nach Programmstart | 10 | | Counter-Strike Source | ja | einige Sekunden nach Programmstart | -15 | | Bioshock | ja | einige Sekunden nach Programmstart | -5 | * Ein positiver Timeout-Wert bedeutet: Warte mit dem Zurückstellen bis die Zeit um ist __oder__ das gestartete Programm früher endet. * Ein negativer Timeout-Wert bedeutet: Warte mit dem Zurückstellen bis die Zeit rum ist, __auch wenn__ das gestartete Programm früher endet. * Ein Timeout mit dem Wert 0 bedeutet: Warte mit dem Zurückstellen bis zur Apokalypse __oder__ bis das gestartete Programm endet. ==== Download ==== === Version 1.0 === {{:projekte:soundswap_v1_0.zip|SoundSwap V1.0}} - Quellcode, exe & Icon. Getestet auf Windows XP, sollte auch mit früheren Windows-Versionen funktionieren. :!: **Achtung:** Version 1.0 wird von diversen Virenscannern (z.B. AntiVir) als heuristischer Treffer gefunden - das liegt natürlich daran dass SoundSwap an der Registry an den Soundeinstellungen rumpfuscht, andere Programme startet, ... eben hautpsächlich Dinge macht die auch ein "böses" Programm ausmachen... natürlich ist SoundSwap nicht bösartig, wer will darf sich gerne den beigelegten Quellcode durchlesen und selber kompilieren oder die exe bei virustotal.com prüfen lassen... trotzdem: Verwendung auf eigene Verantwortung etc... === Aktuell: Version 1.11 === {{:projekte:soundswap_v_1_11.zip|SoundSwap V1.11}} - Quellcode, exe & Icon. Neuerungen: * Unterstützt jetzt auch Programme die nach dem Start einen anderen Prozess starten und dann den Launcher-Prozess beenden (z.B. **Steam-Spiele**). * Unterstützt jetzt auch die Weitergabe von Parametern an das gestartete Programm (alles nach ".exe " wird als parameter interpretiert, nicht schön aber funktioniert ^^) * Sieht nicht mehr so sehr wie ein Virus aus - nur noch McAfee erkennt das Tool als "Heuristic.BehavesLike.Win32.Trojan.I" ===== Weiterer interessanter Kram zum Thema ===== * [[http://kxproject.lugosoft.com|kX Project]] "Our mission is to allow end-users unfettered access to all hardware features of the kX-compatible* soundcards"