#include "intercom.h" #include "osal/string.h" #include "custom_mem/custom_mem.h" #include "stream_frame.h" #include "osal/task.h" #include "osal/work.h" #include "lwip/api.h" #include "lwip/sockets.h" #include "lib/net/eloop/eloop.h" #include "netif/ethernetif.h" #include "syscfg.h" #include "dev/audio/components/vad/auvad.h" #include "hal/gpio.h" #include "adpcm_code.h" #include "keyWork.h" #include "keyScan.h" #include "hal/timer_device.h" #define PIN_SPK_MUTE PA_7 #define MUTE_SPEAKER 0 #define SERVER_RECORD 0 #define SERVER_RECORD_NODE_NUM 70 #define DUPLEX_TYPE HALF_DUPLEX #define PLC_PROCESS 1 #define CHANGE_PLAY_SPEED 1 #define SAMPLERATE 8000 #define INTERCOM_SERVER 1 #define INTERCOM_CLIENT 0 #define INTERCOM_PORT 5008 #define REDUNDANCY_NUM 2 #define CODE_BPS 4 #define DECODED_DATA_LEN 160 #define ENCODED_BUF_NUM 15 #define SUBLIST_NUM 60 #define ENCODED_DATA_BYTE ((DECODED_DATA_LEN/8*CODE_BPS+4)*(1+REDUNDANCY_NUM)+4) #define RESERVE 14 #define ENCODED_BUF_BYTE (ENCODED_DATA_BYTE+RESERVE) #define ENCODED_RINGBUF_LEN (ENCODED_BUF_BYTE*ENCODED_BUF_NUM) #define SOFTBUF_LEN (ENCODED_DATA_BYTE*SUBLIST_NUM) #define CODE_MODE 20 #define NODE_DATA_LEN ENCODED_DATA_BYTE #define NUM_OF_FRAME 1 #define LOSE_STATISTICAL 0 TYPE_INTERCOM_STRUCT *intercom = NULL; audio_node audio_node_src[SOFTBUF_LEN/NODE_DATA_LEN] __attribute__ ((aligned(4),section(".psram.src"))); sublist sublist_src[SUBLIST_NUM] __attribute__ ((aligned(4),section(".psram.src"))); ringbuf_manage ringbuf_mana[ENCODED_BUF_NUM] __attribute__ ((aligned(4),section(".psram.src"))); struct list_head sublist_head; struct list_head ringbuf_manage_src; struct list_head ringbuf_manage_use; struct list_head *manage_cur_push; struct list_head *manage_cur_pop; TYPE_RINGBUF *encoded_ringbuf = NULL; char *sort_buf = NULL; uint32 del_node_num = 0; uint32 g_intercom_start = 0; struct os_mutex send_mutex; struct os_mutex list_mutex; static struct os_semaphore encode_sem; static struct os_semaphore decode_sem; struct os_task intercom_server_handle_task; struct os_task intercom_client_handle_task; volatile uint16 play_sort = 0; uint16 g_current_sort = 1; uint32_t g_numofcached = 0; uint8 g_send_sequence = 0; uint32 g_send_sort = 0; uint32 g_s_identify_num = 0; int now_dac_filter_type = 0; static struct data_structure *current_adc_data = NULL; static struct data_structure *current_dac_data = NULL; #if DEALY_ADJUSTMENT extern uint8 txmode; extern uint8_t send_mode; #endif uint32 playofwait = 30; volatile uint8 send_start_flag = 0; //发送端缓存到一定数量再开启发送; uint8 play_start_flag = 2; //接收到缓存到一定数量再开始解码和播放; uint8 intercom_encode_flag = 0x03; //编码控制开关;bit0:手动控制,bit1:软件控制; #if INTERCOM_SERVER uint8 g_transfer_mode = RECV_MODE; #elif INTERCOM_CLIENT uint8 g_transfer_mode = SEND_MODE; #endif uint8 g_switch_recv_success = 1; uint8 g_code_sema_init = 0; AdpcmEncoder *Enc_Inst = NULL; AdpcmDecoder *Dec_Inst = NULL; extern struct sonic_process_priv *sonic_priv; void intercom_server_handle(void *d); void intercom_client_handle(void *d); void intercom_recv(void *d); void intercom_encoded_handle(void *d); void intercom_decoded_handle(void *d); void retransfer_check(void *d); int intercom_server_init(void); int intercom_client_init(void); void intercom_send(uint8 num); void lose_packet_check(void); static struct os_timer ctl_timer; void decode_sem_up(uint32 *args); void intercom_init(void) { #if INTERCOM_SERVER intercom_server_init(); #elif INTERCOM_CLIENT intercom_client_init(); #endif } static void intercom_struct_init(void) { for(uint8 i=0; i<4; i++) { *((&intercom->udp_sfd)+i) = -1; } } static void srcList_init(void) { for(uint32 i=0; i<(SOFTBUF_LEN/NODE_DATA_LEN); i++) { audio_node_src[i].buf_addr = (uint8*)(sort_buf+(NODE_DATA_LEN*i)); list_add_tail((struct list_head *)&audio_node_src[i].list,(struct list_head *)&intercom->srcList_head); } } static void sublist_init(void) { for(uint32 i=0; idata = (uint8*)intercom_zalloc( (encoded_ringbuf->size)*sizeof(uint8) ); if(!(encoded_ringbuf->data)) { os_printf("malloc encode_ringbuf->data err\n"); return -1; } sort_buf = (char*)intercom_zalloc(SOFTBUF_LEN* sizeof(uint8)); if(!sort_buf) { os_printf("malloc sort_buf err\n"); return -1; } INIT_LIST_HEAD((struct list_head *)&intercom->srcList_head); INIT_LIST_HEAD((struct list_head *)&intercom->checkList_head); INIT_LIST_HEAD((struct list_head *)&intercom->useList_head); INIT_LIST_HEAD((struct list_head *)&sublist_head); INIT_LIST_HEAD((struct list_head *)&ringbuf_manage_src); INIT_LIST_HEAD((struct list_head *)&ringbuf_manage_use); srcList_init(); sublist_init(); ringbuf_manage_init(); os_printf("intercom_room_init succes\n"); return 0; } static void close_socket(void) { for(uint8 i=0; i<4; i++) { if(*((&intercom->udp_sfd)+i) != -1) close(*((&intercom->udp_sfd)+i)); } } static void free_room(void) { if(encoded_ringbuf->data) { intercom_free(encoded_ringbuf->data); encoded_ringbuf->data = NULL; } ringbuf_del(encoded_ringbuf); if(sort_buf) { intercom_free(sort_buf); sort_buf = NULL; } } uint32_t intercom_push_key(struct key_callback_list_s *callback_list,uint32_t keyvalue,uint32_t extern_value) { if( (keyvalue>>8) != AD_PRESS) return 0; uint32 key_val = (keyvalue & 0xff); if((key_val == KEY_EVENT_DOWN) || (key_val == KEY_EVENT_LDOWN) || (key_val == KEY_EVENT_REPEAT)) { g_transfer_mode = SEND_MODE; } else if((key_val == KEY_EVENT_SUP) || (key_val == KEY_EVENT_LUP)) { g_transfer_mode = RECV_MODE; } return 0; } int intercom_server_init(void) { int time_out = CODE_MODE*2; intercom = (TYPE_INTERCOM_STRUCT*)custom_malloc(sizeof(TYPE_INTERCOM_STRUCT)); if(!intercom) goto intercom_server_init_err; intercom_struct_init(); intercom->udp_sfd = socket(AF_INET,SOCK_DGRAM,0); intercom->ack_sfd = socket(AF_INET,SOCK_DGRAM,0); #if DUPLEX_TYPE == HALF_DUPLEX add_keycallback(intercom_push_key,NULL); #endif if((intercom->udp_sfd==-1) || (intercom->ack_sfd==-1)) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_server_init_err; } if(setsockopt(intercom->udp_sfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&time_out,sizeof(int)) == -1) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_server_init_err; } OS_TASK_INIT("intercom_server_handle", &intercom_server_handle_task, intercom_server_handle, NULL, OS_TASK_PRIORITY_NORMAL, 1024); return 0; intercom_server_init_err: close_socket(); if(intercom) custom_free(intercom); intercom = NULL; return -1; } int intercom_client_init(void) { intercom = (TYPE_INTERCOM_STRUCT*)custom_malloc(sizeof(TYPE_INTERCOM_STRUCT)); if(!intercom) goto intercom_client_init_err; intercom_struct_init(); intercom->udp_cfd = socket(AF_INET,SOCK_DGRAM,0); intercom->ack_cfd = socket(AF_INET,SOCK_DGRAM,0); if((intercom->udp_cfd==-1) || (intercom->ack_cfd==-1)) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_client_init_err; } // #if DUPLEX_TYPE == FULL_DUPLEX int time_out = CODE_MODE*2; if(setsockopt(intercom->udp_cfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&time_out,sizeof(int)) == -1) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_client_init_err; } // #endif OS_TASK_INIT("intercom_client_handle", &intercom_client_handle_task, intercom_client_handle, NULL, OS_TASK_PRIORITY_NORMAL, 1024); return 0; intercom_client_init_err: close_socket(); if(intercom) custom_free(intercom); intercom = NULL; return -1; } static void close_intercom_stream(void) { for(uint8 i=0; i<2; i++) { if(*((&intercom->recv_s)+i)) close_stream((stream*)*((&intercom->recv_s)+i)); } } static int opcode_func_r(stream *s,void *priv,int opcode) { int res = 0; switch(opcode) { case STREAM_OPEN_ENTER: break; case STREAM_OPEN_EXIT: { enable_stream(s,1); } break; case STREAM_OPEN_FAIL: break; default: //默认都返回成功 break; } return res; } static uint32_t get_sound_data_len(void *data) { struct data_structure *d = (struct data_structure *)data; return (uint32_t)d->priv; } static uint32_t set_sound_data_len(void *data,uint32_t len) { struct data_structure *d = (struct data_structure *)data; d->priv = (void*)len; return len; } static stream_ops_func stream_sound_ops = { .get_data_len = get_sound_data_len, .set_data_len = set_sound_data_len, }; static int opcode_func_s(stream *s,void *priv,int opcode) { static uint8 *audio_buf = NULL; int res = 0; switch(opcode) { case STREAM_OPEN_ENTER: break; case STREAM_OPEN_EXIT: { audio_buf = os_malloc(8 * ((DECODED_DATA_LEN+10)*2)); if(audio_buf) { stream_data_dis_mem_custom(s); } streamSrc_bind_streamDest(s,R_SONIC_PROCESS); #if SERVER_RECORD && INTERCOM_SERVER streamSrc_bind_streamDest(s,R_INTERMEDIATE_DATA); #endif } break; case STREAM_OPEN_FAIL: break; case STREAM_FILTER_DATA: break; case STREAM_DATA_DIS: { struct data_structure *data = (struct data_structure *)priv; int data_num = (int)data->priv; data->ops = &stream_sound_ops; data->data = audio_buf + data_num*((DECODED_DATA_LEN+10)*2); } break; case STREAM_DATA_FREE: break; case STREAM_DATA_DESTORY: { if(audio_buf) os_free(audio_buf); } break; //数据发送完成,可以选择唤醒对应的任务 case STREAM_RECV_DATA_FINISH: break; default: //默认都返回成功 break; } return res; } #if SERVER_RECORD && INTERCOM_SERVER static int opcode_func_record_s(stream *s,void *priv,int opcode) { static uint8 *audio_buf = NULL; int res = 0; switch(opcode) { case STREAM_OPEN_ENTER: break; case STREAM_OPEN_EXIT: { audio_buf = os_malloc_psram( SERVER_RECORD_NODE_NUM* ((DECODED_DATA_LEN+10)*2)); if(audio_buf) { stream_data_dis_mem_custom(s); } // streamSrc_bind_streamDest(s,R_SPEAKER); streamSrc_bind_streamDest(s,R_AT_AVI_AUDIO); streamSrc_bind_streamDest(s,R_AT_SAVE_AUDIO); } break; case STREAM_OPEN_FAIL: break; case STREAM_FILTER_DATA: break; case STREAM_DATA_DIS: { struct data_structure *data = (struct data_structure *)priv; int data_num = (int)data->priv; data->ops = &stream_sound_ops; data->data = audio_buf + data_num*((DECODED_DATA_LEN+10)*2); } break; case STREAM_DATA_FREE: { } break; //数据发送完成,可以选择唤醒对应的任务 case STREAM_RECV_DATA_FINISH: break; default: //默认都返回成功 break; } return res; } void intercom_record_thread(void *d) { int flen = 0; int16 *send_record_stream_buf = NULL; struct data_structure *get_f_inter_r = NULL; struct data_structure *get_f_inter_s = NULL; stream* s_inter_s = NULL; stream* r_inter_s = NULL; uint8_t *buf = NULL; int ret ; uint32_t count = 0; uint32_t delay_count = 0; static uint32_t last_timestemp = 0; static uint32_t cur_timestemp = 0; s_inter_s = open_stream_available(S_INTERMEDIATE_DATA,SERVER_RECORD_NODE_NUM,0,opcode_func_record_s,NULL); r_inter_s = open_stream_available(R_INTERMEDIATE_DATA,0,SERVER_RECORD_NODE_NUM,opcode_func_r,NULL); if(!s_inter_s || !r_inter_s) { os_printf("open stream err\n"); goto intercom_record_end; } while(1) { get_f_inter_r = recv_real_data(r_inter_s); if(get_f_inter_r) { get_f_inter_s = get_src_data_f(s_inter_s); if(get_f_inter_s) { count++; delay_count = 0; send_record_stream_buf = get_stream_real_data(get_f_inter_s); buf = (uint8_t*)get_stream_real_data(get_f_inter_r); flen = get_stream_real_data_len(get_f_inter_r); os_memcpy(send_record_stream_buf,buf,flen); set_stream_real_data_len(get_f_inter_s,flen); set_stream_data_time(get_f_inter_s,get_f_inter_r->timestamp); cur_timestemp = get_f_inter_r->timestamp; if((cur_timestemp > last_timestemp) && (last_timestemp != 0)) { // os_printf("audio sleep:%d ms CUR:%d LAST:%d\n",(cur_timestemp-last_timestemp),cur_timestemp,last_timestemp); } ret = send_data_to_stream(get_f_inter_s); last_timestemp = cur_timestemp; free_data(get_f_inter_r); get_f_inter_r = NULL; }else { free_data(get_f_inter_r); os_sleep_ms(1); os_printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); //节点数量不足,不能保证肯定能获取到节点 } }else{ delay_count++; os_sleep_ms(1); // printf("M"); if(delay_count == 90){ //printf("!"); //os_printf("================audio reset diff time==============\n"); delay_count = 0; count = 0; } } } intercom_record_end: if(get_f_inter_s) { force_del_data(get_f_inter_s); } if(get_f_inter_r) { free_data(get_f_inter_r); } if(r_inter_s) { close_stream(r_inter_s); } if(s_inter_s) { close_stream(s_inter_s); } } #endif void intercom_server_handle(void *d) { socklen_t addrlen = sizeof(struct sockaddr_in); uint32_t ipaddr; int err = -1; if(sys_cfgs.wifi_mode == WIFI_MODE_STA) { do{ ipaddr = lwip_netif_get_ip2("w0").addr; os_sleep_ms(100); }while((ipaddr&0xff000000) == 0x1000000); } for(char i=0; i<2; i++) { (*((&intercom->udp_s_addr)+i)).sin_family = AF_INET; (*((&intercom->udp_s_addr)+i)).sin_port = htons(INTERCOM_PORT + i); (*((&intercom->udp_s_addr)+i)).sin_addr.s_addr = 0; err = bind(*((&intercom->udp_sfd)+i), (struct sockaddr *)((&intercom->udp_s_addr)+i), addrlen); if(err == -1) { os_printf("\nerr:%s %d %d",__FUNCTION__,__LINE__,i); goto intercom_server_handle; } } for(char i=0; i<2; i++) { (*((&intercom->udp_c_addr)+i)).sin_family = AF_INET; (*((&intercom->udp_c_addr)+i)).sin_port = htons(INTERCOM_PORT + i); (*((&intercom->udp_c_addr)+i)).sin_addr.s_addr = inet_addr("192.168.1.100"); } err = intercom_room_init(); if(err == -1) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_server_handle; } intercom->recv_s = open_stream_available(R_INTERCOM_AUDIO, 0, 8, opcode_func_r, NULL); intercom->send_s = open_stream_available(S_INTERCOM_AUDIO, 8, 0, opcode_func_s, NULL); if( (!intercom->recv_s) || (!intercom->send_s) ) { os_printf("\nopen stream R_INTERCOM_AUDIO err"); goto intercom_server_handle; } Enc_Inst = adpcm_encoder_create(SAMPLERATE,0,0,DECODED_DATA_LEN,REDUNDANCY_NUM); Dec_Inst = adpcm_decoder_create(DECODED_DATA_LEN,REDUNDANCY_NUM); os_mutex_init(&send_mutex); os_mutex_init(&list_mutex); os_sema_init(&encode_sem, 0); os_sema_init(&decode_sem, 0); g_code_sema_init = 1; #if MUTE_SPEAKER == 1 gpio_set_mode(PIN_SPK_MUTE, GPIO_PULL_NONE, GPIO_PULL_LEVEL_NONE); gpio_set_dir(PIN_SPK_MUTE, GPIO_DIR_OUTPUT); #endif OS_TASK_INIT("intercom_encoded_handle", &intercom->encoded_task, intercom_encoded_handle, &encode_sem, OS_TASK_PRIORITY_NORMAL-3, 4096); OS_TASK_INIT("intercom_decoded_handle", &intercom->decoded_task, intercom_decoded_handle, &decode_sem, OS_TASK_PRIORITY_NORMAL-3, 2048); OS_TASK_INIT("intercom_recv", &intercom->recv_task, intercom_recv, NULL, OS_TASK_PRIORITY_NORMAL+1, 1024); OS_TASK_INIT("retransfer_check", &intercom->retransfer_task, retransfer_check, NULL, OS_TASK_PRIORITY_NORMAL-1, 1024); #if SERVER_RECORD && INTERCOM_SERVER OS_TASK_INIT("intercom_record_thread", &intercom->record_task, intercom_record_thread, NULL, OS_TASK_PRIORITY_NORMAL, 1024); #endif os_timer_init(&ctl_timer, (os_timer_func_t)decode_sem_up, OS_TIMER_MODE_PERIODIC, &ctl_timer); os_timer_start(&ctl_timer, CODE_MODE); return; intercom_server_handle: close_socket(); close_intercom_stream(); free_room(); if(intercom) { custom_free(intercom); intercom = NULL; } return; } void intercom_client_handle(void *d) { socklen_t addrlen = sizeof(struct sockaddr_in); int err = -1; uint32_t ipaddr; if(sys_cfgs.wifi_mode == WIFI_MODE_STA) { do{ ipaddr = lwip_netif_get_ip2("w0").addr; os_sleep_ms(100); }while((ipaddr&0xff000000) == 0x1000000); } for(char i=0; i<2; i++) { (*((&intercom->udp_c_addr)+i)).sin_family = AF_INET; (*((&intercom->udp_c_addr)+i)).sin_port = htons(INTERCOM_PORT + i); (*((&intercom->udp_c_addr)+i)).sin_addr.s_addr = 0; err = bind(*((&intercom->udp_cfd)+i), (struct sockaddr *)(&(intercom->udp_c_addr)+i), addrlen); if(err == -1) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_client_handle; } } for(char i=0; i<2; i++) { (*((&intercom->udp_s_addr)+i)).sin_family = AF_INET; (*((&intercom->udp_s_addr)+i)).sin_port = htons(INTERCOM_PORT + i); (*((&intercom->udp_s_addr)+i)).sin_addr.s_addr = inet_addr("192.168.1.1"); } err = intercom_room_init(); if(err == -1) { os_printf("\nerr:%s %d",__FUNCTION__,__LINE__); goto intercom_client_handle; } intercom->recv_s = open_stream_available(R_INTERCOM_AUDIO, 0, 8, opcode_func_r, NULL); intercom->send_s = open_stream_available(S_INTERCOM_AUDIO, 8, 0, opcode_func_s, NULL); if( (!intercom->recv_s) || (!intercom->send_s) ) { os_printf("\nopen stream R_INTERCOM_AUDIO err"); goto intercom_client_handle; } Enc_Inst = adpcm_encoder_create(SAMPLERATE,0,0,DECODED_DATA_LEN,REDUNDANCY_NUM); Dec_Inst = adpcm_decoder_create(DECODED_DATA_LEN,REDUNDANCY_NUM); os_mutex_init(&send_mutex); os_mutex_init(&list_mutex); os_sema_init(&encode_sem, 0); os_sema_init(&decode_sem, 0); g_code_sema_init = 1; #if MUTE_SPEAKER == 1 gpio_set_mode(PIN_SPK_MUTE, GPIO_PULL_NONE, GPIO_PULL_LEVEL_NONE); gpio_set_dir(PIN_SPK_MUTE, GPIO_DIR_OUTPUT); #endif OS_TASK_INIT("intercom_encoded_handle", &intercom->encoded_task, intercom_encoded_handle, &encode_sem, OS_TASK_PRIORITY_NORMAL-3, 4096); OS_TASK_INIT("intercom_decoded_handle", &intercom->decoded_task, intercom_decoded_handle, &decode_sem, OS_TASK_PRIORITY_NORMAL-3, 2048); OS_TASK_INIT("intercom_recv", &intercom->recv_task, intercom_recv, NULL, OS_TASK_PRIORITY_NORMAL+1, 1024); OS_TASK_INIT("retransfer_check", &intercom->retransfer_task, retransfer_check, NULL, OS_TASK_PRIORITY_NORMAL-1, 1024); os_timer_init(&ctl_timer, (os_timer_func_t)decode_sem_up, OS_TIMER_MODE_PERIODIC, &ctl_timer); os_timer_start(&ctl_timer, CODE_MODE); return; intercom_client_handle: close_socket(); close_intercom_stream(); free_room(); if(intercom) { custom_free(intercom); intercom = NULL; } return; } int get_audio_sublist_count(volatile struct list_head *head) { int count = 0; struct list_head *list_n = (struct list_head *)head; int ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) { return 0; } while(list_n->next != head) { list_n = list_n->next; count++; if(count>SUBLIST_NUM) { count = 0; break; } } os_mutex_unlock(&list_mutex); return count; } int get_audio_node_count(struct list_head *head) { int count = 0; struct list_head *list_n = (struct list_head *)head; while(list_n->next != head) { list_n = list_n->next; count++; if(count>(SOFTBUF_LEN/NODE_DATA_LEN)) { count = 0; break; } } return count; } int get_ringbuf_manage_count() { int count = 0; struct list_head *list_n = (struct list_head *)manage_cur_pop; struct list_head *head = (struct list_head *)manage_cur_push; while(list_n != head) { list_n = list_n->next; count++; if(count>(ENCODED_BUF_NUM)) { count = 0; break; } } return count; } static struct list_head *get_audio_sublist(struct list_head *head) { int ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return 0; if(list_empty_careful((const struct list_head *)&sublist_head)){ os_mutex_unlock(&list_mutex); os_printf("sublist_head empty\n"); return 0; } list_move_tail((struct list_head *)sublist_head.next,(struct list_head *)head); os_mutex_unlock(&list_mutex); return head->prev; } static struct list_head *get_audio_node(volatile struct list_head *head, uint32 node_num) { int ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return 0; if(get_audio_node_count((struct list_head *)&intercom->srcList_head) < node_num){ os_mutex_unlock(&list_mutex); os_printf("srcList empty\n"); return 0; } for(uint32 i=0; isrcList_head.next,(struct list_head *)head); os_mutex_unlock(&list_mutex); return head->next; } static void del_ringbuf_manage() { list_move_tail((struct list_head *)ringbuf_manage_use.next,(struct list_head*)&ringbuf_manage_src); os_mutex_unlock(&list_mutex); } static struct list_head *get_ringbuf_manage(uint8 grab) { if(list_empty_careful((const struct list_head *)&ringbuf_manage_src)) { if(grab) list_move_tail((struct list_head *)ringbuf_manage_use.next,(struct list_head *)&ringbuf_manage_use); else { return 0; } } else list_move_tail((struct list_head *)ringbuf_manage_src.next,(struct list_head *)&ringbuf_manage_use); return ringbuf_manage_use.prev; } static void clear_ringbuf_manage_use(void) { ringbuf_manage_use.next->prev = ringbuf_manage_src.prev; ringbuf_manage_use.prev->next = (struct list_head*)(&(ringbuf_manage_src)); ringbuf_manage_src.prev->next = ringbuf_manage_use.next; ringbuf_manage_src.prev = ringbuf_manage_use.prev; ringbuf_manage_use.next = (struct list_head*)(&(ringbuf_manage_use)); ringbuf_manage_use.prev = (struct list_head*)(&(ringbuf_manage_use)); } static void *get_audio_addr(struct list_head *list) { audio_node *audio_n; audio_n = list_entry((struct list_head *)list,audio_node,list); return audio_n->buf_addr; } static void *get_ringbuf_manage_addr(struct list_head *list) { ringbuf_manage *ringbuf_mana; ringbuf_mana = list_entry((struct list_head *)list,ringbuf_manage,list); return ringbuf_mana->buf_addr; } static void del_audio_node(volatile struct list_head *del) { del->next->prev = intercom->srcList_head.prev; del->prev->next = (struct list_head*)(&(intercom->srcList_head)); intercom->srcList_head.prev->next = del->next; intercom->srcList_head.prev = del->prev; del->next = (struct list_head *)del; del->prev = (struct list_head *)del; } static void del_audio_sublist(volatile struct list_head *del) { int ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return; sublist *sublist_n = list_entry((struct list_head *)del,sublist,list); if(sublist_n->node_cnt) del_audio_node(&(sublist_n->node_head)); list_move_tail((struct list_head *)del,(struct list_head*)&sublist_head); os_mutex_unlock(&list_mutex); } static void insert_into_useList(volatile struct list_head *del, volatile struct list_head *head) { sublist *sublist_n; sublist *sublist_n_pos; sublist *npos; sublist_n = list_entry((struct list_head *)del,sublist,list); int prev_sort = 0; uint16 new_sort = 0; uint16 next_sort = 0; new_sort = sublist_n->sort; prev_sort = (play_start_flag&BIT(0))?play_sort:-1; if((prev_sort>=new_sort) && ((prev_sort-new_sort)<=20)) { // os_printf("del1:%d %d\n",new_sort,prev_sort); del_audio_sublist(del); return; } int ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return; if(list_empty_careful((struct list_head *)head)) { // os_printf("is1:%d %d\n",new_sort,prev_sort); list_move((struct list_head *)del,(struct list_head *)head); os_mutex_unlock(&list_mutex); return; } os_mutex_unlock(&list_mutex); list_for_each_entry_safe(sublist_n_pos, npos, (struct list_head *)head, list) { next_sort = sublist_n_pos->sort; if(new_sort == next_sort) { // os_printf("del2:%d %d %d\n",new_sort,prev_sort,next_sort); del_audio_sublist(del); return; } else if( (prev_sort < new_sort ) && (new_sort < next_sort) && ((next_sort-new_sort) < 60000) ) { ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return; // os_printf("is2:%d %d %d\n",new_sort,prev_sort,next_sort); list_move((struct list_head *)del,(struct list_head *)(sublist_n_pos->list.prev)); os_mutex_unlock(&list_mutex); return; } else if( (prev_sort>60000) && ((prev_sort - new_sort)>60000) && (new_sort < next_sort) && (prev_sort - next_sort>60000) ) { ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return; // os_printf("is3:%d %d %d\n",new_sort,prev_sort,next_sort); list_move((struct list_head *)del,(struct list_head *)(sublist_n_pos->list.prev)); os_mutex_unlock(&list_mutex); return; } prev_sort = next_sort; } ret = os_mutex_lock(&list_mutex,-1); if(ret < 0) return; // os_printf("is4:%d %d %d\n",new_sort,prev_sort,next_sort); list_move_tail((struct list_head *)del,(struct list_head *)head); os_mutex_unlock(&list_mutex); return; } int recv_repeat_check(uint16 seq, uint16 sort) { static uint16 seq_sort[ENCODED_BUF_NUM*2+1] = {0}; if(sort == seq_sort[seq]) { return 1; } else { seq_sort[seq] = sort; return 0; } } uint16_t calulate_sum(uint8_t * buf, uint16_t len) { uint16_t sum = 0; for(uint16_t i=0; i= 2) { retrans_num[i] = 0; lose_packet &= ~BIT(i); } } } sublist_l = intercom->checkList_head.next; sublist_n = list_entry((struct list_head *)sublist_l,sublist,list); status = sublist_n->status; #if INTERCOM_CLIENT if(status == 2) { g_transfer_mode = SEND_MODE; del_audio_sublist(sublist_l); } else { g_transfer_mode = RECV_MODE; #endif temp = (sequence % (ENCODED_BUF_NUM*2))+1; seq = sublist_n->seq; if(os_abs(seq-temp) >= 8) temp = seq; sort = sublist_n->sort; prev_sort = (play_start_flag&BIT(0))?play_sort:-1; /*收到重复包,丢弃*/ if(recv_repeat_check(seq, sort)) { del_audio_sublist(sublist_l); } else if((sort <= prev_sort) && (prev_sort-sort <10)) { del_audio_sublist(sublist_l); lose_packet &= ~BIT(seq); retrans_num[seq] = 0; } else { /*收到丢包,清掉该丢包位*/ if( lose_packet & BIT(seq) ) { lose_packet &= ~BIT(seq); retrans_num[seq] = 0; // printf("re:%d\n",sort); } else if( temp != seq) { if(BIT(seq) > BIT(temp)) lose_packet |= (BIT(seq) - BIT(temp)); else { last_loop_lose = BIT(ENCODED_BUF_NUM*2+1) - BIT(temp); new_loop_lose = BIT(seq) - BIT(1); lose_packet |= (last_loop_lose|new_loop_lose); } sequence = seq; } else sequence = temp; recv_timeout = 0; insert_into_useList(sublist_l,&intercom->useList_head); // os_printf("r:%d\n",sort); } #if INTERCOM_CLIENT } #endif if(lose_packet) { if(now_dac_filter_type == SOUND_INTERCOM) { #if INTERCOM_SERVER sendto(intercom->ack_sfd, &lose_packet,4, 0, (struct sockaddr*)&(intercom->ack_c_addr), addrlen); #elif INTERCOM_CLIENT sendto(intercom->ack_cfd, &lose_packet, 4, 0, (struct sockaddr*)&(intercom->ack_s_addr), addrlen); #endif // printf("lp:%d***********\n",lose_packet); } } } void losePacket_retransfer(uint8 *addr, uint32 len) { if(encoded_ringbuf == NULL) { return; } uint8 send_buf[ENCODED_BUF_BYTE*NUM_OF_FRAME] = {0}; if((addr+len) > ((uint8*)(encoded_ringbuf->data+encoded_ringbuf->size))) { uint32 residue_len = (uint8*)(encoded_ringbuf->data+encoded_ringbuf->size)-addr; os_memcpy(send_buf, addr, residue_len); os_memcpy(send_buf+residue_len, encoded_ringbuf->data, len-residue_len); } else os_memcpy(send_buf, addr, len); #if INTERCOM_SERVER sendto(intercom->udp_sfd, send_buf, len, 0, (struct sockaddr*)&(intercom->udp_c_addr), sizeof(intercom->udp_c_addr)); #elif INTERCOM_CLIENT sendto(intercom->udp_cfd, send_buf, len, 0, (struct sockaddr*)&(intercom->udp_s_addr), sizeof(intercom->udp_s_addr)); #endif } void retransfer_check(void *d) { int len = 0; char sequence = 0; socklen_t addrlen = sizeof(struct sockaddr_in); uint32 lose_packet = 0; volatile struct list_head *manage_p = NULL; uint8 *addr = NULL; uint32 send_totallen = 0; uint8_t cnt = 0; while(1) { #if INTERCOM_SERVER len = recvfrom(intercom->ack_sfd, &lose_packet, 4, 0, (struct sockaddr*)&(intercom->ack_c_addr), &addrlen); if(g_transfer_mode == RECV_MODE) continue; #elif INTERCOM_CLIENT len = recvfrom(intercom->ack_cfd, &lose_packet, 4, 0, (struct sockaddr*)&(intercom->ack_s_addr), &addrlen); #endif if((play_start_flag&BIT(1)) == 0) continue; if(len > 0) { if(os_mutex_lock(&send_mutex,-1) == 0) { manage_p = ringbuf_manage_use.next; while(manage_p != &(ringbuf_manage_use)) { cnt++; send_totallen = 0; addr = (uint8*)get_ringbuf_manage_addr((struct list_head *)manage_p); sequence = *addr; if(BIT(sequence) & lose_packet) { // printf("rs:%d\n",sequence); for(uint32 i=0; inext; if(manage_p == (&ringbuf_manage_use)) break; } losePacket_retransfer(addr, send_totallen); os_sleep_ms(1); } else manage_p = manage_p->next; if(cnt >= ENCODED_BUF_NUM) break; } os_mutex_unlock(&send_mutex); } } } } void intercom_send(uint8 num) { int slen = 0; socklen_t addrlen = sizeof(struct sockaddr_in); uint8 send_buf[ENCODED_BUF_BYTE*NUM_OF_FRAME] = {0}; uint32 send_totallen = 0; uint8 *addr = NULL; struct list_head *manage_p = NULL; uint32 numof_available = get_ringbuf_manage_count(); if((numof_available >= num) && (send_start_flag==0)) { send_start_flag = 1; } if((send_start_flag) && (numof_available >= num)) { manage_cur_pop = manage_cur_pop->next; manage_p = manage_cur_pop; addr = (uint8*)get_ringbuf_manage_addr(manage_cur_pop); for(uint32 i=0; inext; } if((addr+send_totallen) > ((uint8*)(encoded_ringbuf->data+encoded_ringbuf->size))) { uint32 residue_len = (uint8*)(encoded_ringbuf->data+encoded_ringbuf->size)-addr; os_memcpy(send_buf, addr, residue_len); os_memcpy(send_buf+residue_len, encoded_ringbuf->data, send_totallen-residue_len); } else os_memcpy(send_buf, addr, send_totallen); if(send_start_flag == 1) { #if INTERCOM_SERVER slen = sendto(intercom->udp_sfd, send_buf, send_totallen, 0, (struct sockaddr*)&(intercom->udp_c_addr), addrlen); #elif INTERCOM_CLIENT slen = sendto(intercom->udp_cfd, send_buf, send_totallen, 0, (struct sockaddr*)&(intercom->udp_s_addr), addrlen); #endif // os_printf("s:%d %d\n",*((uint16_t*)(send_buf+2)),send_totallen); } } } void intercom_recv(void *d) { int rlen = 0; socklen_t addrlen = sizeof(struct sockaddr_in); uint8 recv_buf[ENCODED_BUF_BYTE*NUM_OF_FRAME] = {0}; uint8 *node_addr = NULL; uint32 code_len = 0; uint32 offset = 0; uint32 node_num = 0; #if DUPLEX_TYPE == FULL_DUPLEX static int recv_timeout_cnt = 0; #endif #if INTERCOM_SERVER uint8 encoded_buf[RESERVE] = {0}; int ret = -1; static uint32 send_req_cnt = 0; #endif static int r_identify_num = 0; while(1) { #if INTERCOM_SERVER rlen = recvfrom(intercom->udp_sfd, recv_buf, ENCODED_BUF_BYTE*NUM_OF_FRAME, 0, (struct sockaddr*)&(intercom->udp_c_addr), &addrlen); if(memcmp(&intercom->udp_c_addr.sin_addr,&intercom->ack_c_addr.sin_addr,sizeof(struct in_addr)) != 0) memcpy(&intercom->ack_c_addr.sin_addr,&intercom->udp_c_addr.sin_addr,sizeof(struct in_addr)); if(rlen <= 0) { #if DUPLEX_TYPE == HALF_DUPLEX ret = os_mutex_lock(&send_mutex,-1); if(ret < 0) continue; if((get_ringbuf_manage_count()<=0) && (g_transfer_mode == RECV_MODE) && (g_switch_recv_success==0) && (send_req_cnt < 10)) { os_printf("intercom server send request\n"); encoded_buf[1] = 2; *((uint32*)(encoded_buf+8)) = g_s_identify_num; sendto(intercom->udp_sfd, encoded_buf, RESERVE, 0, (struct sockaddr*)&(intercom->udp_c_addr), addrlen); send_req_cnt++; if(send_req_cnt >= 10) send_req_cnt = 10; } os_mutex_unlock(&send_mutex); #elif DUPLEX_TYPE == FULL_DUPLEX recv_timeout_cnt++; if(recv_timeout_cnt>=20){ recv_timeout_cnt = 20; if(send_start_flag==1) send_start_flag = 2; //认为对方进入低功耗或者掉线,停止发送,但是发送缓存区还需要更新; intercom_encode_flag &= ~BIT(1); //停止编码 } #endif continue; } else { #if DUPLEX_TYPE == HALF_DUPLEX g_switch_recv_success = 1; send_req_cnt = 0; #elif DUPLEX_TYPE == FULL_DUPLEX recv_timeout_cnt = 0; if(send_start_flag==2) send_start_flag = 1; intercom_encode_flag |= BIT(1); #endif } #elif INTERCOM_CLIENT rlen = recvfrom(intercom->udp_cfd, recv_buf, ENCODED_BUF_BYTE*NUM_OF_FRAME, 0, (struct sockaddr*)&(intercom->udp_s_addr), &addrlen); if((play_start_flag&BIT(1)) == 0) { continue; } if(rlen <= 0) { recv_timeout_cnt++; if(recv_timeout_cnt>=20){ recv_timeout_cnt = 20; #if(DUPLEX_TYPE == FULL_DUPLEX) intercom_encode_flag &= ~BIT(1); //停止编码 #else if(g_transfer_mode == RECV_MODE) g_transfer_mode = SEND_MODE; #endif } } else { recv_timeout_cnt = 0; #if(DUPLEX_TYPE == FULL_DUPLEX) intercom_encode_flag |= BIT(1); #endif } #endif if(rlen >= RESERVE) { offset = 0; while(rlen > offset) { uint16_t check_sum = *((uint16_t*)(recv_buf+offset+RESERVE-2)); if(check_sum != calulate_sum(recv_buf+offset, RESERVE-2)) { os_printf("intercom abnormal packet\n"); break; } struct list_head *sublist_l = get_audio_sublist((struct list_head*)(&intercom->checkList_head)); if(!sublist_l) break; sublist *sublist_n = list_entry((struct list_head *)sublist_l,sublist,list); os_memcpy(&(sublist_n->seq), recv_buf+offset, RESERVE-2); if(r_identify_num != sublist_n->identify_num) { for(uint8 i=0; iuseList_head.next; del_audio_sublist(sublist_l); } g_numofcached = 0; play_start_flag &= ~BIT(0); r_identify_num = sublist_n->identify_num; os_printf("\n******change intercom identify_num****\n"); } offset += RESERVE; code_len = ENCODED_DATA_BYTE; node_num = (code_len%NODE_DATA_LEN)?(code_len/NODE_DATA_LEN+1):(code_len/NODE_DATA_LEN); sublist_n->node_cnt = node_num; struct list_head *audio_n = get_audio_node(&(sublist_n->node_head), node_num); if(audio_n) { while(code_len > NODE_DATA_LEN) { node_addr = (uint8*)get_audio_addr(audio_n); os_memcpy(node_addr, recv_buf+offset, NODE_DATA_LEN); audio_n = audio_n->next; offset += NODE_DATA_LEN; code_len -= NODE_DATA_LEN; } if(code_len > 0) { node_addr = (uint8*)get_audio_addr(audio_n); os_memcpy(node_addr, recv_buf+offset, code_len); offset += code_len; code_len = 0; } lose_packet_check(); } else { sublist_n->node_cnt = 0; del_audio_sublist(sublist_l); } } } } } void mute_speaker(uint8 enable) { gpio_set_val(PIN_SPK_MUTE, enable); } void decode_sem_up(uint32 *args) { if(g_code_sema_init) { os_sema_up(&decode_sem); } return; } void encode_sema_up() { if(g_code_sema_init) { os_sema_up(&encode_sem); } } void intercom_encoded_start(void) { intercom_encode_flag |= BIT(0); } void intercom_emcoded_stop(void) { intercom_encode_flag &= ~BIT(0); } void intercom_encoded_handle(void *d) { int16 *recv_stream_buf = NULL; struct data_structure *get_f = NULL; int code_len = 0; uint8_t encoded_buf[ENCODED_BUF_BYTE] = {0}; static uint16 sort = 0; uint32 timestamp = 0; static uint8 mute_sta = 0; static uint8 num_of_avaiable = 0; uint8 send_num = 0; ringbuf_manage *ringbuf_mana_n = NULL; struct list_head *ringbuf_mana_l = NULL; struct list_head *manage_l_del = NULL; ringbuf_manage *manage_n_del = NULL; struct os_semaphore *sem = (struct os_semaphore *)d; int ret = -1; g_s_identify_num = 0; os_random_bytes((uint8*)(&g_s_identify_num), 4); os_printf("\n**********intercom ID:%d***********\n",g_s_identify_num); while(1) { os_sema_down(sem,-1); get_f = recv_real_data(intercom->recv_s); current_adc_data = get_f; ret = os_mutex_lock(&send_mutex,-1); if(ret == 0){ #if DUPLEX_TYPE == HALF_DUPLEX if(g_transfer_mode == SEND_MODE) { #endif if(get_f) { #if DUPLEX_TYPE == HALF_DUPLEX if((g_numofcached > 0) || (intercom_encode_flag!=0x03)) { #elif DUPLEX_TYPE == FULL_DUPLEX if(intercom_encode_flag!=0x03) { #endif free_data(get_f); current_adc_data = NULL; g_send_sequence = (g_send_sequence % (ENCODED_BUF_NUM*2))+1; encoded_buf[0] = (uint8)g_send_sequence; encoded_buf[1] = 0; if(sort < 65535) sort++; else sort = 0; *((uint16*)(encoded_buf+2)) = sort; timestamp = os_jiffies(); *((uint32*)(encoded_buf+4)) = timestamp; *((uint32*)(encoded_buf+8)) = g_s_identify_num; *((uint16_t*)(encoded_buf+12)) = calulate_sum(encoded_buf,RESERVE-2); ringbuf_mana_l = get_ringbuf_manage(0); if(!ringbuf_mana_l) { ringbuf_mana_l = ringbuf_manage_use.next; ringbuf_mana_n = list_entry(ringbuf_mana_l, ringbuf_manage, list); encoded_ringbuf->front = (encoded_ringbuf->front+ENCODED_BUF_BYTE)%(encoded_ringbuf->size); if(manage_cur_pop == ringbuf_manage_use.next) manage_cur_pop = manage_cur_pop->next; ringbuf_mana_l = get_ringbuf_manage(1); } manage_cur_push = ringbuf_mana_l; ringbuf_mana_n = list_entry(ringbuf_mana_l, ringbuf_manage, list); ringbuf_mana_n->buf_addr = (uint8*)encoded_ringbuf->data + encoded_ringbuf->rear; while(ringbuf_push_available(encoded_ringbuf) < ENCODED_BUF_BYTE) { manage_l_del = ringbuf_manage_use.next; manage_n_del = list_entry(manage_l_del, ringbuf_manage, list); encoded_ringbuf->front = (encoded_ringbuf->front+ENCODED_BUF_BYTE)%(encoded_ringbuf->size); if(manage_cur_pop == ringbuf_manage_use.next) manage_cur_pop = manage_cur_pop->next; del_ringbuf_manage(); } push_ringbuf(encoded_ringbuf, encoded_buf, ENCODED_BUF_BYTE); send_num = 1; intercom_send(send_num); os_mutex_unlock(&send_mutex); continue; } g_switch_recv_success = 0; mute_sta = 0; recv_stream_buf = get_stream_real_data(get_f); timestamp = os_jiffies(); adpcm_encode(Enc_Inst,encoded_buf+RESERVE,&code_len,recv_stream_buf,DECODED_DATA_LEN,CODE_BPS); free_data(get_f); current_adc_data = NULL; g_send_sequence = (g_send_sequence % (ENCODED_BUF_NUM*2))+1; encoded_buf[0] = (uint8)g_send_sequence; encoded_buf[1] = 1; if(sort < 65535) sort++; else sort = 0; *((uint16*)(encoded_buf+2)) = sort; *((uint32*)(encoded_buf+4)) = timestamp; *((uint32*)(encoded_buf+8)) = g_s_identify_num; *((uint16_t*)(encoded_buf+12)) = calulate_sum(encoded_buf,RESERVE-2); ringbuf_mana_l = get_ringbuf_manage(0); if(!ringbuf_mana_l) { ringbuf_mana_l = ringbuf_manage_use.next; ringbuf_mana_n = list_entry(ringbuf_mana_l, ringbuf_manage, list); encoded_ringbuf->front = (encoded_ringbuf->front+ENCODED_BUF_BYTE)%(encoded_ringbuf->size); if(manage_cur_pop == ringbuf_manage_use.next) manage_cur_pop = manage_cur_pop->next; ringbuf_mana_l = get_ringbuf_manage(1); } manage_cur_push = ringbuf_mana_l; ringbuf_mana_n = list_entry(ringbuf_mana_l, ringbuf_manage, list); ringbuf_mana_n->buf_addr = (uint8*)encoded_ringbuf->data + encoded_ringbuf->rear; while(ringbuf_push_available(encoded_ringbuf) < ENCODED_BUF_BYTE) { manage_l_del = ringbuf_manage_use.next; manage_n_del = list_entry(manage_l_del, ringbuf_manage, list); encoded_ringbuf->front = (encoded_ringbuf->front+ENCODED_BUF_BYTE)%(encoded_ringbuf->size); if(manage_cur_pop == ringbuf_manage_use.next) manage_cur_pop = manage_cur_pop->next; del_ringbuf_manage(); } push_ringbuf(encoded_ringbuf, encoded_buf, ENCODED_BUF_BYTE); send_num = NUM_OF_FRAME; intercom_send(send_num); } else { if(send_start_flag) { if(mute_sta == 0) { num_of_avaiable = get_ringbuf_manage_count(); mute_sta = 1; } if(num_of_avaiable > 0) { intercom_send(num_of_avaiable); num_of_avaiable--; } else { g_send_sequence = (g_send_sequence % (ENCODED_BUF_NUM*2))+1; encoded_buf[0] = (uint8)g_send_sequence; encoded_buf[1] = 0; if(sort < 65535) sort++; else sort = 0; *((uint16*)(encoded_buf+2)) = sort; timestamp = os_jiffies(); *((uint32*)(encoded_buf+4)) = timestamp; *((uint32*)(encoded_buf+8)) = g_s_identify_num; *((uint16_t*)(encoded_buf+12)) = calulate_sum(encoded_buf,RESERVE-2); ringbuf_mana_l = get_ringbuf_manage(0); if(!ringbuf_mana_l) { ringbuf_mana_l = ringbuf_manage_use.next; ringbuf_mana_n = list_entry(ringbuf_mana_l, ringbuf_manage, list); encoded_ringbuf->front = (encoded_ringbuf->front+ENCODED_BUF_BYTE)%(encoded_ringbuf->size); if(manage_cur_pop == ringbuf_manage_use.next) manage_cur_pop = manage_cur_pop->next; ringbuf_mana_l = get_ringbuf_manage(1); } manage_cur_push = ringbuf_mana_l; ringbuf_mana_n = list_entry(ringbuf_mana_l, ringbuf_manage, list); ringbuf_mana_n->buf_addr = (uint8*)encoded_ringbuf->data + encoded_ringbuf->rear; while(ringbuf_push_available(encoded_ringbuf) < ENCODED_BUF_BYTE) { manage_l_del = ringbuf_manage_use.next; manage_n_del = list_entry(manage_l_del, ringbuf_manage, list); encoded_ringbuf->front = (encoded_ringbuf->front+ENCODED_BUF_BYTE)%(encoded_ringbuf->size); if(manage_cur_pop == ringbuf_manage_use.next) manage_cur_pop = manage_cur_pop->next; del_ringbuf_manage(); } push_ringbuf(encoded_ringbuf, encoded_buf, ENCODED_BUF_BYTE); send_num = 1; intercom_send(send_num); } } } #if DUPLEX_TYPE == HALF_DUPLEX } else if(g_transfer_mode == RECV_MODE){ num_of_avaiable = get_ringbuf_manage_count(); if(num_of_avaiable > 0) { intercom_send(num_of_avaiable); num_of_avaiable--; } if(get_f) { free_data(get_f); current_adc_data = NULL; } } #endif os_mutex_unlock(&send_mutex); } } } void set_sonic_speed(struct sonic_process_priv *sonic_priv, float speed); static int send_to_stream(uint32_t cached) { int16 *send_stream_buf = NULL; struct data_structure *get_f = NULL; struct list_head *sublist_l = NULL; sublist *sublist_n = NULL; int code_len = 0; uint32 offset = 0; uint16 new_sort = 0; uint32_t timestamp = 0; int16 decode_data[DECODED_DATA_LEN] = {0}; uint8 encode_data[ENCODED_DATA_BYTE] = {0}; uint8 packet_sta = 0; static uint32_t last_timestamp = 0; static uint32_t plc_cnt = 0; int send_res = 0; static uint32_t lose_sum = 0; static uint8_t play_speed_sta = 2; static float play_speed = 1.0f; #if LOSE_STATISTICAL static uint32_t last_statistical_time = 0; #endif send_to_stream_again: get_f = get_src_data_f(intercom->send_s); current_dac_data = get_f; if(get_f) { send_stream_buf = get_stream_real_data(get_f); play_sort = g_current_sort; if(list_empty((struct list_head*)&intercom->useList_head) == 0) { sublist_l = intercom->useList_head.next; sublist_n = list_entry((struct list_head*)sublist_l, sublist, list); new_sort = sublist_n->sort; if( (new_sort - g_current_sort) > 20 ) g_current_sort = new_sort; // else if( ((g_current_sort - new_sort)>0) && ((g_current_sort - new_sort)<60000) ) // g_current_sort = new_sort; if(SUBLIST_NUM-cached<15) g_current_sort = new_sort; packet_sta = sublist_n->status; if(packet_sta == 0) { #if MUTE_SPEAKER == 1 mute_speaker(1); #endif force_del_data(get_f); del_audio_sublist(sublist_l); g_intercom_start = 0; g_current_sort += 1; return 0; } #if MUTE_SPEAKER == 1 mute_speaker(0); #endif if(g_current_sort == new_sort) { timestamp = sublist_n->timestamp; last_timestamp = timestamp; code_len = ENCODED_DATA_BYTE; struct list_head *audio_n = sublist_n->node_head.next; uint8 *addr = NULL; offset = 0; while(code_len > NODE_DATA_LEN) { addr = (uint8*)get_audio_addr(audio_n); os_memcpy(encode_data+offset, addr, NODE_DATA_LEN); audio_n = audio_n->next; offset += NODE_DATA_LEN; code_len -= NODE_DATA_LEN; } if(code_len > 0) { addr = (uint8*)get_audio_addr(audio_n); os_memcpy(encode_data+offset, addr, code_len); offset += code_len; code_len = 0; } code_len = adpcm_decode(Dec_Inst,decode_data,encode_data,ENCODED_DATA_BYTE,CODE_BPS); del_audio_sublist(sublist_l); plc_cnt = 0; } else { #if PLC_PROCESS == 1 code_len = adpcm_decode_plc(Dec_Inst,decode_data); timestamp = last_timestamp+CODE_MODE; last_timestamp = timestamp; #else os_memset(decode_data, 0, DECODED_DATA_LEN*2); #endif plc_cnt++; lose_sum++; if(plc_cnt > 20) play_start_flag &= ~BIT(0); } } else { #if PLC_PROCESS == 1 code_len = adpcm_decode_plc(Dec_Inst,decode_data); timestamp = last_timestamp+CODE_MODE; last_timestamp = timestamp; #else os_memset(decode_data, 0, DECODED_DATA_LEN*2); #endif plc_cnt++; lose_sum++; if(plc_cnt > 20) play_start_flag &= ~BIT(0); } g_current_sort += 1; #if CHANGE_PLAY_SPEED == 1 if(cached<=(playofwait-5)) { if(play_speed_sta != 0) { play_speed = 0.9f; set_sonic_speed(sonic_priv, play_speed); play_speed_sta = 0; } } else if(cached>=(playofwait+5)) { if(play_speed_sta != 1) { play_speed = 1.1f; set_sonic_speed(sonic_priv, play_speed); play_speed_sta = 1; } } else if(cached==playofwait) { if(play_speed_sta != 2) { play_speed = 1.0f; set_sonic_speed(sonic_priv, play_speed); play_speed_sta = 2; } } #endif os_memcpy(send_stream_buf, decode_data, DECODED_DATA_LEN*2); set_sound_data_len(get_f, DECODED_DATA_LEN*2); get_f->type = SET_DATA_TYPE(SOUND, SOUND_INTERCOM); set_stream_data_time(get_f,timestamp); send_res = send_data_to_stream(get_f); current_dac_data = NULL; g_intercom_start = 1; if((now_dac_filter_type == SOUND_INTERCOM) && (send_res>0) &&(cached>=1)){ cached -= 1; os_sleep_ms(2); goto send_to_stream_again; } } #if LOSE_STATISTICAL if(os_jiffies()-last_statistical_time > 1000) { os_printf("intercom loss statistical:%d\n",lose_sum); lose_sum = 0; last_statistical_time = os_jiffies(); } #endif // os_printf("g_numofcached:%d\n",cached); return 0; } extern void audio_dac_set_filter_type(int filter_type); extern int get_audio_dac_set_filter_type(void); void intercom_decoded_handle(void *d) { static int former_dac_filter_type = 0; uint8 numofwait = 0; //等待缓存数量满足条件而暂缓播放的次数 struct os_semaphore *sem = (struct os_semaphore *)d; former_dac_filter_type = get_audio_dac_set_filter_type(); if(former_dac_filter_type != SOUND_FILE) audio_dac_set_filter_type(SOUND_INTERCOM); struct list_head *sublist_l = NULL; sublist *sublist_n = NULL; while(1) { os_sema_down(sem, -1); #if DEALY_ADJUSTMENT #if INTERCOM_SERVER if(txmode == 3) #elif INTERCOM_CLIENT if(send_mode == 3) #endif playofwait = 5; else playofwait = SORTBUF_NUM/2; #endif g_numofcached = get_audio_sublist_count((struct list_head *)&intercom->useList_head); now_dac_filter_type = get_audio_dac_set_filter_type(); if((now_dac_filter_type != SOUND_INTERCOM) && (!find_stream_enable(R_AT_AVI_AUDIO))) { for(uint8_t i=0; iuseList_head.next; del_audio_sublist(sublist_l); g_current_sort += 1; play_sort = g_current_sort; } play_start_flag &= ~BIT(0); numofwait = 0; os_sleep_ms(1); continue; } if((g_numofcached >= playofwait) && (!find_stream_enable(R_AT_AVI_AUDIO)) && (play_start_flag&BIT(0))) { for(uint8 i=0; iuseList_head.next; del_audio_sublist(sublist_l); g_current_sort += 1; play_sort = g_current_sort; } } del_node_num = 0; g_numofcached = get_audio_sublist_count((struct list_head *)&intercom->useList_head); /*缓存的帧数大于一定数量则开始播放*/ #if DUPLEX_TYPE == HALF_DUPLEX if( ((play_start_flag&BIT(0)) == 0) && ((g_numofcached > playofwait) || (numofwait > playofwait) || ((g_transfer_mode == SEND_MODE)&&(g_numofcached>0))) ) #else if( ((play_start_flag&BIT(0)) == 0) && ((g_numofcached > playofwait) || (numofwait > playofwait))) #endif { play_start_flag |= BIT(0); numofwait = 0; sublist_l = intercom->useList_head.next; sublist_n = list_entry((struct list_head*)sublist_l, sublist, list); g_current_sort = sublist_n->sort; os_printf("intercom play start\n"); } if( ((play_start_flag&BIT(0)) == 0) && (g_numofcached > 0) ) { numofwait++; } if(play_start_flag&BIT(0)) { send_to_stream(g_numofcached); } #if DUPLEX_TYPE == HALF_DUPLEX if((g_numofcached <=0) && (g_transfer_mode == SEND_MODE) && (play_start_flag&BIT(0))) { #if MUTE_SPEAKER == 1 mute_speaker(1); #endif play_start_flag &= ~BIT(0); g_intercom_start = 0; } #endif } } void intercom_encode_switch(uint8 enable) { if(enable) intercom_encode_flag |= BIT(0); else intercom_encode_flag &= ~BIT(0); } void intercom_suspend(void) { os_timer_stop(&ctl_timer); g_code_sema_init = 0; play_start_flag &= ~BIT(1); os_sleep_ms(60); clear_ringbuf_manage_use(); if(current_adc_data) { free_data(current_adc_data); current_adc_data = NULL; } if(current_dac_data) { force_del_data(current_dac_data); current_dac_data = NULL; } } void intercom_resume(void) { os_timer_start(&ctl_timer,CODE_MODE); g_numofcached = get_audio_sublist_count((struct list_head *)&intercom->useList_head); for(uint8 i=0; iuseList_head.next; del_audio_sublist(sublist_l); } g_numofcached = 0; g_code_sema_init = 1; play_start_flag &= ~BIT(0); play_start_flag |= BIT(1); send_start_flag = 0; g_intercom_start = 0; }