int jack_send_dacs(void) { t_sample * fp; int j; int rtnval = SENDDACS_YES; int timenow; int timeref = sys_getrealtime(); if (!jack_client) return SENDDACS_NO; if (!sys_inchannels && !sys_outchannels) return (SENDDACS_NO); if (jack_dio_error) { sys_log_error(ERR_RESYNC); jack_dio_error = 0; } pthread_mutex_lock(&jack_mutex); if (jack_filled >= jack_out_max) pthread_cond_wait(&jack_sem,&jack_mutex); if (!jack_client) { pthread_mutex_unlock(&jack_mutex); return SENDDACS_NO; } jack_started = 1; fp = sys_soundout; for (j = 0; j < sys_outchannels; j++) { memcpy(jack_outbuf + (j * BUF_JACK) + jack_filled, fp, DEFDACBLKSIZE*sizeof(t_sample)); fp += DEFDACBLKSIZE; } fp = sys_soundin; for (j = 0; j < sys_inchannels; j++) { memcpy(fp, jack_inbuf + (j * BUF_JACK) + jack_filled, DEFDACBLKSIZE*sizeof(t_sample)); fp += DEFDACBLKSIZE; } jack_filled += DEFDACBLKSIZE; pthread_mutex_unlock(&jack_mutex); if ((timenow = sys_getrealtime()) - timeref > 0.002) { rtnval = SENDDACS_SLEPT; } memset(sys_soundout, 0, DEFDACBLKSIZE*sizeof(t_sample)*sys_outchannels); return rtnval; }
void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int advance, int callback, int blocksize) { int i; int defaultchannels = SYS_DEFAULTCH; int inchans, outchans, nrealindev, nrealoutdev; int realindev[MAXAUDIOINDEV], realoutdev[MAXAUDIOOUTDEV]; int realinchans[MAXAUDIOINDEV], realoutchans[MAXAUDIOOUTDEV]; char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0; /* initialize device-arrays */ for(i=0; i<MAXAUDIOINDEV; i++) realindev[i] = realinchans[i] = 0; for(i=0; i<MAXAUDIOOUTDEV; i++) realoutdev[i] = realoutchans[i] = 0; for(i=0; i<MAXNDEV*DEVDESCSIZE; i++) indevlist[i] = outdevlist[i] = 0; audio_getdevs(indevlist, &indevs, outdevlist, &outdevs, &canmulti, &cancallback, MAXNDEV, DEVDESCSIZE); if (rate < 1) rate = DEFAULTSRATE; if (advance < 0) advance = DEFAULTADVANCE; if (blocksize != (1 << ilog2(blocksize)) || blocksize < DEFDACBLKSIZE) blocksize = DEFDACBLKSIZE; audio_init(); /* Since the channel vector might be longer than the audio device vector, or vice versa, we fill the shorter one in to match the longer one. Also, if both are empty, we fill in one device (the default) and two channels. */ if (naudioindev == -1) { /* no input audio devices specified */ if (nchindev == -1) { if (indevs >= 1) { nchindev=1; chindev[0] = defaultchannels; naudioindev = 1; audioindev[0] = DEFAULTAUDIODEV; } else naudioindev = nchindev = 0; } else { for (i = 0; i < MAXAUDIOINDEV; i++) audioindev[i] = i; naudioindev = nchindev; } } else { if (nchindev == -1) { nchindev = naudioindev; for (i = 0; i < naudioindev; i++) chindev[i] = defaultchannels; } else if (nchindev > naudioindev) { for (i = naudioindev; i < nchindev; i++) { if (i == 0) audioindev[0] = DEFAULTAUDIODEV; else audioindev[i] = audioindev[i-1] + 1; } naudioindev = nchindev; } else if (nchindev < naudioindev) { for (i = nchindev; i < naudioindev; i++) { if (i == 0) chindev[0] = defaultchannels; else chindev[i] = chindev[i-1]; } naudioindev = nchindev; } } if (naudiooutdev == -1) { /* not set */ if (nchoutdev == -1) { if (outdevs >= 1) { nchoutdev=1; choutdev[0]=defaultchannels; naudiooutdev=1; audiooutdev[0] = DEFAULTAUDIODEV; } else nchoutdev = naudiooutdev = 0; } else { for (i = 0; i < MAXAUDIOOUTDEV; i++) audiooutdev[i] = i; naudiooutdev = nchoutdev; } } else { if (nchoutdev == -1) { nchoutdev = naudiooutdev; for (i = 0; i < naudiooutdev; i++) choutdev[i] = defaultchannels; } else if (nchoutdev > naudiooutdev) { for (i = naudiooutdev; i < nchoutdev; i++) { if (i == 0) audiooutdev[0] = DEFAULTAUDIODEV; else audiooutdev[i] = audiooutdev[i-1] + 1; } naudiooutdev = nchoutdev; } else if (nchoutdev < naudiooutdev) { for (i = nchoutdev; i < naudiooutdev; i++) { if (i == 0) choutdev[0] = defaultchannels; else choutdev[i] = choutdev[i-1]; } naudiooutdev = nchoutdev; } } /* count total number of input and output channels */ for (i = nrealindev = inchans = 0; i < naudioindev; i++) if (chindev[i] > 0) { realinchans[nrealindev] = chindev[i]; realindev[nrealindev] = audioindev[i]; inchans += chindev[i]; nrealindev++; } for (i = nrealoutdev = outchans = 0; i < naudiooutdev; i++) if (choutdev[i] > 0) { realoutchans[nrealoutdev] = choutdev[i]; realoutdev[nrealoutdev] = audiooutdev[i]; outchans += choutdev[i]; nrealoutdev++; } sys_schedadvance = advance * 1000; sys_log_error(ERR_NOTHING); audio_nextinchans = inchans; audio_nextoutchans = outchans; sys_setchsr(audio_nextinchans, audio_nextoutchans, rate); sys_save_audio_params(nrealindev, realindev, realinchans, nrealoutdev, realoutdev, realoutchans, rate, advance, callback, blocksize); }
int alsa_send_dacs(void) { #ifdef DEBUG_ALSA_XFER static int xferno = 0; static int callno = 0; #endif static double timenow; double timelast; t_sample *fp, *fp1, *fp2; int i, j, k, err, iodev, result, ch; int chansintogo, chansouttogo; unsigned int transfersize; if (alsa_usemmap) return (alsamm_send_dacs()); if (!alsa_nindev && !alsa_noutdev) return (SENDDACS_NO); chansintogo = sys_inchannels; chansouttogo = sys_outchannels; transfersize = DEFDACBLKSIZE; timelast = timenow; timenow = sys_getrealtime(); #ifdef DEBUG_ALSA_XFER if (timenow - timelast > 0.050) fprintf(stderr, "(%d)", (int)(1000 * (timenow - timelast))), fflush(stderr); callno++; #endif alsa_checkiosync(); /* check I/O are in sync and data not late */ for (iodev = 0; iodev < alsa_nindev; iodev++) { snd_pcm_status(alsa_indev[iodev].a_handle, alsa_status); if (snd_pcm_status_get_avail(alsa_status) < transfersize) return SENDDACS_NO; } for (iodev = 0; iodev < alsa_noutdev; iodev++) { snd_pcm_status(alsa_outdev[iodev].a_handle, alsa_status); if (snd_pcm_status_get_avail(alsa_status) < transfersize) return SENDDACS_NO; } /* do output */ for (iodev = 0, fp1 = sys_soundout, ch = 0; iodev < alsa_noutdev; iodev++) { int thisdevchans = alsa_outdev[iodev].a_channels; int chans = (chansouttogo < thisdevchans ? chansouttogo : thisdevchans); chansouttogo -= chans; if (alsa_outdev[iodev].a_sampwidth == 4) { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--; j += thisdevchans, fp2++) { float s1 = *fp2 * INT32_MAX; ((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(s1); } for (; i < thisdevchans; i++, ch++) for (j = i, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((t_alsa_sample32 *)alsa_snd_buf)[j] = 0; } else if (alsa_outdev[iodev].a_sampwidth == 3) { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--; j += thisdevchans, fp2++) { int s = *fp2 * 8388352.; if (s > 8388351) s = 8388351; else if (s < -8388351) s = -8388351; #if BYTE_ORDER == LITTLE_ENDIAN ((char *)(alsa_snd_buf))[3*j] = (s & 255); ((char *)(alsa_snd_buf))[3*j+1] = ((s>>8) & 255); ((char *)(alsa_snd_buf))[3*j+2] = ((s>>16) & 255); #else fprintf(stderr("big endian 24-bit not supported"); #endif } for (; i < thisdevchans; i++, ch++) for (j = i, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((char *)(alsa_snd_buf))[3*j] = ((char *)(alsa_snd_buf))[3*j+1] = ((char *)(alsa_snd_buf))[3*j+2] = 0; } else /* 16 bit samples */ { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--; j += thisdevchans, fp2++) { int s = *fp2 * 32767.; if (s > 32767) s = 32767; else if (s < -32767) s = -32767; ((t_alsa_sample16 *)alsa_snd_buf)[j] = s; } for (; i < thisdevchans; i++, ch++) for (j = ch, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((t_alsa_sample16 *)alsa_snd_buf)[j] = 0; } result = snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, transfersize); if (result != (int)transfersize) { #ifdef DEBUG_ALSA_XFER if (result >= 0 || errno == EAGAIN) fprintf(stderr, "ALSA: write returned %d of %d\n", result, transfersize); else fprintf(stderr, "ALSA: write: %s\n", snd_strerror(errno)); fprintf(stderr, "inputcount %d, outputcount %d, outbufsize %d\n", inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsa_outdev[iodev].a_sampwidth * outchannels); #endif sys_log_error(ERR_DACSLEPT); return (SENDDACS_NO); } /* zero out the output buffer */ memset(sys_soundout, 0, DEFDACBLKSIZE * sizeof(*sys_soundout) * sys_outchannels); if (sys_getrealtime() - timenow > 0.002) { #ifdef DEBUG_ALSA_XFER fprintf(stderr, "output %d took %d msec\n", callno, (int)(1000 * (timenow - timelast))), fflush(stderr); #endif timenow = sys_getrealtime(); sys_log_error(ERR_DACSLEPT); } }
int pa_send_dacs(void) { t_sample *fp; float *fp2, *fp3; float *conversionbuf; int j, k; int rtnval = SENDDACS_YES; int timenow; int timeref = sys_getrealtime(); if (!sys_inchannels && !sys_outchannels) return (SENDDACS_NO); #if CHECKFIFOS if (sys_outchannels * sys_ringbuf_GetReadAvailable(&pa_inring) != sys_inchannels * sys_ringbuf_GetWriteAvailable(&pa_outring)) fprintf(stderr, "warning (2): in and out rings unequal (%d, %d)\n", sys_ringbuf_GetReadAvailable(&pa_inring), sys_ringbuf_GetWriteAvailable(&pa_outring)); #endif conversionbuf = (float *)alloca((sys_inchannels > sys_outchannels? sys_inchannels:sys_outchannels) * DEFDACBLKSIZE * sizeof(float)); if (pa_dio_error) { sys_log_error(ERR_RESYNC); pa_dio_error = 0; } if (!sys_inchannels) /* if no input channels sync on output */ { #ifdef THREADSIGNAL pthread_mutex_lock(&pa_mutex); #endif while (sys_ringbuf_GetWriteAvailable(&pa_outring) < (long)(sys_outchannels * DEFDACBLKSIZE * sizeof(float))) #ifdef THREADSIGNAL pthread_cond_wait(&pa_sem, &pa_mutex); #else #ifdef _WIN32 Sleep(1); #else usleep(1000); #endif /* _WIN32 */ #endif /* THREADSIGNAL */ #ifdef THREADSIGNAL pthread_mutex_unlock(&pa_mutex); #endif } /* write output */ if (sys_outchannels) { for (j = 0, fp = sys_soundout, fp2 = conversionbuf; j < sys_outchannels; j++, fp2++) for (k = 0, fp3 = fp2; k < DEFDACBLKSIZE; k++, fp++, fp3 += sys_outchannels) *fp3 = *fp; sys_ringbuf_Write(&pa_outring, conversionbuf, sys_outchannels*(DEFDACBLKSIZE*sizeof(float))); } if (sys_inchannels) /* if there is input sync on it */ { #ifdef THREADSIGNAL pthread_mutex_lock(&pa_mutex); #endif while (sys_ringbuf_GetReadAvailable(&pa_inring) < (long)(sys_inchannels * DEFDACBLKSIZE * sizeof(float))) #ifdef THREADSIGNAL pthread_cond_wait(&pa_sem, &pa_mutex); #else #ifdef _WIN32 Sleep(1); #else usleep(1000); #endif /* _WIN32 */ #endif /* THREADSIGNAL */ #ifdef THREADSIGNAL pthread_mutex_unlock(&pa_mutex); #endif } pa_started = 1; if (sys_inchannels) { sys_ringbuf_Read(&pa_inring, conversionbuf, sys_inchannels*(DEFDACBLKSIZE*sizeof(float))); for (j = 0, fp = sys_soundin, fp2 = conversionbuf; j < sys_inchannels; j++, fp2++) for (k = 0, fp3 = fp2; k < DEFDACBLKSIZE; k++, fp++, fp3 += sys_inchannels) *fp = *fp3; } if ((timenow = sys_getrealtime()) - timeref > 0.002) { rtnval = SENDDACS_SLEPT; } memset(sys_soundout, 0, DEFDACBLKSIZE*sizeof(t_sample)*sys_outchannels); return rtnval; }
int alsa_send_dacs(void) { static double timenow; double timelast; t_sample *fp, *fp1, *fp2; int i, j, k, err, iodev, result, ch, resync = 0;; int chansintogo, chansouttogo; unsigned int transfersize; if (alsa_usemmap) return (alsamm_send_dacs()); if (!alsa_nindev && !alsa_noutdev) return (SENDDACS_NO); chansintogo = STUFF->st_inchannels; chansouttogo = STUFF->st_outchannels; transfersize = DEFDACBLKSIZE; timelast = timenow; timenow = sys_getrealtime(); #ifdef DEBUG_ALSA_XFER if (timenow - timelast > 0.050) post("long wait between calls: %d", (int)(1000 * (timenow - timelast))), fflush(stderr); callno++; #endif for (iodev = 0; iodev < alsa_nindev; iodev++) { result = snd_pcm_state(alsa_indev[iodev].a_handle); if (result == SND_PCM_STATE_XRUN) { int res2 = snd_pcm_start(alsa_indev[iodev].a_handle); fprintf(stderr, "restart alsa input\n"); if (res2 < 0) fprintf(stderr, "alsa xrun recovery apparently failed\n"); } snd_pcm_status(alsa_indev[iodev].a_handle, alsa_status); if (snd_pcm_status_get_avail(alsa_status) < transfersize) return (SENDDACS_NO); } for (iodev = 0; iodev < alsa_noutdev; iodev++) { result = snd_pcm_state(alsa_outdev[iodev].a_handle); if (result == SND_PCM_STATE_XRUN) { int res2 = snd_pcm_start(alsa_outdev[iodev].a_handle); fprintf(stderr, "restart alsa output\n"); if (res2 < 0) fprintf(stderr, "alsa xrun recovery apparently failed\n"); } snd_pcm_status(alsa_outdev[iodev].a_handle, alsa_status); if (snd_pcm_status_get_avail(alsa_status) < transfersize) return (SENDDACS_NO); } #ifdef DEBUG_ALSA_XFER post("xfer %d", transfersize); #endif /* do output */ for (iodev = 0, fp1 = STUFF->st_soundout, ch = 0; iodev < alsa_noutdev; iodev++) { int thisdevchans = alsa_outdev[iodev].a_channels; int chans = (chansouttogo < thisdevchans ? chansouttogo : thisdevchans); chansouttogo -= chans; if (alsa_outdev[iodev].a_sampwidth == 4) { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--; j += thisdevchans, fp2++) { float s1 = *fp2 * INT32_MAX; ((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(s1); } for (; i < thisdevchans; i++, ch++) for (j = i, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((t_alsa_sample32 *)alsa_snd_buf)[j] = 0; } else if (alsa_outdev[iodev].a_sampwidth == 3) { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--; j += thisdevchans, fp2++) { int s = *fp2 * 8388352.; if (s > 8388351) s = 8388351; else if (s < -8388351) s = -8388351; #if BYTE_ORDER == LITTLE_ENDIAN ((char *)(alsa_snd_buf))[3*j] = (s & 255); ((char *)(alsa_snd_buf))[3*j+1] = ((s>>8) & 255); ((char *)(alsa_snd_buf))[3*j+2] = ((s>>16) & 255); #else fprintf(stderr, "big endian 24-bit not supported"); #endif } for (; i < thisdevchans; i++, ch++) for (j = i, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((char *)(alsa_snd_buf))[3*j] = ((char *)(alsa_snd_buf))[3*j+1] = ((char *)(alsa_snd_buf))[3*j+2] = 0; } else /* 16 bit samples */ { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--; j += thisdevchans, fp2++) { int s = *fp2 * 32767.; if (s > 32767) s = 32767; else if (s < -32767) s = -32767; ((t_alsa_sample16 *)alsa_snd_buf)[j] = s; } for (; i < thisdevchans; i++, ch++) for (j = ch, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((t_alsa_sample16 *)alsa_snd_buf)[j] = 0; } result = snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, transfersize); if (result != (int)transfersize) { #ifdef DEBUG_ALSA_XFER if (result >= 0 || errno == EAGAIN) post("ALSA: write returned %d of %d\n", result, transfersize); else post("ALSA: write: %s\n", snd_strerror(errno)); #endif sys_log_error(ERR_DATALATE); if (result == -EPIPE) { result = snd_pcm_prepare(alsa_indev[iodev].a_handle); if (result < 0) fprintf(stderr, "read reset error %d\n", result); } else fprintf(stderr, "read other error %d\n", result); resync = 1; } /* zero out the output buffer */ memset(STUFF->st_soundout, 0, DEFDACBLKSIZE * sizeof(*STUFF->st_soundout) * STUFF->st_outchannels); if (sys_getrealtime() - timenow > 0.002) { #ifdef DEBUG_ALSA_XFER post("output %d took %d msec\n", callno, (int)(1000 * (timenow - timelast))), fflush(stderr); #endif timenow = sys_getrealtime(); sys_log_error(ERR_DACSLEPT); } }
void sys_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int advance, int enable) { #ifdef ROCKBOX int i; #else int i, *ip; #endif int defaultchannels = SYS_DEFAULTCH; int inchans, outchans; if (rate < 1) rate = SYS_DEFAULTSRATE; #ifdef ROCKBOX pd_audio_init(); #else audio_init(); #endif /* Since the channel vector might be longer than the audio device vector, or vice versa, we fill the shorter one in to match the longer one. Also, if both are empty, we fill in one device (the default) and two channels. */ if (naudioindev == -1) { /* no input audio devices specified */ if (nchindev == -1) { nchindev=1; chindev[0] = defaultchannels; naudioindev = 1; audioindev[0] = DEFAULTAUDIODEV; } else { for (i = 0; i < MAXAUDIOINDEV; i++) audioindev[i] = i; naudioindev = nchindev; } } else { if (nchindev == -1) { nchindev = naudioindev; for (i = 0; i < naudioindev; i++) chindev[i] = defaultchannels; } else if (nchindev > naudioindev) { for (i = naudioindev; i < nchindev; i++) { if (i == 0) audioindev[0] = DEFAULTAUDIODEV; else audioindev[i] = audioindev[i-1] + 1; } naudioindev = nchindev; } else if (nchindev < naudioindev) { for (i = nchindev; i < naudioindev; i++) { if (i == 0) chindev[0] = defaultchannels; else chindev[i] = chindev[i-1]; } naudioindev = nchindev; } } if (naudiooutdev == -1) { /* not set */ if (nchoutdev == -1) { nchoutdev=1; choutdev[0]=defaultchannels; naudiooutdev=1; audiooutdev[0] = DEFAULTAUDIODEV; } else { for (i = 0; i < MAXAUDIOOUTDEV; i++) audiooutdev[i] = i; naudiooutdev = nchoutdev; } } else { if (nchoutdev == -1) { nchoutdev = naudiooutdev; for (i = 0; i < naudiooutdev; i++) choutdev[i] = defaultchannels; } else if (nchoutdev > naudiooutdev) { for (i = naudiooutdev; i < nchoutdev; i++) { if (i == 0) audiooutdev[0] = DEFAULTAUDIODEV; else audiooutdev[i] = audiooutdev[i-1] + 1; } naudiooutdev = nchoutdev; } else if (nchoutdev < naudiooutdev) { for (i = nchoutdev; i < naudiooutdev; i++) { if (i == 0) choutdev[0] = defaultchannels; else choutdev[i] = choutdev[i-1]; } naudiooutdev = nchoutdev; } } /* count total number of input and output channels */ for (i = inchans = 0; i < naudioindev; i++) inchans += chindev[i]; for (i = outchans = 0; i < naudiooutdev; i++) outchans += choutdev[i]; /* if no input or output devices seem to have been specified, this really means just disable audio, which we now do. Meanwhile, we can set audio input and output devices to their defaults. */ if (!inchans && !outchans) { enable = 0; naudioindev = nchindev = naudiooutdev = nchoutdev = 1; audioindev[0] = audiooutdev[0] = DEFAULTAUDIODEV; chindev[0] = choutdev[0] = 0; } sys_schedadvance = advance * 1000; sys_setchsr(inchans, outchans, rate); sys_log_error(ERR_NOTHING); if (enable && (inchans > 0 || outchans > 0)) { #ifdef USEAPI_PORTAUDIO if (sys_audioapi == API_PORTAUDIO) { int blksize = (sys_blocksize ? sys_blocksize : 64); pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout, blksize, sys_advance_samples/blksize, (naudiooutdev > 0 ? audioindev[0] : 0), (naudiooutdev > 0 ? audiooutdev[0] : 0)); } else #endif #ifdef USEAPI_JACK if (sys_audioapi == API_JACK) jack_open_audio((naudioindev > 0 ? chindev[0] : 0), (naudiooutdev > 0 ? choutdev[0] : 0), rate); else #endif #ifdef USEAPI_OSS if (sys_audioapi == API_OSS) oss_open_audio(naudioindev, audioindev, nchindev, chindev, naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); else #endif #ifdef USEAPI_ALSA /* for alsa, only one device is supported; it may be open for both input and output. */ if (sys_audioapi == API_ALSA) alsa_open_audio(naudioindev, audioindev, nchindev, chindev, naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); else #endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) mmio_open_audio(naudioindev, audioindev, nchindev, chindev, naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); else #endif #ifdef USEAPI_ROCKBOX if (sys_audioapi == API_ROCKBOX) rockbox_open_audio(rate); else #endif post("unknown audio API specified"); } sys_save_audio_params(naudioindev, audioindev, chindev, naudiooutdev, audiooutdev, choutdev, rate, advance); if (sys_inchannels == 0 && sys_outchannels == 0) enable = 0; audio_state = enable; #ifndef ROCKBOX sys_vgui("set pd_whichapi %d\n", (audio_isopen() ? sys_audioapi : 0)); #endif sched_set_using_dacs(enable); }