Advertisement
Guest User

Untitled

a guest
May 28th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.91 KB | None | 0 0
  1.  
  2. static void ALSA_MixerInit(void)
  3. {
  4. int x, mixnum = 0;
  5. snd_ctl_card_info_t *info;
  6.  
  7. info = HeapAlloc( GetProcessHeap(), 0, snd_ctl_card_info_sizeof());
  8. for (x = 0; x < MAX_MIXERS; ++x)
  9. {
  10. int card, err, capcontrols = 0;
  11. char cardind[6], cardname[10];
  12.  
  13. snd_ctl_t *ctl;
  14. snd_mixer_elem_t *elem, *mastelem = NULL, *headelem = NULL, *captelem = NULL, *pcmelem = NULL, *micelem = NULL;
  15.  
  16. memset(info, 0, snd_ctl_card_info_sizeof());
  17. memset(&mixdev[mixnum], 0, sizeof(*mixdev));
  18. snprintf(cardind, sizeof(cardind), "%d", x);
  19. card = snd_card_get_index(cardind);
  20. if (card < 0)
  21. continue;
  22.  
  23. snprintf(cardname, sizeof(cardname), "hw:%d", card);
  24.  
  25. err = snd_ctl_open(&ctl, cardname, 0);
  26. if (err < 0)
  27. {
  28. WARN("Cannot open card: %s\n", snd_strerror(err));
  29. continue;
  30. }
  31.  
  32. err = snd_ctl_card_info(ctl, info);
  33. if (err < 0)
  34. {
  35. WARN("Cannot get card info: %s\n", snd_strerror(err));
  36. snd_ctl_close(ctl);
  37. continue;
  38. }
  39.  
  40. MultiByteToWideChar(CP_UNIXCP, 0, snd_ctl_card_info_get_name(info), -1, mixdev[mixnum].mixername, sizeof(mixdev[mixnum].mixername)/sizeof(WCHAR));
  41. snd_ctl_close(ctl);
  42.  
  43. err = snd_mixer_open(&mixdev[mixnum].mix, 0);
  44. if (err < 0)
  45. {
  46. WARN("Error occurred opening mixer: %s\n", snd_strerror(err));
  47. continue;
  48. }
  49.  
  50. FIXME("Card: %s\n", cardname);
  51.  
  52. err = snd_mixer_attach(mixdev[mixnum].mix, cardname);
  53. if (err < 0)
  54. goto eclose;
  55.  
  56. err = snd_mixer_selem_register(mixdev[mixnum].mix, NULL, NULL);
  57. if (err < 0)
  58. goto eclose;
  59.  
  60. err = snd_mixer_load(mixdev[mixnum].mix);
  61. if (err < 0)
  62. goto eclose;
  63.  
  64. /* First, lets see what's available..
  65. * If there are multiple Master or Captures, all except 1 will be added as slaves
  66. */
  67. for (elem = snd_mixer_first_elem(mixdev[mixnum].mix); elem; elem = snd_mixer_elem_next(elem))
  68. //crashes on this fixme if enabled
  69. //if not, there is no crash, but no sliders work for sndvol32.exe
  70. //FIXME("elem name: %s on card %s\n", snd_mixer_selem_get_name(elem), cardname);
  71. if (!strcasecmp(snd_mixer_selem_get_name(elem), "Master") && !mastelem)
  72. mastelem = elem;
  73. else if ((!strcasecmp(snd_mixer_selem_get_name(elem), "Capture") ||
  74. !strcasecmp(snd_mixer_selem_get_name(elem), "Mic")) && !captelem)
  75. captelem = elem;
  76. else if (!blacklisted(elem))
  77. {
  78. DWORD comp = getcomponenttype(snd_mixer_selem_get_name(elem));
  79. DWORD skip = 0;
  80.  
  81. /* Work around buggy drivers: Make this a capture control if the name is recognised as a microphone */
  82. if (snd_mixer_selem_has_capture_volume(elem))
  83. ++capcontrols;
  84. else if (comp == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
  85. {
  86. ++capcontrols;
  87. skip = 1;
  88. }
  89.  
  90. if (!skip && snd_mixer_selem_has_playback_volume(elem))
  91. {
  92. if (!strcasecmp(snd_mixer_selem_get_name(elem), "Headphone") && !headelem)
  93. headelem = elem;
  94. else if (!strcasecmp(snd_mixer_selem_get_name(elem), "PCM") && !pcmelem)
  95. pcmelem = elem;
  96. else
  97. ++(mixdev[mixnum].chans);
  98. }
  99. }
  100.  
  101. /* Add master channel, uncounted channels and an extra for capture */
  102. mixdev[mixnum].chans += !!mastelem + !!headelem + !!pcmelem + 1;
  103.  
  104. /* If there is only 'Capture' and 'Master', this device is not worth it */
  105. if (mixdev[mixnum].chans == 2)
  106. {
  107. WARN("No channels found, skipping device!\n");
  108. goto close;
  109. }
  110.  
  111. /* Master element can't have a capture control in this code, so
  112. * if Headphone or PCM is promoted to master, unset its capture control */
  113. if (headelem && !mastelem)
  114. {
  115. /* Using 'Headphone' as master device */
  116. mastelem = headelem;
  117. capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
  118. }
  119. else if (pcmelem && !mastelem)
  120. {
  121. /* Use 'PCM' as master device */
  122. mastelem = pcmelem;
  123. capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
  124. }
  125. else if (!mastelem && !captelem)
  126. {
  127. /* If there is nothing sensible that can act as 'Master' control, something is wrong */
  128. FIXME("No master control found on %s, disabling mixer\n", snd_ctl_card_info_get_name(info));
  129. goto close;
  130. }
  131.  
  132. if (!captelem || !capcontrols)
  133. {
  134. /* Can't enable capture, so disabling it
  135. * Note: capture control will still exist because
  136. * dwLineID 0 and 1 are reserved for Master and Capture
  137. */
  138. WARN("No use enabling capture part of mixer, capture control found: %s, amount of capture controls: %d\n",
  139. (!captelem ? "no" : "yes"), capcontrols);
  140. capcontrols = 0;
  141. mixdev[mixnum].dests = 1;
  142. }
  143. else
  144. {
  145. mixdev[mixnum].chans += capcontrols;
  146. mixdev[mixnum].dests = 2;
  147. }
  148.  
  149. mixdev[mixnum].lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(line) * mixdev[mixnum].chans);
  150. mixdev[mixnum].controls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(control) * CONTROLSPERLINE*mixdev[mixnum].chans);
  151. err = -ENOMEM;
  152. if (!mixdev[mixnum].lines || !mixdev[mixnum].controls)
  153. goto close;
  154.  
  155. filllines(&mixdev[mixnum], mastelem, captelem, capcontrols);
  156. fillcontrols(&mixdev[mixnum]);
  157.  
  158. TRACE("%s: Amount of controls: %i/%i, name: %s\n", cardname, mixdev[mixnum].dests, mixdev[mixnum].chans, debugstr_w(mixdev[mixnum].mixername));
  159. mixnum++;
  160. continue;
  161.  
  162. eclose:
  163. WARN("Error occurred initialising mixer: %s\n", snd_strerror(err));
  164. close:
  165. HeapFree(GetProcessHeap(), 0, mixdev[mixnum].lines);
  166. HeapFree(GetProcessHeap(), 0, mixdev[mixnum].controls);
  167. snd_mixer_close(mixdev[mixnum].mix);
  168. }
  169. cards = mixnum;
  170. HeapFree( GetProcessHeap(), 0, info );
  171.  
  172. /* There is no trouble with already assigning callbacks without initialising critsect:
  173. * Callbacks only occur when snd_mixer_handle_events is called (only happens in thread)
  174. */
  175. InitializeCriticalSection(&elem_crst);
  176. elem_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_MIXER.elem_crst");
  177. TRACE("\n");
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement