X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Faudioalsa.C;h=4a128a74a3586a20ca3ff8ce60ea60d5aa6499b7;hb=22c6251d37911a11e322bf7518e6a992ea0bb6c7;hp=7a8d712c3b8f2687280dd33a9bccfa0925872c12;hpb=7fd85fb66168f6b518c5f2d73e04036e87faa0e1;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/cinelerra/audioalsa.C b/cinelerra-5.1/cinelerra/audioalsa.C index 7a8d712c..4a128a74 100644 --- a/cinelerra-5.1/cinelerra/audioalsa.C +++ b/cinelerra-5.1/cinelerra/audioalsa.C @@ -67,7 +67,7 @@ public: ~alsa_leaks() { snd_config_update_free_global(); } } alsa_leak; -void AudioALSA::list_devices(ArrayList *devices, int pcm_title, int mode) +void AudioALSA::list_devices(ArrayList *names, ArrayList *pcm_names, int mode) { snd_ctl_t *handle; int card, err, dev; @@ -92,24 +92,22 @@ void AudioALSA::list_devices(ArrayList *devices, int pcm_title, int mode) card = -1; #define DEFAULT_DEVICE "default" - char *result = new char[strlen(DEFAULT_DEVICE) + 1]; - devices->append(result); - strcpy(result, DEFAULT_DEVICE); + if( names ) + names->append(cstrdup(DEFAULT_DEVICE)); + if( pcm_names ) + pcm_names->append(cstrdup(DEFAULT_DEVICE)); - while(snd_card_next(&card) >= 0) - { + while(snd_card_next(&card) >= 0) { char name[BCTEXTLEN]; if(card < 0) break; sprintf(name, "hw:%i", card); - if((err = snd_ctl_open(&handle, name, 0)) < 0) - { + if((err = snd_ctl_open(&handle, name, 0)) < 0) { printf("AudioALSA::list_devices card=%i: %s\n", card, snd_strerror(err)); continue; } - if((err = snd_ctl_card_info(handle, info)) < 0) - { + if((err = snd_ctl_card_info(handle, info)) < 0) { printf("AudioALSA::list_devices card=%i: %s\n", card, snd_strerror(err)); snd_ctl_close(handle); continue; @@ -117,103 +115,36 @@ void AudioALSA::list_devices(ArrayList *devices, int pcm_title, int mode) dev = -1; - while(1) - { + while(1) { if(snd_ctl_pcm_next_device(handle, &dev) < 0) printf("AudioALSA::list_devices: snd_ctl_pcm_next_device\n"); - if (dev < 0) - break; + if (dev < 0) break; snd_pcm_info_set_device(pcminfo, dev); snd_pcm_info_set_subdevice(pcminfo, 0); snd_pcm_info_set_stream(pcminfo, stream); - if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) - { + if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { if(err != -ENOENT) printf("AudioALSA::list_devices card=%i: %s\n", card, snd_strerror(err)); continue; } - if(pcm_title) - { + if( pcm_names ) { sprintf(string, "plughw:%d,%d", card, dev); // strcpy(string, "cards.pcm.front"); + pcm_names->append(cstrdup(string)); } - else - { + if( names ) { sprintf(string, "%s #%d", - snd_ctl_card_info_get_name(info), - dev); + snd_ctl_card_info_get_name(info), dev); + names->append(cstrdup(string)); } - - char *result = devices->append(new char[strlen(string) + 1]); - strcpy(result, string); } - - snd_ctl_close(handle); } - -#ifdef HAVE_PACTL -// attempt to add pulseaudio "monitor" devices -// run: pactl list | -// scan output for #n, Name: -// build alsa device config and add to alsa snd_config - - const char *arg = 0; - switch( mode ) { - case MODERECORD: - arg = "source"; - break; - case MODEPLAY: - arg = "sink"; - break; - } - FILE *pactl = 0; - char line[BCTEXTLEN]; - if( arg ) { - sprintf(line, "pactl list %ss", arg); - pactl = popen(line,"r"); - } - if( pactl ) { - if( pcm_title ) snd_config_update(); - char name[BCTEXTLEN], pa_name[BCTEXTLEN], device[BCTEXTLEN]; - name[0] = pa_name[0] = device[0] = 0; - int arg_len = strlen(arg); - while( fgets(line, sizeof(line), pactl) ) { - if( !strncasecmp(line, arg, arg_len) ) { - char *sp = name, *id = pa_name; - for( char *cp=line; *cp && *cp!='\n'; *sp++=*cp++ ) - *id++ = (*cp>='A' && *cp<='Z') || - (*cp>='a' && *cp<='z') || - (*cp>='0' && *cp<='9') ? *cp : '_'; - *sp++ = 0; *id = 0; - if( !pcm_title ) - devices->append(strcpy(new char[sp-name], name)); - continue; - } - if( !pcm_title ) continue; - if( sscanf(line, " Name: %s", device) != 1 ) continue; - int len = strlen(pa_name); - devices->append(strcpy(new char[len+1], pa_name)); - char alsa_config[BCTEXTLEN]; - len = snprintf(alsa_config, sizeof(alsa_config), - "pcm.!%s {\n type pulse\n device %s\n}\n" - "ctl.!%s {\n type pulse\n device %s\n}\n", - pa_name, device, pa_name, device); - FILE *fp = fmemopen(alsa_config,len,"r"); - snd_input_t *inp; - snd_input_stdio_attach(&inp, fp, 1); - snd_config_load(snd_config, inp); - name[0] = pa_name[0] = device[0] = 0; - snd_input_close(inp); - } - pclose(pactl); - } -#endif } void AudioALSA::translate_name(char *output, char *input, int mode) @@ -224,8 +155,10 @@ void AudioALSA::translate_name(char *output, char *input, int mode) ArrayList pcm_titles; pcm_titles.set_array_delete(); - list_devices(&titles, 0, mode); - list_devices(&pcm_titles, 1, mode); + list_devices(&titles, &pcm_titles, mode); + +// attempt to add pulseaudio "monitor" devices + add_pulse_devices(mode, &titles, &pcm_titles); sprintf(output, "default"); for(int i = 0; i < titles.total; i++) @@ -246,18 +179,10 @@ snd_pcm_format_t AudioALSA::translate_format(int format) { switch(format) { - case 8: - return SND_PCM_FORMAT_S8; - break; - case 16: - return SND_PCM_FORMAT_S16_LE; - break; - case 24: - return SND_PCM_FORMAT_S24_LE; - break; - case 32: - return SND_PCM_FORMAT_S32_LE; - break; + case 8: return SND_PCM_FORMAT_S8; + case 16: return SND_PCM_FORMAT_S16_LE; + case 24: return SND_PCM_FORMAT_S24_LE; + case 32: return SND_PCM_FORMAT_S32_LE; } return SND_PCM_FORMAT_UNKNOWN; } @@ -599,7 +524,7 @@ int AudioALSA::write_buffer(char *buffer, int size) done = 1; } else { - printf("AudioALSA::write_buffer err %d(%s) at sample %jd\n", + printf(_("AudioALSA::write_buffer err %d(%s) at sample %jd\n"), ret, snd_strerror(ret), device->current_position()); Timer::delay(50); // snd_pcm_resume(get_output()); @@ -696,4 +621,64 @@ snd_pcm_t* AudioALSA::get_input() return dsp_in; } +void AudioALSA::add_pulse_devices(int mode, + ArrayList *names, ArrayList *pcm_names) +{ +#ifdef HAVE_PACTL +// run: pactl list | +// scan output for #n, Name: +// build alsa device config and add to alsa snd_config + const char *arg = 0; + switch( mode ) { + case MODERECORD: + arg = "source"; + break; + case MODEPLAY: + arg = "sink"; + break; + } + FILE *pactl = 0; + char line[BCTEXTLEN]; + if( arg ) { + sprintf(line, "LANGUAGE=en_US.UTF-8 pactl list %ss", arg); + pactl = popen(line,"r"); + } + if( pactl ) { + snd_config_update(); + char name[BCTEXTLEN], pa_name[BCTEXTLEN], device[BCTEXTLEN]; + name[0] = pa_name[0] = device[0] = 0; + int arg_len = strlen(arg); + while( fgets(line, sizeof(line), pactl) ) { + if( !strncasecmp(line, arg, arg_len) ) { + char *sp = name, *id = pa_name; + for( char *cp=line; *cp && *cp!='\n'; *sp++=*cp++ ) + *id++ = (*cp>='A' && *cp<='Z') || + (*cp>='a' && *cp<='z') || + (*cp>='0' && *cp<='9') ? *cp : '_'; + *sp++ = 0; *id = 0; + if( names ) + names->append(cstrdup(name)); + continue; + } + if( sscanf(line, " Name: %s", device) != 1 ) continue; + int len = strlen(pa_name); + if( pcm_names ) + pcm_names->append(cstrdup(pa_name)); + char alsa_config[BCTEXTLEN]; + len = snprintf(alsa_config, sizeof(alsa_config), + "pcm.!%s {\n type pulse\n device %s\n}\n" + "ctl.!%s {\n type pulse\n device %s\n}\n", + pa_name, device, pa_name, device); + FILE *fp = fmemopen(alsa_config,len,"r"); + snd_input_t *inp; + snd_input_stdio_attach(&inp, fp, 1); + snd_config_load(snd_config, inp); + name[0] = pa_name[0] = device[0] = 0; + snd_input_close(inp); + } + pclose(pactl); + } +#endif +} + #endif