doubao_chat/apps/wifi_camera/wifi/rt_stream/tx_stream.c

244 lines
6.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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