Загрузка данных
#include <stddef.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <portaudio.h>
#include <audio_dev.h>
#include <audio_utils.h>
#define PA_THREAD_PRIORITY 9
enum pa_state {
PA_STREAM_RUNNING,
PA_STREAM_STOPPED,
PA_STREAM_CLOSED
};
struct pa_strm {
uint8_t alloc;
uint8_t devid;
uint8_t number_of_chan;
uint32_t sample_format;
int rate;
pthread_cond_t pa_cond;
pthread_mutex_t pa_mutex;
pthread_t pa_thread;
pthread_attr_t threadAttr;
enum pa_state state;
PaStreamCallback *callback;
void *user_data;
int active;
};
#define MODOPS_PA_STREAM_COUNT 2
static struct pa_strm pa_strm_pool[MODOPS_PA_STREAM_COUNT] = {0};
//Mutex && condwait
static int pa_mutex_init(struct pa_strm *pa)
{
pthread_mutexattr_t attr;
int rc;
if(pa == NULL)
return -1;
rc = pthread_mutexattr_init(&attr);
if (rc != 0) {
printf("%s Error pthread_mutexattr_init rc=%d\n",__FUNCTION__,rc);
return rc;
}
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
if (rc != 0) {
printf("%s Error pthread_mutexattr_settype rc=%d\n",__FUNCTION__,rc);
return rc;
}
rc = pthread_mutex_init(&pa->pa_mutex, &attr);
if (rc != 0) {
printf("%s Error pthread_mutex_init rc=%d\n",__FUNCTION__,rc);
return rc;
}
rc = pthread_mutexattr_destroy(&attr);
if (rc != 0) {
printf("%s Error pthread_mutexattr_destroy rc=%d\n",__FUNCTION__,rc);
pthread_mutex_destroy(&pa->pa_mutex);
return rc;
}
return 0;
}
static int pa_mutex_destroy(struct pa_strm *pa)
{
return (pa) ? pthread_mutex_destroy(&pa->pa_mutex) : -1;
}
static void pa_cond_wait(struct pa_strm *pa_stream)
{
if(pa_stream == NULL)
return;
pthread_mutex_lock(&pa_stream->pa_mutex);
while (!pa_stream->active)
{
pthread_cond_wait(&pa_stream->pa_cond, &pa_stream->pa_mutex);
}
pthread_mutex_unlock(&pa_stream->pa_mutex);
}
static void pa_cond_signal(struct pa_strm *pa_stream)
{
if(pa_stream == NULL)
return;
pthread_mutex_lock(&pa_stream->pa_mutex);
pthread_cond_signal(&pa_stream->pa_cond);
pthread_mutex_unlock(&pa_stream->pa_mutex);
}
static struct pa_strm *pa_str_alloc()
{
struct pa_strm *pa_strm_ = NULL;
for(uint8_t i=0; i < MODOPS_PA_STREAM_COUNT; i++)
{
if(pa_strm_pool[i].alloc == 0)
{
pa_strm_ = &pa_strm_pool[i];
pa_strm_pool[i].alloc = 1;
break;
}
}
return pa_strm_;
}
static void pa_str_free(struct pa_strm *pa_strm_)
{
if(!pa_strm_)
return;
for(uint8_t i=0; i < MODOPS_PA_STREAM_COUNT; i++)
{
if(pa_strm_pool[i].devid == pa_strm_->devid)
{
pa_strm_pool[i].alloc = 0;
break;
}
}
}
static void pa_do_rate_conversion(struct pa_strm *pa_stream,
struct audio_dev *audio_dev, uint8_t *buf, int inp_frames) {
int cur_rate, out_rate;
int audio_dev_rate = audio_dev->ad_ops->ad_ops_ioctl(audio_dev,
ADIOCTL_GET_RATE, NULL);
cur_rate = audio_dev->dir == AUDIO_DEV_OUTPUT
? audio_dev_rate : pa_stream->rate;
out_rate = audio_dev->dir == AUDIO_DEV_OUTPUT
? pa_stream->rate : audio_dev_rate;
if(cur_rate != out_rate)
audio_convert_rate(cur_rate, out_rate, buf, inp_frames);
}
/* Sort out problems related to the number of channels */
static void pa_do_channel_conversion(struct pa_strm *pa_stream,
struct audio_dev *audio_dev, uint8_t *buf, int inp_frames) {
int cur_chan, out_chan;
int num_of_chan = audio_dev->ad_ops->ad_ops_ioctl(audio_dev,
audio_dev->dir == AUDIO_DEV_OUTPUT
? ADIOCTL_OUT_SUPPORT
: ADIOCTL_IN_SUPPORT,
NULL);
num_of_chan = num_of_chan & AD_STEREO_SUPPORT ? 2 : 1;
cur_chan = audio_dev->dir == AUDIO_DEV_OUTPUT
? pa_stream->number_of_chan : num_of_chan;
out_chan = audio_dev->dir == AUDIO_DEV_OUTPUT
? num_of_chan : pa_stream->number_of_chan;
printf("stream=%p cur_chan=%d out_chan=%d\n",pa_stream,cur_chan,out_chan);
if(cur_chan != out_chan)
audio_convert_channels(cur_chan, out_chan, buf, inp_frames);
}