/*
@file
@brief record demo for linux
@author taozhang9
@date 2016/05/27
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <alsa/asoundlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <pthread.h>
#include "formats.h"
#include "linuxrec.h"
#define DBG_ON 1
#if DBG_ON
#define dbg printf
#else
#define dbg
#endif
/* Do not change the sequence */
enum {
RECORD_STATE_CREATED, /* Init */
RECORD_STATE_CLOSING,
RECORD_STATE_READY, /* Opened */
RECORD_STATE_STOPPING, /* During Stop */
RECORD_STATE_RECORDING, /* Started */
};
#define SAMPLE_RATE 16000
#define SAMPLE_BIT_SIZE 16
#define FRAME_CNT 10
//#define BUF_COUNT 1
#define DEF_BUFF_TIME 500000
#define DEF_PERIOD_TIME 100000
#define DEFAULT_FORMAT \
{\
WAVE_FORMAT_PCM, \
1, \
16000, \
32000, \
2, \
16, \
sizeof(WAVEFORMATEX) \
}
#if 0
struct bufinfo {
char *data;
unsigned int bufsize;
};
#endif
static int show_xrun = 1;
static int start_record_internal(snd_pcm_t *pcm)
{
return snd_pcm_start(pcm);
}
static int stop_record_internal(snd_pcm_t *pcm)
{
return snd_pcm_drop(pcm);
}
static int is_stopped_internal(struct recorder *rec)
{
snd_pcm_state_t state;
state = snd_pcm_state((snd_pcm_t *)rec->wavein_hdl);
switch (state) {
case SND_PCM_STATE_RUNNING:
case SND_PCM_STATE_DRAINING:
return 0;
default: break;
}
return 1;
}
static int format_ms_to_alsa(const WAVEFORMATEX * wavfmt,
snd_pcm_format_t * format)
{
snd_pcm_format_t tmp;
tmp = snd_pcm_build_linear_format(wavfmt->wBitsPerSample,
wavfmt->wBitsPerSample, wavfmt->wBitsPerSample == 8 ? 1 : 0, 0);
if ( tmp == SND_PCM_FORMAT_UNKNOWN )
return -EINVAL;
*format = tmp;
return 0;
}
/* set hardware and software params */
static int set_hwparams(struct recorder * rec, const WAVEFORMATEX *wavfmt,
unsigned int buffertime, unsigned int periodtime)
{
snd_pcm_hw_params_t *params;
int err;
unsigned int rate;
snd_pcm_format_t format;
snd_pcm_uframes_t size;
snd_pcm_t *handle = (snd_pcm_t *)rec->wavein_hdl;
rec->buffer_time = buffertime;
rec->period_time = periodtime;
snd_pcm_hw_params_alloca(¶ms);
err = snd_pcm_hw_params_any(handle, params);
if (err < 0) {
dbg("Broken configuration for this PCM");
return err;
}
err = snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
dbg("Access type not available");
return err;
}
err = format_ms_to_alsa(wavfmt, &format);
if (err) {
dbg("Invalid format");
return - EINVAL;
}
err = snd_pcm_hw_params_set_format(handle, params, format);
if (err < 0) {
dbg("Sample format non available");
return err;
}
err = snd_pcm_hw_params_set_channels(handle, params, wavfmt->nChannels);
if (err < 0) {
dbg("Channels count non available");
return err;
}
rate = wavfmt->nSamplesPerSec;
err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0);
if (err < 0) {
dbg("Set rate failed");
return err;
}
if(rate != wavfmt->nSamplesPerSec) {
dbg("Rate mismatch");
return -EINVAL;
}
if (rec->buffer_time == 0 || rec->period_time == 0) {
err = snd_pcm_hw_params_get_buffer_time_max(params,
&rec->buffer_time, 0);
assert(err >= 0);
if (rec->buffer_time > 500000)
rec->buffer_time = 500000;
rec->period_time = rec->buffer_time / 4;
}
err = snd_pcm_hw_params_set_period_time_near(handle, params,
&rec->period_time, 0);
if (err < 0) {
dbg("set period time fail");
return err;
}
err = snd_pcm_hw_params_set_buffer_time_near(handle, params,
&rec->buffer_time, 0);
if (err < 0) {
dbg("set buffer time failed");
return err;
}
err = snd_pcm_hw_params_get_period_size(params, &size, 0);
if (err < 0) {
dbg("get period size fail");
return err;
}
rec->period_frames = size;
err = snd_pcm_hw_params_get_buffer_size(params, &size);
if (size == rec->period_frames) {
dbg("Can't use period equal to buffer size (%lu == %lu)",
size, (unsigned long)rec->period_frames);
return -EINVAL;
}
rec->buffer_frames = size;
rec->bits_per_frame = wavfmt->wBitsPerSample;
/* set to driver */
err = snd_pcm_hw_params(handle, params);
if (err < 0) {
dbg("Unable to install hw params:");
return err;
}
return 0;
}
static int set_swparams(struct recorder * rec)
{
int err;
snd_pcm_sw_params_t *swparams;
snd_pcm_t * handle = (snd_pcm_t*)(rec->wavein_hdl);
/* sw para */
snd_pcm_sw_params_alloca(&swparams);
err = snd_pcm_sw_params_current(handle, swparams);
if (err < 0) {
dbg("get current sw para fail");
return err;
}
err = snd_pcm_sw_params_set_avail_min(handle, swparams,
rec->period_frames);
if (err < 0) {
dbg("set avail min failed");
return err;
}
/* set a value bigger than the buffer frames to prevent the auto start.
* we use the snd_pcm_start to explicit start the pcm */
err = snd_pcm_sw_params_set_start_threshold(handle, swparams,
rec->buffer_frames * 2);
if (err < 0) {
dbg("set start threshold fail");
return err;
}
if ( (err = snd_pcm_sw_params(handle, swparams)) < 0) {
dbg("unable to install sw params:");
return err;
}
return 0;
}
static int set_params(struct recorder *rec, WAVEFORMATEX *fmt,
unsigned int buffertime, unsigned int periodtime)
{
int err;
WAVEFORMATEX defmt = DEFAULT_FORMAT;
if (fmt == NULL) {
fmt = &defmt;
}
err = set_hwparams(rec, fmt, buffertime, periodtime);
if (err)
return err;
err = set_swparams(rec);
if (err)
return err;
return 0;
}
/*
* Underrun and suspend recovery
*/
static int xrun_recovery(snd_pcm_t *handle, int err)
{
if (err == -EPIPE) { /* over-run */
if (show_xrun)
printf("!!!!!!overrun happend!!!!!!");
err = snd_pcm_prepare(handle);
if (err < 0) {
if (show_xrun)
printf("Can't recovery from overrun,"
"prepare failed: %s\n", snd_strerror(err));
return err;
}
return 0;
} else if (err == -ESTRPIPE) {
while ((err = snd_pcm_resume(handle)) == -EAGAIN)
usleep(200000); /* wait until the suspend flag is released */
if (err < 0) {
err = snd_pcm_prepare(handle);
if (err < 0) {
if (show_xrun)
printf("Can't recovery from suspend,"
"prepare failed: %s\n", snd_strerror(err));
return err;
}
}
return 0;
}
return err;
}
static ssize_t pcm_read(struct recorder *rec, size_t rcount)
{
ssize_t r;
size_t count = rcount;
char *data;
snd_pcm_t *handle = (snd_pcm_t *)rec->wavein_hdl;
if(!handle)
return -EINVAL;
data = rec->audiobuf;
while (count > 0) {
r = snd_pcm_readi(handle, data, count);
if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
snd_pcm_wait(handle, 100);
} else if (r < 0) {
if(xrun_recovery(handle, r) < 0) {
return -1;
}
}
if (r > 0) {
count -= r;
data += r * rec->bits_per_frame / 8;
}
}
return rcount;
}
static void * record_thread_proc(void * para)
{
struct recorder * rec = (struct recorder *) para;
size_t frames, bytes;
sigset_t mask, oldmask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
pthread_sigmask(SIG_BLOCK, &mask, &oldmask);
while(1) {
frames = rec->period_frames;
bytes = frames * rec->bits_per_frame / 8;
/* closing, exit the thread */
if (rec->state == RECORD_STATE_CLOSING)
break;
if(rec->state < RECORD_STATE_RECORDING)
usleep(100000);
if (pcm_read(rec, frames) != frames) {
return NULL;
}
if (rec->on_data_ind)
rec->on_data_ind(rec->audiobuf, bytes,
rec->user_cb_para);
}
return rec;
}
static int create_record_thread(void * para, pthread_t * tidp)
{
int err;
err = pthread_create(tidp, NULL, record_thread_proc, (void *)para);
if (err != 0)
return err;
ret
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
1、通过文件检索可以将固定的目录下的三种类型的图片和音乐给检索出来,然后再利用libjpeg库和libpng库来对jpeg图片和png图片进行解码,再通过直接操作framebuffer来将图片显示在LCD屏上,还可以使用触摸屏来切换图片。而播放音乐就要移植madplay库并使用当中的命令来播放音乐,也可以使用触摸屏来切换音乐。 2、拍照功能,利用V4L2来实现采集一帧的图像并把它显示在LCD屏上。 3、语言交互功能,首先在客户端实现录音功能,并将录制的音频数据通过socket传输到服务端中,服务端就先进行语法构建然后再进行语法识别,最后将识别的结果保存在xml文件中,再通过socket将xml文件传输到客户端中,客户端再对这个文件进行解析,并得到识别的id号,然后再根据id进行相应的操作,如操作上述两个功能。
资源推荐
资源详情
资源评论
收起资源包目录
AITalk_demo.7z (93个子文件)
AITalk_demo
gec210
voicectl.c 4KB
head4audio.h 3KB
voicectl 27KB
common.c~ 9KB
camera.c 10KB
head4sock.h 1KB
common.c 10KB
common.h 3KB
jpeg
jmorecfg.h 12KB
jconfig.h 2KB
jpeglib.h 47KB
jerror.h 14KB
libjpeg.so.8.3.0 999KB
project.c~ 3KB
libz.so.1.2.8 137KB
voicectl.c~ 4KB
project.c 4KB
Makefile 420B
Makefile~ 410B
libvnet.so 7KB
x86
bin
pcm
cmd.pcm 94KB
result.xml 313B
.msc
msc.cfg 746B
res
asr
common.jet 9.33MB
cmd.bnf~ 230B
cmd.bnf 230B
msc
msc.cfg 686B
res
asr
common.jet 9.33MB
asr_record_demo 71KB
examples
asr_record_demo
linuxrec.o 22KB
asr_record_demo.c~ 11KB
speech_recognizer.o 31KB
linuxrec.h 3KB
linuxrec.c 14KB
formats.h 399B
asr_record_demo.c 11KB
asr_record_demo.o 36KB
speech_recognizer.h 2KB
msc
b1deac5e03bfa89bb13c55cbc3227e49
msc.cfg 0B
Makefile 589B
speech_recognizer.c 9KB
.DS_Store 6KB
lib
libasound.so 1.19MB
libmsc.so 3.03MB
inc
qisr.h 10KB
msp_errors.h 35KB
msp_cmn.h 11KB
msp_types.h 4KB
alsa
pcm_plugin.h 7KB
version.h 499B
timer.h 11KB
mixer.h 14KB
pcm_rate.h 4KB
seq_event.h 11KB
asoundlib.h 2KB
pcm_old.h 20KB
control.h 26KB
iatomic.h 28KB
pcm.h 50KB
seq.h 32KB
control_external.h 8KB
sound
sscape_ioctl.h 368B
sb16_csp.h 4KB
ainstr_iw.h 11KB
type_compat.h 907B
asound_fm.h 4KB
ainstr_fm.h 3KB
ainstr_gf1.h 6KB
hdsp.h 3KB
emu10k1.h 15KB
ainstr_simple.h 5KB
conf.h 8KB
pcm_external.h 2KB
alisp.h 2KB
rawmidi.h 7KB
input.h 3KB
mixer_abst.h 4KB
hwdep.h 7KB
global.h 5KB
conv.h 2KB
output.h 3KB
seq_midi_event.h 2KB
pcm_extplug.h 6KB
instr.h 7KB
asoundef.h 18KB
error.h 3KB
pcm_ioplug.h 7KB
seqmid.h 14KB
libasound.so.2.0.0 1.19MB
libasound.so.2 1.19MB
libmsc64.so 3.16MB
Makefile 72B
Makefile~ 94B
共 93 条
- 1
资源评论
SetLaVie
- 粉丝: 9
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功