Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static void ALSA_MixerInit(void)
- {
- int x, mixnum = 0;
- snd_ctl_card_info_t *info;
- info = HeapAlloc( GetProcessHeap(), 0, snd_ctl_card_info_sizeof());
- for (x = 0; x < MAX_MIXERS; ++x)
- {
- int card, err, capcontrols = 0;
- char cardind[6], cardname[10];
- snd_ctl_t *ctl;
- snd_mixer_elem_t *elem, *mastelem = NULL, *headelem = NULL, *captelem = NULL, *pcmelem = NULL, *micelem = NULL;
- memset(info, 0, snd_ctl_card_info_sizeof());
- memset(&mixdev[mixnum], 0, sizeof(*mixdev));
- snprintf(cardind, sizeof(cardind), "%d", x);
- card = snd_card_get_index(cardind);
- if (card < 0)
- continue;
- snprintf(cardname, sizeof(cardname), "hw:%d", card);
- err = snd_ctl_open(&ctl, cardname, 0);
- if (err < 0)
- {
- WARN("Cannot open card: %s\n", snd_strerror(err));
- continue;
- }
- err = snd_ctl_card_info(ctl, info);
- if (err < 0)
- {
- WARN("Cannot get card info: %s\n", snd_strerror(err));
- snd_ctl_close(ctl);
- continue;
- }
- MultiByteToWideChar(CP_UNIXCP, 0, snd_ctl_card_info_get_name(info), -1, mixdev[mixnum].mixername, sizeof(mixdev[mixnum].mixername)/sizeof(WCHAR));
- snd_ctl_close(ctl);
- err = snd_mixer_open(&mixdev[mixnum].mix, 0);
- if (err < 0)
- {
- WARN("Error occurred opening mixer: %s\n", snd_strerror(err));
- continue;
- }
- FIXME("Card: %s\n", cardname);
- err = snd_mixer_attach(mixdev[mixnum].mix, cardname);
- if (err < 0)
- goto eclose;
- err = snd_mixer_selem_register(mixdev[mixnum].mix, NULL, NULL);
- if (err < 0)
- goto eclose;
- err = snd_mixer_load(mixdev[mixnum].mix);
- if (err < 0)
- goto eclose;
- /* First, lets see what's available..
- * If there are multiple Master or Captures, all except 1 will be added as slaves
- */
- for (elem = snd_mixer_first_elem(mixdev[mixnum].mix); elem; elem = snd_mixer_elem_next(elem))
- //crashes on this fixme if enabled
- //if not, there is no crash, but no sliders work for sndvol32.exe
- //FIXME("elem name: %s on card %s\n", snd_mixer_selem_get_name(elem), cardname);
- if (!strcasecmp(snd_mixer_selem_get_name(elem), "Master") && !mastelem)
- mastelem = elem;
- else if ((!strcasecmp(snd_mixer_selem_get_name(elem), "Capture") ||
- !strcasecmp(snd_mixer_selem_get_name(elem), "Mic")) && !captelem)
- captelem = elem;
- else if (!blacklisted(elem))
- {
- DWORD comp = getcomponenttype(snd_mixer_selem_get_name(elem));
- DWORD skip = 0;
- /* Work around buggy drivers: Make this a capture control if the name is recognised as a microphone */
- if (snd_mixer_selem_has_capture_volume(elem))
- ++capcontrols;
- else if (comp == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
- {
- ++capcontrols;
- skip = 1;
- }
- if (!skip && snd_mixer_selem_has_playback_volume(elem))
- {
- if (!strcasecmp(snd_mixer_selem_get_name(elem), "Headphone") && !headelem)
- headelem = elem;
- else if (!strcasecmp(snd_mixer_selem_get_name(elem), "PCM") && !pcmelem)
- pcmelem = elem;
- else
- ++(mixdev[mixnum].chans);
- }
- }
- /* Add master channel, uncounted channels and an extra for capture */
- mixdev[mixnum].chans += !!mastelem + !!headelem + !!pcmelem + 1;
- /* If there is only 'Capture' and 'Master', this device is not worth it */
- if (mixdev[mixnum].chans == 2)
- {
- WARN("No channels found, skipping device!\n");
- goto close;
- }
- /* Master element can't have a capture control in this code, so
- * if Headphone or PCM is promoted to master, unset its capture control */
- if (headelem && !mastelem)
- {
- /* Using 'Headphone' as master device */
- mastelem = headelem;
- capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
- }
- else if (pcmelem && !mastelem)
- {
- /* Use 'PCM' as master device */
- mastelem = pcmelem;
- capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
- }
- else if (!mastelem && !captelem)
- {
- /* If there is nothing sensible that can act as 'Master' control, something is wrong */
- FIXME("No master control found on %s, disabling mixer\n", snd_ctl_card_info_get_name(info));
- goto close;
- }
- if (!captelem || !capcontrols)
- {
- /* Can't enable capture, so disabling it
- * Note: capture control will still exist because
- * dwLineID 0 and 1 are reserved for Master and Capture
- */
- WARN("No use enabling capture part of mixer, capture control found: %s, amount of capture controls: %d\n",
- (!captelem ? "no" : "yes"), capcontrols);
- capcontrols = 0;
- mixdev[mixnum].dests = 1;
- }
- else
- {
- mixdev[mixnum].chans += capcontrols;
- mixdev[mixnum].dests = 2;
- }
- mixdev[mixnum].lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(line) * mixdev[mixnum].chans);
- mixdev[mixnum].controls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(control) * CONTROLSPERLINE*mixdev[mixnum].chans);
- err = -ENOMEM;
- if (!mixdev[mixnum].lines || !mixdev[mixnum].controls)
- goto close;
- filllines(&mixdev[mixnum], mastelem, captelem, capcontrols);
- fillcontrols(&mixdev[mixnum]);
- TRACE("%s: Amount of controls: %i/%i, name: %s\n", cardname, mixdev[mixnum].dests, mixdev[mixnum].chans, debugstr_w(mixdev[mixnum].mixername));
- mixnum++;
- continue;
- eclose:
- WARN("Error occurred initialising mixer: %s\n", snd_strerror(err));
- close:
- HeapFree(GetProcessHeap(), 0, mixdev[mixnum].lines);
- HeapFree(GetProcessHeap(), 0, mixdev[mixnum].controls);
- snd_mixer_close(mixdev[mixnum].mix);
- }
- cards = mixnum;
- HeapFree( GetProcessHeap(), 0, info );
- /* There is no trouble with already assigning callbacks without initialising critsect:
- * Callbacks only occur when snd_mixer_handle_events is called (only happens in thread)
- */
- InitializeCriticalSection(&elem_crst);
- elem_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_MIXER.elem_crst");
- TRACE("\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement