Загрузка данных


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;
}