zephyr_audio_dev.c:
uint8_t *audio_dev_get_in_cur_ptr(struct audio_dev *audio_dev) {
struct zephyr_audio_dev_priv *priv = audio_dev->ad_priv;
return priv->dev_type == ZEPHYR_DIGITAL_IN ? priv->buf : NULL;
}
portaudio_lib.c:
static void *pa_thread_hnd_in(void *arg) {
struct pa_strm *pa_stream = (struct pa_strm *) arg;
int err;
struct audio_dev *audio_dev;
uint8_t *in_buf = NULL;
int inp_frames;
int out_frames;
int buf_len;
int audio_dev_rate;
int div;
audio_dev = audio_dev_get_by_idx(pa_stream->devid);
if(!audio_dev || !audio_dev->ad_ops || !audio_dev->ad_ops->ad_ops_start || !audio_dev->ad_ops->ad_ops_resume)
{
printf("pa_thread_hnd: failed audio_dev=%p\n",audio_dev);
return NULL;
}
audio_dev_rate = audio_dev->ad_ops->ad_ops_ioctl(audio_dev,
ADIOCTL_GET_RATE, NULL);
buf_len = audio_dev->ad_ops->ad_ops_ioctl(audio_dev,
ADIOCTL_BUFLEN, NULL);
if (buf_len == -1) {
printf("Couldn't get audio device buf_len\n");
return NULL;
}
if (!pa_stream->callback) {
printf("No callback provided for PA thread. "
"That's probably not what you want.\n");
return NULL;
}
pa_cond_wait(pa_stream);
audio_dev->ad_ops->ad_ops_start(audio_dev);
out_frames = buf_len; /* This one is in bytes */
switch (pa_stream->sample_format) {
case paInt8:
case paUInt8:
/* Leave it as is */
break;
case paInt16:
out_frames /= 2;
break;
case paInt24:
out_frames /= 3;
case paFloat32:
case paInt32:
out_frames /= 4;
break;
default:
printf("Unknown sample format: %d\n", pa_stream->sample_format);
}
/* Even if source is mono channel,
* we will anyway put twice as much data
* to fill right channel as well */
//out_frames /= 2; /* XXX work with mono-support devices */
div = audio_dev_rate / pa_stream->rate;
if(div <= 0)
div = 1;
inp_frames = out_frames / div;
printf("pa_thread_hnd_in) audio_dev_rate=%u stream: rate=%u sample_format=0x%X num_chan=%d out_frames=%d inp_frames=%d\n",audio_dev_rate,pa_stream->rate,pa_stream->sample_format,pa_stream->number_of_chan,out_frames,inp_frames);
while (1) {
pa_cond_wait(pa_stream);
if (pa_stream->state != PA_STREAM_RUNNING) {
printf("Exit pa_in_thread\n");
audio_dev_close_in_stream();
return NULL;
}
switch (audio_dev->dir) {
case AUDIO_DEV_INPUT:
in_buf = audio_dev_get_in_cur_ptr(audio_dev);
//printf("in_buf = 0x%X, buf_len %d\n", in_buf, buf_len);
pa_do_rate_conversion(pa_stream, audio_dev, in_buf,
inp_frames);
pa_do_channel_conversion(pa_stream, audio_dev, in_buf,
inp_frames);
break;
default:
break;
}
err = pa_stream->callback(in_buf,
NULL,
inp_frames,
NULL,
0,
pa_stream->user_data);
switch (err) {
case paContinue:
/* Allright, just to continue the stream */
break;
/* Continue until all buffers generated by the callback
* have been played */
case paComplete:
Pa_StopStream(pa_stream);
break;
default:
printf("pa_thread_hnd_in: User callback error: %d\n", err);
Pa_StopStream(pa_stream);
break;
}
pa_stream->active = 0;
audio_dev->ad_ops->ad_ops_resume(audio_dev);
}
audio_dev_close_in_stream();
return NULL;
}