#include "system/includes.h"//cbuf #include "sock_api/sock_api.h" #include "server/audio_server.h"//static const struct audio_vfs_ops #include "server/rt_stream_pkg.h"//head info .h #include "lwip/sockets.h"//struct sockaddr_in static struct { struct server *enc_server; //编码server u8 enc_volume; //录音音量 char *data_buf; //buf,存储录音数据 u32 buf_len; //buf长度 cbuffer_t record_cbuf; //cycle buf OS_SEM r_sem; } record_hdl = { .enc_volume = 100, .buf_len = 5 * 1024, }; #define __this (&record_hdl) #define DATA_BUF_SIZE 5*1024 struct __tx_talk { void *sock; u8 data_buf[DATA_BUF_SIZE]; int thread_pid; u32 recv_time; cbuffer_t cbuf_net_data; }; struct __tx_talk *tx_talk; //功 能:MIC驱动底层将调用该函数,将录音数据写进指定的文件中 //参 数:void *file:文件描述符 // void *data:data指针 // u32 len : data大小 //返回值:写入字节数 static int record_vfs_fwrite(void *file, void *data, u32 len) { cbuf_write(&__this->record_cbuf, data, len); os_sem_set(&__this->r_sem, 0); os_sem_post(&__this->r_sem); return len; } static int record_vfs_fclose(void *file) { return 0; } //录音文件操作方法集。传递给MIC底层驱动调用 static const struct audio_vfs_ops record_vfs_ops = { .fwrite = record_vfs_fwrite, .fclose = record_vfs_fclose, }; //功能:底层驱动回调函数 static void enc_server_event_handler(void *priv, int argc, int *argv) { switch (argv[0]) { case AUDIO_SERVER_EVENT_ERR: case AUDIO_SERVER_EVENT_END: break; case AUDIO_SERVER_EVENT_CURR_TIME: printf("play time : %d\n", argv[1]); break; default: break; } } //功 能:开启MIC数据采样 //参 数:int sample_rate:采样率(单位:Hz) // u32 msec :采样时间(单位:ms) //注意同一个MIC采样率保持一致 打断唤醒16000 static int mic_record_start(int sample_rate, u32 msec) { int err = -1; union audio_req req = {0}; //打开enc_server if (!__this->enc_server) { __this->enc_server = server_open("audio_server", "enc"); if (!__this->enc_server) { goto _mic_err_; } server_register_event_handler(__this->enc_server, NULL, enc_server_event_handler); } //申请数据存储buf __this->data_buf = (char *)malloc(__this->buf_len); if (__this->data_buf == NULL) { goto _mic_err_; } //初始化cycle_buf cbuf_init(&__this->record_cbuf, __this->data_buf, __this->buf_len); os_sem_create(&__this->r_sem, 0); //MIC数据采集配置 req.enc.cmd = AUDIO_ENC_OPEN; //命令 req.enc.channel = 1; //采样通道数目 req.enc.volume = __this->enc_volume; //录音音量 req.enc.output_buf = NULL; //缓存buf req.enc.output_buf_len = 8 * 1024; //缓存buf大小 req.enc.sample_rate = sample_rate; //采样率 req.enc.format = "pcm"; //录音数据格式 req.enc.frame_size = sample_rate / 25; //数据帧大小 req.enc.sample_source = "mic"; //采样源 req.enc.vfs_ops = &record_vfs_ops; //文件操作方法集 req.enc.msec = msec; //采样时间 //发送录音请求 err = server_request(__this->enc_server, AUDIO_REQ_ENC, &req); if (err) { goto _mic_err_; } return 0; _mic_err_: if (__this->enc_server) { server_close(__this->enc_server); __this->enc_server = NULL; } if (__this->data_buf) { free(__this->data_buf); __this->data_buf = NULL; } return -1; } //功 能:关闭MIC数据采样 //参 数:无 //返回值:无 void mic_record_stop(void) { union audio_req req = {0}; os_sem_post(&__this->r_sem); //关闭enc_server if (__this->enc_server) { req.enc.cmd = AUDIO_ENC_CLOSE; server_request(__this->enc_server, AUDIO_REQ_ENC, &req); server_close(__this->enc_server); __this->enc_server = NULL; } //释放buf if (__this->data_buf) { free(__this->data_buf); __this->data_buf = NULL; } //关闭数据接收线程 if (tx_talk->thread_pid) { puts("kill recv task"); thread_kill(&tx_talk->thread_pid, KILL_FORCE); } } void send_mic_data_handler(void *priv) { u8 read_buf[660] = {0}; //buf大小与 frame_size 相等 u32 rlen; mic_record_start(8000, 0); struct sockaddr_in dest_addr = {0}; dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr("192.168.1.1"); dest_addr.sin_port = htons(2231); static u32 v_seq = 0, a_seq = 0; struct frm_head frame_head = {0}; u32 frame_head_size = sizeof(struct frm_head); frame_head.type = PCM_TYPE_AUDIO ; while (1) { /* 收集够640个数据 */ os_sem_pend(&__this->r_sem, 0); cbuf_get_data_size(&__this->record_cbuf); os_sem_pend(&__this->r_sem, 0); cbuf_get_data_size(&__this->record_cbuf + 320); rlen = cbuf_read(&__this->record_cbuf, read_buf + frame_head_size, sizeof(read_buf) - frame_head_size); frame_head.seq = (a_seq ++); frame_head.payload_size = rlen; frame_head.frm_sz = rlen; frame_head.timestamp += 0; memcpy(read_buf, &frame_head, frame_head_size); sock_sendto(tx_talk->sock, read_buf, rlen + frame_head_size, 0, &dest_addr, sizeof(dest_addr)); } } void init_sock_receive_voice(void) { struct sockaddr_in dest_addr; int err; /* 初始化结构体 */ if (tx_talk != NULL) { printf("\nAPP not allow open again\n"); } tx_talk = calloc(sizeof(struct __tx_talk), 1); if (tx_talk == NULL) { printf("\nnot enough space\n"); } tx_talk->sock = sock_reg(AF_INET, SOCK_DGRAM, 0, NULL, NULL); if (tx_talk->sock == NULL) { printf("\n%s %d ->Error in socket()\n", __func__, __LINE__); } /* 绑定数据通道 */ dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); dest_addr.sin_port = htons(2231); err = sock_bind(tx_talk->sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)); if (err) { printf("%s %d->Error in bind(),errno=%d\n", __func__, __LINE__, errno); } /* 建立MIC数据线程 */ thread_fork("send_mic_data_handler", 25, 5 * 1024, 0, &tx_talk->thread_pid, send_mic_data_handler, NULL); }