void sys_close_audio(void) { if (sys_externalschedlib) { return; } if (!audio_isopen()) return; #ifdef USEAPI_PORTAUDIO if (sys_audioapiopened == API_PORTAUDIO) pa_close_audio(); else #endif #ifdef USEAPI_JACK if (sys_audioapiopened == API_JACK) jack_close_audio(); else #endif #ifdef USEAPI_OSS if (sys_audioapiopened == API_OSS) oss_close_audio(); else #endif #ifdef USEAPI_ALSA if (sys_audioapiopened == API_ALSA) alsa_close_audio(); else #endif #ifdef USEAPI_MMIO if (sys_audioapiopened == API_MMIO) mmio_close_audio(); else #endif #ifdef USEAPI_AUDIOUNIT if (sys_audioapiopened == API_AUDIOUNIT) audiounit_close_audio(); else #endif #ifdef USEAPI_ESD if (sys_audioapiopened == API_ESD) esd_close_audio(); else #endif #ifdef USEAPI_DUMMY if (sys_audioapiopened == API_DUMMY) dummy_close_audio(); else #endif post("sys_close_audio: unknown API %d", sys_audioapiopened); sys_inchannels = sys_outchannels = 0; sys_audioapiopened = -1; sched_set_using_audio(SCHED_AUDIO_NONE); audio_state = 0; audio_callback_is_open = 0; sys_vgui("set pd_whichapi 0\n"); }
void sys_close_audio(void) { if (!audio_isopen()) return; #ifdef USEAPI_PORTAUDIO if (sys_audioapi == API_PORTAUDIO) pa_close_audio(); else #endif #ifdef USEAPI_JACK if (sys_audioapi == API_JACK) jack_close_audio(); else #endif #ifdef USEAPI_OSS if (sys_audioapi == API_OSS) oss_close_audio(); else #endif #ifdef USEAPI_ALSA if (sys_audioapi == API_ALSA) alsa_close_audio(); else #endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) mmio_close_audio(); else #endif #ifdef USEAPI_ROCKBOX if (sys_audioapi == API_ROCKBOX) rockbox_close_audio(); else #endif post("sys_close_audio: unknown API %d", sys_audioapi); sys_inchannels = sys_outchannels = 0; }
/* return 0 on success */ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate) { int err, inchans = 0, outchans = 0, subunitdir; char devname[512]; snd_output_t* out; int frag_size = (sys_blocksize ? sys_blocksize : ALSA_DEFFRAGSIZE); int nfrags, i, iodev, dev2; int wantinchans, wantoutchans, device; nfrags = sys_schedadvance * (float)rate / (1e6 * frag_size); /* save our belief as to ALSA's buffer size for later */ alsa_buf_samps = nfrags * frag_size; alsa_nindev = alsa_noutdev = 0; alsa_jittermax = ALSA_DEFJITTERMAX; if (sys_verbose) post("audio buffer set to %d", (int)(0.001 * sys_schedadvance)); for (iodev = 0; iodev < naudioindev; iodev++) { alsa_numbertoname(audioindev[iodev], devname, 512); err = snd_pcm_open(&alsa_indev[alsa_nindev].a_handle, devname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); check_error(err, "snd_pcm_open (input)"); if (err < 0) continue; alsa_indev[alsa_nindev].a_devno = audioindev[iodev]; snd_pcm_nonblock(alsa_indev[alsa_nindev].a_handle, 1); if (sys_verbose) post("opened input device name %s", devname); alsa_nindev++; } for (iodev = 0; iodev < naudiooutdev; iodev++) { alsa_numbertoname(audiooutdev[iodev], devname, 512); err = snd_pcm_open(&alsa_outdev[alsa_noutdev].a_handle, devname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); check_error(err, "snd_pcm_open (output)"); if (err < 0) continue; alsa_outdev[alsa_noutdev].a_devno = audiooutdev[iodev]; snd_pcm_nonblock(alsa_outdev[alsa_noutdev].a_handle, 1); alsa_noutdev++; } if (!alsa_nindev && !alsa_noutdev) goto blewit; /* If all the open devices support mmap_noninterleaved, let's call Wini's code in s_audio_alsamm.c */ alsa_usemmap = 1; for (iodev = 0; iodev < alsa_nindev; iodev++) if (!alsaio_canmmap(&alsa_indev[iodev])) alsa_usemmap = 0; for (iodev = 0; iodev < alsa_noutdev; iodev++) if (!alsaio_canmmap(&alsa_outdev[iodev])) alsa_usemmap = 0; if (alsa_usemmap) { post("using mmap audio interface"); if (alsamm_open_audio(rate)) goto blewit; else return (0); } for (iodev = 0; iodev < alsa_nindev; iodev++) { int channels = chindev[iodev]; if (alsaio_setup(&alsa_indev[iodev], 0, &channels, &rate, nfrags, frag_size) < 0) goto blewit; inchans += channels; } for (iodev = 0; iodev < alsa_noutdev; iodev++) { int channels = choutdev[iodev]; if (alsaio_setup(&alsa_outdev[iodev], 1, &channels, &rate, nfrags, frag_size) < 0) goto blewit; outchans += channels; } if (!inchans && !outchans) goto blewit; for (iodev = 0; iodev < alsa_nindev; iodev++) snd_pcm_prepare(alsa_indev[iodev].a_handle); for (iodev = 0; iodev < alsa_noutdev; iodev++) snd_pcm_prepare(alsa_outdev[iodev].a_handle); /* if duplex we can link the channels so they start together */ for (iodev = 0; iodev < alsa_nindev; iodev++) for (dev2 = 0; dev2 < alsa_noutdev; dev2++) { if (alsa_indev[iodev].a_devno == alsa_outdev[iodev].a_devno) { snd_pcm_link(alsa_indev[iodev].a_handle, alsa_outdev[iodev].a_handle); } } /* allocate the status variables */ if (!alsa_status) { err = snd_pcm_status_malloc(&alsa_status); check_error(err, "snd_pcm_status_malloc"); } /* fill the buffer with silence */ memset(alsa_snd_buf, 0, alsa_snd_bufsize); if (outchans) { i = (frag_size * nfrags)/DEFDACBLKSIZE + 1; while (i--) { for (iodev = 0; iodev < alsa_noutdev; iodev++) snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, DEFDACBLKSIZE); } } else if (inchans) { for (iodev = 0; iodev < alsa_nindev; iodev++) if ((err = snd_pcm_start(alsa_indev[iodev].a_handle)) < 0) check_error(err, "input start failed\n"); } return (0); blewit: sys_inchannels = 0; sys_outchannels = 0; alsa_close_audio(); return (1); }