613 lines
15 KiB
C
613 lines
15 KiB
C
|
#include <stdio.h>
|
||
|
#include <alsa/asoundlib.h>
|
||
|
#include <pthread.h>
|
||
|
|
||
|
struct rt_hwparams {
|
||
|
snd_pcm_format_t format;
|
||
|
unsigned int channels;
|
||
|
unsigned int rate;
|
||
|
|
||
|
snd_pcm_uframes_t buffer_size;
|
||
|
snd_pcm_uframes_t period_size;
|
||
|
};
|
||
|
|
||
|
pthread_t play_thread;
|
||
|
pthread_t capture_thread;
|
||
|
|
||
|
pthread_attr_t play_thread_attr;
|
||
|
struct sched_param play_schedule_param;
|
||
|
|
||
|
pthread_attr_t capture_thread_attr;
|
||
|
struct sched_param capture_schedule_param;
|
||
|
|
||
|
void *func_play_demo(void *arg);
|
||
|
void *func_play_hub_demo(void *arg);
|
||
|
|
||
|
void *func_capture_demo(void *arg);
|
||
|
void *func_capture_sync_demo(void *arg);
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
pthread_attr_init(&play_thread_attr);
|
||
|
play_schedule_param.sched_priority = 88;
|
||
|
pthread_attr_setinheritsched(&play_thread_attr, PTHREAD_EXPLICIT_SCHED);
|
||
|
pthread_attr_setschedpolicy(&play_thread_attr, SCHED_RR);
|
||
|
pthread_attr_setschedparam(&play_thread_attr, &play_schedule_param);
|
||
|
|
||
|
pthread_attr_init(&capture_thread_attr);
|
||
|
capture_schedule_param.sched_priority = 88;
|
||
|
pthread_attr_setinheritsched(&capture_thread_attr, PTHREAD_EXPLICIT_SCHED);
|
||
|
pthread_attr_setschedpolicy(&capture_thread_attr, SCHED_RR);
|
||
|
pthread_attr_setschedparam(&capture_thread_attr, &capture_schedule_param);
|
||
|
|
||
|
// pthread_create(&play_thread, &play_thread_attr, func_play_demo, &play_schedule_param);
|
||
|
pthread_create(&play_thread, &play_thread_attr, func_play_hub_demo, &play_schedule_param);
|
||
|
// pthread_create(&capture_thread, &capture_thread_attr, func_capture_demo, &capture_schedule_param);
|
||
|
pthread_create(&capture_thread, &capture_thread_attr, func_capture_sync_demo, &capture_schedule_param);
|
||
|
|
||
|
pthread_join(play_thread, NULL);
|
||
|
pthread_join(capture_thread, NULL);
|
||
|
|
||
|
printf("main exit\n");
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int rt_snd_pcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode,
|
||
|
snd_pcm_hw_params_t *hw_params, struct rt_hwparams *hwparams)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
ret = snd_pcm_open(pcmp, name, stream, mode);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_open failed: %d.\n", ret);
|
||
|
goto err_pcm_open;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_any(*pcmp, hw_params);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_any failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_set_access(*pcmp, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_set_access failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_set_format(*pcmp, hw_params, hwparams->format);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_set_format failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_set_channels(*pcmp, hw_params, hwparams->channels);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_set_channels failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_set_rate(*pcmp, hw_params, hwparams->rate, 0);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_set_rate failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_set_buffer_size(*pcmp, hw_params, hwparams->buffer_size);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_set_buffer_size failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params_set_period_size(*pcmp, hw_params, hwparams->period_size, 0);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_set_period_size failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
ret = snd_pcm_hw_params(*pcmp, hw_params);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
err_pcm_hw_params:
|
||
|
snd_pcm_close(*pcmp);
|
||
|
err_pcm_open:
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
static void rt_snd_pcm_close(snd_pcm_t *pcmp)
|
||
|
{
|
||
|
if (pcmp)
|
||
|
snd_pcm_close(pcmp);
|
||
|
}
|
||
|
|
||
|
static int rt_mixer_cset(const char *card_name, const char *str, const char *value)
|
||
|
{
|
||
|
int i, err;
|
||
|
static char card[64] = "default";
|
||
|
static snd_ctl_t *handle = NULL;
|
||
|
snd_ctl_elem_info_t *info;
|
||
|
snd_ctl_elem_id_t *id;
|
||
|
snd_ctl_elem_value_t *control;
|
||
|
snd_ctl_elem_info_alloca(&info);
|
||
|
snd_ctl_elem_id_alloca(&id);
|
||
|
snd_ctl_elem_value_alloca(&control);
|
||
|
|
||
|
i = snd_card_get_index(card_name);
|
||
|
if (i >= 0 && i < 32)
|
||
|
sprintf(card, "hw:%i", i);
|
||
|
else {
|
||
|
fprintf(stderr, "Invalid card number.\n");
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
if (snd_ctl_ascii_elem_id_parse(id, str)) {
|
||
|
fprintf(stderr, "Wrong control identifier: %s\n", str);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
if (handle == NULL && (err = snd_ctl_open(&handle, card, 0)) < 0) {
|
||
|
printf("Control %s open error: %s\n", card, snd_strerror(err));
|
||
|
return err;
|
||
|
}
|
||
|
snd_ctl_elem_info_set_id(info, id);
|
||
|
if ((err = snd_ctl_elem_info(handle, info)) < 0) {
|
||
|
printf("Cannot find the given element from control %s\n", card);
|
||
|
snd_ctl_close(handle);
|
||
|
handle = NULL;
|
||
|
return err;
|
||
|
}
|
||
|
snd_ctl_elem_info_get_id(info, id); /* FIXME: Remove it when hctl find works ok !!! */
|
||
|
|
||
|
snd_ctl_elem_value_set_id(control, id);
|
||
|
if ((err = snd_ctl_elem_read(handle, control)) < 0) {
|
||
|
snd_ctl_close(handle);
|
||
|
handle = NULL;
|
||
|
return err;
|
||
|
}
|
||
|
err = snd_ctl_ascii_value_parse(handle, control, info, value);
|
||
|
if (err < 0) {
|
||
|
snd_ctl_close(handle);
|
||
|
handle = NULL;
|
||
|
return err;
|
||
|
}
|
||
|
if ((err = snd_ctl_elem_write(handle, control)) < 0) {
|
||
|
snd_ctl_close(handle);
|
||
|
handle = NULL;
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
snd_ctl_close(handle);
|
||
|
handle = NULL;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* base.
|
||
|
* 1. card -> audiocodec
|
||
|
* 2. asound.conf -> default card should be audiocodec, and hooks to open the playback control
|
||
|
*
|
||
|
* process.
|
||
|
* 1. open pcm file
|
||
|
* 2. open and set hw_params audiocodec card
|
||
|
* 3. read pcm file data and write to audiocodec card pcm device
|
||
|
* 4. close audiocodec card
|
||
|
*
|
||
|
* ex.
|
||
|
* channel -> 1
|
||
|
* sample bit -> 16
|
||
|
* sample rate -> 16K
|
||
|
* period size -> 1024
|
||
|
* period count -> 4
|
||
|
*/
|
||
|
void *func_play_demo(void *arg)
|
||
|
{
|
||
|
int ret;
|
||
|
FILE *fp_play = NULL;
|
||
|
size_t fp_read_size;
|
||
|
size_t fp_read_num;
|
||
|
|
||
|
snd_pcm_t *play_handle = NULL;
|
||
|
char *data = NULL;
|
||
|
snd_pcm_sframes_t num_write;
|
||
|
snd_pcm_hw_params_t *hw_params = NULL;
|
||
|
|
||
|
struct rt_hwparams rt_hwparam = {
|
||
|
.channels = 1,
|
||
|
.format = SND_PCM_FORMAT_S16_LE,
|
||
|
.rate = 16000,
|
||
|
.buffer_size = 4096,
|
||
|
.period_size = 1024,
|
||
|
};
|
||
|
|
||
|
fp_play = fopen("play_mono_16k.pcm","rb");
|
||
|
if (!fp_play) {
|
||
|
printf("fopen _failed.\n");
|
||
|
goto err_fopen;
|
||
|
}
|
||
|
|
||
|
printf("play start\n");
|
||
|
|
||
|
ret = snd_pcm_hw_params_malloc(&hw_params);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_malloc failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params_malloc;
|
||
|
}
|
||
|
|
||
|
ret = rt_snd_pcm_open(&play_handle, "default", SND_PCM_STREAM_PLAYBACK, 0, hw_params, &rt_hwparam);
|
||
|
if (ret < 0) {
|
||
|
printf("rt_snd_pcm_open failed: %d.\n", ret);
|
||
|
goto err_rt_snd_pcm_open;
|
||
|
}
|
||
|
|
||
|
fp_read_size = snd_pcm_frames_to_bytes(play_handle, rt_hwparam.period_size);
|
||
|
data = (char *)malloc(fp_read_size);
|
||
|
if (data == NULL) {
|
||
|
printf("malloc failed\n");
|
||
|
goto err_malloc;
|
||
|
}
|
||
|
|
||
|
do {
|
||
|
fp_read_num = fread(data, 1, fp_read_size, fp_play);
|
||
|
if (fp_read_num < fp_read_size) {
|
||
|
printf("fread failed: %zu\n", fp_read_num);
|
||
|
goto err_pcm_writei;
|
||
|
}
|
||
|
|
||
|
num_write = snd_pcm_writei(play_handle, data, rt_hwparam.period_size);
|
||
|
if (num_write < 0) {
|
||
|
printf("snd_pcm_writei failed: %s\n", snd_strerror(num_write));
|
||
|
goto err_pcm_writei;
|
||
|
}
|
||
|
} while (!feof(fp_play));
|
||
|
|
||
|
snd_pcm_drain(play_handle);
|
||
|
|
||
|
err_pcm_writei:
|
||
|
if (data)
|
||
|
free(data);
|
||
|
err_malloc:
|
||
|
rt_snd_pcm_close(play_handle);
|
||
|
err_rt_snd_pcm_open:
|
||
|
snd_pcm_hw_params_free(hw_params);
|
||
|
err_pcm_hw_params_malloc:
|
||
|
if(fp_play)
|
||
|
fclose(fp_play);
|
||
|
err_fopen:
|
||
|
printf("play exit\n");
|
||
|
pthread_exit(NULL);
|
||
|
}
|
||
|
|
||
|
/* base.
|
||
|
* 1. card -> audiocodec
|
||
|
* 2. asound.conf -> default card should be audiocodec, and hooks to open the capture control
|
||
|
*
|
||
|
* process.
|
||
|
* 1. open new pcm file
|
||
|
* 2. open and set hw_params audiocodec card
|
||
|
* 4. read audiocodec card pcm device data and write to pcm file
|
||
|
* 5. close audiocodec card
|
||
|
*
|
||
|
* ex.
|
||
|
* channel -> 1
|
||
|
* sample bit -> 16
|
||
|
* sample rate -> 16K
|
||
|
* period size -> 1024
|
||
|
* period count -> 4
|
||
|
*/
|
||
|
void *func_capture_demo(void *arg)
|
||
|
{
|
||
|
int i, ret;
|
||
|
FILE *fp_capture = NULL;
|
||
|
size_t fp_write_size;
|
||
|
size_t fp_write_num;
|
||
|
|
||
|
snd_pcm_t *capture_handle = NULL;
|
||
|
char *data = NULL;
|
||
|
snd_pcm_sframes_t num_read;
|
||
|
snd_pcm_hw_params_t *hw_params = NULL;
|
||
|
|
||
|
struct rt_hwparams rt_hwparam = {
|
||
|
.channels = 1,
|
||
|
.format = SND_PCM_FORMAT_S16_LE,
|
||
|
.rate = 16000,
|
||
|
.buffer_size = 4096,
|
||
|
.period_size = 1024,
|
||
|
};
|
||
|
|
||
|
unsigned int capture_time = 500;
|
||
|
|
||
|
fp_capture = fopen("capture_mono_16k.pcm","wb");
|
||
|
if (!fp_capture) {
|
||
|
printf("fopen _failed.\n");
|
||
|
goto err_fopen;
|
||
|
}
|
||
|
|
||
|
printf("capture start\n");
|
||
|
|
||
|
ret = snd_pcm_hw_params_malloc(&hw_params);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_malloc failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params_malloc;
|
||
|
}
|
||
|
|
||
|
ret = rt_snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0, hw_params, &rt_hwparam);
|
||
|
if (ret < 0) {
|
||
|
printf("rt_snd_pcm_open failed: %d.\n", ret);
|
||
|
goto err_rt_snd_pcm_open;
|
||
|
}
|
||
|
|
||
|
fp_write_size = snd_pcm_frames_to_bytes(capture_handle, rt_hwparam.period_size);
|
||
|
data = (char *)malloc(fp_write_size);
|
||
|
if (data == NULL) {
|
||
|
printf("malloc failed\n");
|
||
|
goto err_malloc;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < capture_time; i++) {
|
||
|
num_read = snd_pcm_readi(capture_handle, data, rt_hwparam.period_size);
|
||
|
if (num_read < 0) {
|
||
|
printf("snd_pcm_readi failed: %s\n", snd_strerror(num_read));
|
||
|
goto err_pcm_readi;
|
||
|
}
|
||
|
|
||
|
fp_write_num = fwrite(data, 1, fp_write_size, fp_capture);
|
||
|
if (fp_write_num != fp_write_size) {
|
||
|
printf("fwrite failed: %zu\n", fp_write_num);
|
||
|
goto err_pcm_readi;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
snd_pcm_drain(capture_handle);
|
||
|
|
||
|
err_pcm_readi:
|
||
|
if (data)
|
||
|
free(data);
|
||
|
err_malloc:
|
||
|
err_rt_snd_pcm_open:
|
||
|
snd_pcm_hw_params_free(hw_params);
|
||
|
err_pcm_hw_params_malloc:
|
||
|
if(fp_capture)
|
||
|
fclose(fp_capture);
|
||
|
err_fopen:
|
||
|
printf("capture exit\n");
|
||
|
pthread_exit(NULL);
|
||
|
}
|
||
|
|
||
|
/* base.
|
||
|
* 1. card -> audiocodec & snddaudio0
|
||
|
* 2. card func -> audiocodec & snddaudio0 whit "tx hub mode" controls
|
||
|
* 3. asound.conf -> default card should be audiocodec, and hooks to open the playback control
|
||
|
*
|
||
|
* process.
|
||
|
* 1. open pcm file
|
||
|
* 2. set audiocodec & snddaudio0 card "tx hub mode" control to "On"
|
||
|
* 3. open and set hw_params audiocodec & snddaudio0 card
|
||
|
* 4. read pcm file data and write to audiocodec card pcm device
|
||
|
* 5. close audiocodec & snddaudio0 card
|
||
|
*
|
||
|
* ex.
|
||
|
* channel -> 1
|
||
|
* sample bit -> 16
|
||
|
* sample rate -> 16K
|
||
|
* period size -> 1024
|
||
|
* period count -> 4
|
||
|
*/
|
||
|
void *func_play_hub_demo(void *arg)
|
||
|
{
|
||
|
int ret;
|
||
|
FILE *fp_play = NULL;
|
||
|
size_t fp_read_size;
|
||
|
size_t fp_read_num;
|
||
|
|
||
|
snd_pcm_t *play_handle = NULL;
|
||
|
snd_pcm_t *play_hub_handle = NULL;
|
||
|
char *data = NULL;
|
||
|
snd_pcm_sframes_t num_write;
|
||
|
snd_pcm_hw_params_t *hw_params = NULL;
|
||
|
|
||
|
struct rt_hwparams rt_hwparam = {
|
||
|
.channels = 1,
|
||
|
.format = SND_PCM_FORMAT_S16_LE,
|
||
|
.rate = 16000,
|
||
|
.buffer_size = 4096,
|
||
|
.period_size = 1024,
|
||
|
};
|
||
|
|
||
|
fp_play = fopen("play_mono_16k.pcm","rb");
|
||
|
if (!fp_play) {
|
||
|
printf("fopen _failed.\n");
|
||
|
goto err_fopen;
|
||
|
}
|
||
|
|
||
|
printf("capture control set start\n");
|
||
|
ret = rt_mixer_cset("audiocodec", "name='tx hub mode'", "On");
|
||
|
if (ret < 0) {
|
||
|
printf("rt_mixer_cset failed: %d.\n", ret);
|
||
|
goto err_mixer_cset;
|
||
|
}
|
||
|
|
||
|
ret = rt_mixer_cset("snddaudio0", "name='tx hub mode'", "On");
|
||
|
if (ret < 0) {
|
||
|
printf("rt_mixer_cset failed: %d.\n", ret);
|
||
|
goto err_mixer_cset;
|
||
|
}
|
||
|
printf("capture control set exit\n");
|
||
|
|
||
|
printf("play start\n");
|
||
|
|
||
|
ret = snd_pcm_hw_params_malloc(&hw_params);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_malloc failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params_malloc;
|
||
|
}
|
||
|
|
||
|
ret = rt_snd_pcm_open(&play_handle, "default", SND_PCM_STREAM_PLAYBACK, 0, hw_params, &rt_hwparam);
|
||
|
if (ret < 0) {
|
||
|
printf("rt_snd_pcm_open failed: %d.\n", ret);
|
||
|
goto err_rt_snd_pcm_open;
|
||
|
}
|
||
|
|
||
|
ret = rt_snd_pcm_open(&play_hub_handle, "hw:snddaudio0,0", SND_PCM_STREAM_PLAYBACK, 0, hw_params, &rt_hwparam);
|
||
|
if (ret < 0) {
|
||
|
printf("rt_snd_pcm_open failed: %d.\n", ret);
|
||
|
goto err_rt_snd_pcm_open;
|
||
|
}
|
||
|
|
||
|
fp_read_size = snd_pcm_frames_to_bytes(play_handle, rt_hwparam.period_size);
|
||
|
data = (char *)malloc(fp_read_size);
|
||
|
if (data == NULL) {
|
||
|
printf("malloc failed\n");
|
||
|
goto err_malloc;
|
||
|
}
|
||
|
|
||
|
do {
|
||
|
fp_read_num = fread(data, 1, fp_read_size, fp_play);
|
||
|
if (fp_read_num < fp_read_size) {
|
||
|
printf("fread failed: %zu\n", fp_read_num);
|
||
|
goto err_pcm_writei;
|
||
|
}
|
||
|
|
||
|
num_write = snd_pcm_writei(play_handle, data, rt_hwparam.period_size);
|
||
|
if (num_write < 0) {
|
||
|
printf("snd_pcm_writei failed: %s\n", snd_strerror(num_write));
|
||
|
goto err_pcm_writei;
|
||
|
}
|
||
|
} while (!feof(fp_play));
|
||
|
|
||
|
snd_pcm_drain(play_handle);
|
||
|
|
||
|
err_pcm_writei:
|
||
|
if (data)
|
||
|
free(data);
|
||
|
err_malloc:
|
||
|
rt_snd_pcm_close(play_hub_handle);
|
||
|
rt_snd_pcm_close(play_handle);
|
||
|
err_rt_snd_pcm_open:
|
||
|
snd_pcm_hw_params_free(hw_params);
|
||
|
err_pcm_hw_params_malloc:
|
||
|
err_mixer_cset:
|
||
|
if(fp_play)
|
||
|
fclose(fp_play);
|
||
|
err_fopen:
|
||
|
printf("play exit\n");
|
||
|
pthread_exit(NULL);
|
||
|
}
|
||
|
|
||
|
/* base.
|
||
|
* 1. card -> audiocodec & snddaudio0
|
||
|
* 2. card func -> audiocodec & snddaudio0 whit "rx sync mode" controls
|
||
|
* 3. asound.conf -> default card should be multi audiocodec & snddaudio0, and hooks to open the capture control;
|
||
|
*
|
||
|
* process.
|
||
|
* 1. open pcm file
|
||
|
* 2. set audiocodec & snddaudio0 card "rx sync mode" control to "On"
|
||
|
* 3. open and set hw_params default card
|
||
|
* 4. read default card pcm device data and write to pcm file
|
||
|
* 5. close default card
|
||
|
*
|
||
|
* ex.
|
||
|
* channel -> 2
|
||
|
* sample bit -> 16
|
||
|
* sample rate -> 16K
|
||
|
* period size -> 1024
|
||
|
* period count -> 4
|
||
|
*/
|
||
|
void *func_capture_sync_demo(void *arg)
|
||
|
{
|
||
|
int i, ret;
|
||
|
FILE *fp_capture = NULL;
|
||
|
size_t fp_write_size;
|
||
|
size_t fp_write_num;
|
||
|
|
||
|
snd_pcm_t *capture_handle = NULL;
|
||
|
char *data = NULL;
|
||
|
snd_pcm_sframes_t num_read;
|
||
|
snd_pcm_hw_params_t *hw_params = NULL;
|
||
|
|
||
|
struct rt_hwparams rt_hwparam = {
|
||
|
.channels = 2,
|
||
|
.format = SND_PCM_FORMAT_S16_LE,
|
||
|
.rate = 16000,
|
||
|
.buffer_size = 4096,
|
||
|
.period_size = 1024,
|
||
|
};
|
||
|
|
||
|
unsigned int capture_time = 500;
|
||
|
|
||
|
fp_capture = fopen("capture_stereo_16k.pcm","wb");
|
||
|
if (!fp_capture) {
|
||
|
printf("fopen _failed.\n");
|
||
|
goto err_fopen;
|
||
|
}
|
||
|
|
||
|
printf("capture control set start\n");
|
||
|
ret = rt_mixer_cset("audiocodec", "name='rx sync mode'", "On");
|
||
|
if (ret < 0) {
|
||
|
printf("rt_mixer_cset failed: %d.\n", ret);
|
||
|
goto err_mixer_cset;
|
||
|
}
|
||
|
|
||
|
ret = rt_mixer_cset("snddaudio0", "name='rx sync mode'", "On");
|
||
|
if (ret < 0) {
|
||
|
printf("rt_mixer_cset failed: %d.\n", ret);
|
||
|
goto err_mixer_cset;
|
||
|
}
|
||
|
printf("capture control set exit\n");
|
||
|
|
||
|
printf("capture start\n");
|
||
|
|
||
|
ret = snd_pcm_hw_params_malloc(&hw_params);
|
||
|
if (ret < 0) {
|
||
|
printf("snd_pcm_hw_params_malloc failed: %d.\n", ret);
|
||
|
goto err_pcm_hw_params_malloc;
|
||
|
}
|
||
|
|
||
|
ret = rt_snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0, hw_params, &rt_hwparam);
|
||
|
if (ret < 0) {
|
||
|
printf("rt_snd_pcm_open failed: %d.\n", ret);
|
||
|
goto err_rt_snd_pcm_open;
|
||
|
}
|
||
|
|
||
|
fp_write_size = snd_pcm_frames_to_bytes(capture_handle, rt_hwparam.period_size);
|
||
|
data = (char *)malloc(fp_write_size);
|
||
|
if (data == NULL) {
|
||
|
printf("malloc failed\n");
|
||
|
goto err_malloc;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < capture_time; i++) {
|
||
|
num_read = snd_pcm_readi(capture_handle, data, rt_hwparam.period_size);
|
||
|
if (num_read < 0) {
|
||
|
printf("snd_pcm_readi failed: %s\n", snd_strerror(num_read));
|
||
|
goto err_pcm_readi;
|
||
|
}
|
||
|
|
||
|
fp_write_num = fwrite(data, 1, fp_write_size, fp_capture);
|
||
|
if (fp_write_num != fp_write_size) {
|
||
|
printf("fwrite failed: %zu\n", fp_write_num);
|
||
|
goto err_pcm_readi;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
snd_pcm_drain(capture_handle);
|
||
|
|
||
|
err_pcm_readi:
|
||
|
if (data)
|
||
|
free(data);
|
||
|
err_malloc:
|
||
|
err_rt_snd_pcm_open:
|
||
|
snd_pcm_hw_params_free(hw_params);
|
||
|
err_pcm_hw_params_malloc:
|
||
|
err_mixer_cset:
|
||
|
if(fp_capture)
|
||
|
fclose(fp_capture);
|
||
|
err_fopen:
|
||
|
printf("capture exit\n");
|
||
|
pthread_exit(NULL);
|
||
|
}
|