#include "encode_write.h" #include "file_operate/file_bs_deal.h" #include "audio_enc.h" #include "media/audio_base.h" #include "dev_manager.h" #include "app_config.h" #include "spi/nor_fs.h" #include "rec_nor/nor_interface.h" #if TCFG_ENC_WRITE_FILE_ENABLE extern FILE *file_api_auto_create_file(const char *path, const char *folder, const char *filename, u32 *file_index); // *INDENT-OFF* struct enc_write_file{ volatile u32 init_ok : 1; volatile u32 wait_idle : 1; volatile u32 start : 1; volatile u32 wait_stop : 1; u32 write_err : 1; OS_SEM sem_task_run; struct __dev *dev; const char *folder; const char *filename; void *fmnt; FILE *file; u32 cut_size; u32 limit_size; int file_size; u32 input_frame_len; void *input_hdl; struct audio_enc_write_input *input; u32 write_err_no_check; void *evt_hdl; void (*evt_cb)(void *, int, int); void *set_head_hdl; int (*set_head)(void *, char **head); }; static volatile u32 enc_file_index = (u32) - 1; static volatile u32 enc_file_coding_type = 0; extern u8 record_part; void last_enc_file_codeing_type_save(u32 type) { enc_file_coding_type = type; } //获取最后录音文件的序号. 用于录音播放, -1表示无效 int last_enc_file_path_get(char path[64]) { #if TCFG_NOR_REC || FLASH_INSIDE_REC_ENABLE int index = 0; char logo[20] = {0}; #if TCFG_NOR_REC strcpy(logo, "rec_nor"); sprintf(path, "%s%s%s", dev_manager_get_root_path_by_logo(logo), REC_FOLDER_NAME"/AC69****",".WAV"); #elif FLASH_INSIDE_REC_ENABLE char index_str[5] = {0}; index = flashinsize_rec_get_index(); memset(logo, 0, 20); memset(path, 0, 64); strcpy(logo, "rec_sdfile"); index_str[0] = index / 1000 + '0'; index_str[1] = index % 1000 / 100 + '0'; index_str[2] = index % 100 / 10 + '0'; index_str[3] = index % 10 + '0'; sprintf(path, "%s%s%s%s", dev_manager_get_root_path_by_logo(logo), REC_FOLDER_NAME"/AC69", index_str, ".WAV"); #endif printf("rec file =%s\n", path); return 0; #else char index_str[5] = {0}; char *logo = dev_manager_get_phy_logo(dev_manager_find_active(0));//最后活动设备 printf("enc file idex = %d, dev_path = %s\n", enc_file_index, dev_manager_get_root_path_by_logo(logo)); if (enc_file_index != (u32) - 1) { index_str[0] = enc_file_index / 1000 + '0'; index_str[1] = enc_file_index % 1000 / 100 + '0'; index_str[2] = enc_file_index % 100 / 10 + '0'; index_str[3] = enc_file_index % 10 + '0'; if ((enc_file_coding_type == AUDIO_CODING_WAV) || (enc_file_coding_type == AUDIO_CODING_PCM)) { sprintf(path, "%s%s%s%s", dev_manager_get_root_path_by_logo(logo), REC_FOLDER_NAME"/AC69", index_str, ".WAV"); } else if (enc_file_coding_type == AUDIO_CODING_G726) { sprintf(path, "%s%s%s%s", dev_manager_get_root_path_by_logo(logo), REC_FOLDER_NAME"/AC69", index_str, ".wav"); } else if (enc_file_coding_type == AUDIO_CODING_MP3) { sprintf(path, "%s%s%s%s", dev_manager_get_root_path_by_logo(logo), REC_FOLDER_NAME"/AC69", index_str, ".MP3"); } else { return -1; } printf("rec file =%s\n", path); return 0; } return -1; #endif } static void enc_write_file_task(void *p) { int ret, len; int pend_dly = -1; struct enc_write_file *wfil = p; s16 *frame; while (1) { if (pend_dly) { os_sem_pend(&wfil->sem_task_run, pend_dly); } if (!wfil->init_ok) { wfil->wait_idle = 0; wfil->start = 0; wfil->wait_stop = 0; break; } pend_dly++; if (!wfil->start) { continue; } len = wfil->input->get(wfil->input_hdl, &frame, wfil->input_frame_len); if (len) { if (wfil->write_err == 0) { ret = fwrite(wfil->file, frame, len); wfil->file_size = fpos(wfil->file); #if TCFG_NOR_REC || FLASH_INSIDE_REC_ENABLE int max_capacity = 0; #if TCFG_NOR_REC max_capacity = get_rec_capacity(wfil->file); #elif FLASH_INSIDE_REC_ENABLE max_capacity = flashinsize_rec_get_capacity(); #endif if (wfil->file_size + len > (max_capacity - 4096)) { log_w("rec is overflow!!!!!!!!!!!!!"); wfil->write_err_no_check = 1; wfil->write_err = 1; } else { wfil->write_err_no_check = 0; } #endif } else { ret = 0; } if (ret != len) { if (wfil->write_err == 0) { log_e("write file err "); if (wfil->evt_cb) { wfil->evt_cb(wfil->evt_hdl, ENC_WRITE_FILE_EVT_WRITE_ERR, 0); } } wfil->write_err = 1; } else { pend_dly = 0; } if (wfil->input->put) { wfil->input->put(wfil->input_hdl, frame); } } else { wfil->wait_stop = 0; } } while (1) { os_time_dly(100); } } int enc_write_file_resume(void *hdl) { struct enc_write_file *wfil = hdl; if (wfil->start && (wfil->write_err == 0)) { os_sem_set(&wfil->sem_task_run, 0); os_sem_post(&wfil->sem_task_run); return 0; } return -1; } void enc_write_file_close(void *hdl) { struct enc_write_file *wfil = hdl; if (wfil->init_ok) { wfil->wait_idle = 1; wfil->init_ok = 0; os_sem_set(&wfil->sem_task_run, 0); os_sem_post(&wfil->sem_task_run); while (wfil->wait_idle) { os_time_dly(1); } task_kill("enc_write"); } if (wfil->file) { int f_len = fpos(wfil->file); struct vfs_attr attr = {0}; do { if (f_len <= wfil->cut_size) { enc_file_index = (u32) - 1; fdelete(wfil->file); break; } f_len -= wfil->cut_size; if (f_len <= wfil->limit_size) { enc_file_index = (u32) - 1; fdelete(wfil->file); break; } if (wfil->set_head && (wfil->write_err_no_check || wfil->write_err == 0)) { char *head; int len = wfil->set_head(wfil->set_head_hdl, &head); if (f_len <= len) { enc_file_index = (u32) - 1; fdelete(wfil->file); break; } if (len) { fseek(wfil->file, 0, SEEK_SET); fwrite(wfil->file, head, len); } } fseek(wfil->file, f_len, SEEK_SET); fget_attrs(wfil->file, &attr); fclose(wfil->file); char *dev_logo = NULL; #if (TCFG_RECORD_FOLDER_DEV_ENABLE) dev_logo = dev_manager_get_rec_logo(wfil->dev); #else dev_logo = dev_manager_get_logo(wfil->dev); #endif dev_manager_set_valid_by_logo(dev_logo, 1); } while (0); if (wfil->evt_cb) { wfil->evt_cb(wfil->evt_hdl, ENC_WRITE_FILE_EVT_FILE_CLOSE, attr.sclust); } wfil->file = NULL; } free(wfil); } static u32 get_creat_path_len(char *root_path, const char *folder, const char *filename) { return (strlen(root_path) + strlen(folder) + strlen(filename) + strlen("/") + 1); } static char *create_path(char *path, char *root_path, const char *folder, const char *filename) { strcat(path, root_path); strcat(path, folder); strcat(path, "/"); strcat(path, filename); #if TCFG_NOR_REC #elif FLASH_INSIDE_REC_ENABLE int index = 0; int last_num = -1; char *file_num_str; index = sdfile_rec_scan_ex(); last_num = index + 1; file_num_str = strrchr(path, '.') - 4; if (last_num > 9999) { last_num = 0; } file_num_str[0] = last_num / 1000 + '0'; file_num_str[1] = last_num % 1000 / 100 + '0'; file_num_str[2] = last_num % 100 / 10 + '0'; file_num_str[3] = last_num % 10 + '0'; #endif printf(">>>[test]:create path =%s\n", path); return path; } void *enc_write_file_open(char *logo, const char *folder, const char *filename) { if (!logo || !folder || !filename) { return NULL; } int err; struct enc_write_file *wfil = zalloc(sizeof(struct enc_write_file)); if (!wfil) { return NULL; } struct __dev *dev = dev_manager_find_spec(logo, 0); if(!dev){ free(wfil); return NULL; } char *root_path = dev_manager_get_root_path(dev); wfil->dev = dev; wfil->folder = folder; wfil->filename = filename; char *path = NULL; u32 path_len = get_creat_path_len(root_path, folder, filename); printf("path_len %d\n", path_len); path = zalloc(path_len); if(path == NULL){ goto _exit; } create_path(path, root_path, folder, filename); wfil->file = fopen(path, "w+"); free(path); path = NULL; if (!wfil->file) { log_e("file create err "); goto _exit; } enc_file_index = get_last_num(); //获取最后的数字 /* r_printf(">>>[test]:enc_file_index = %d\n", enc_file_index); */ os_sem_create(&wfil->sem_task_run, 0); err = task_create(enc_write_file_task, wfil, "enc_write"); if (err != OS_NO_ERR) { log_e("task create err "); goto _exit; } wfil->init_ok = 1; return wfil; _exit: printf("\n--func=%s, line=%d\n", __FUNCTION__, __LINE__); enc_write_file_close(wfil); printf("\n--func=%s, line=%d\n", __FUNCTION__, __LINE__); return NULL; } int enc_write_file_start(void *hdl) { struct enc_write_file *wfil = hdl; if (wfil->init_ok) { wfil->start = 1; return 0; } return -1; } void enc_write_file_stop(void *hdl, u32 delay_ms) { struct enc_write_file *wfil = hdl; if (wfil->start) { wfil->wait_stop = 1; u32 dly = 0; do { if (!wfil->wait_stop) { break; } if (wfil->write_err) { break; } os_time_dly(1); dly += 10; } while (dly < delay_ms); wfil->start = 0; } } void enc_write_file_set_head_handler(void *hdl, int (*set_head)(void *, char **head), void *set_head_hdl) { struct enc_write_file *wfil = hdl; wfil->set_head = set_head; wfil->set_head_hdl = set_head_hdl; } void enc_write_file_set_evt_handler(void *hdl, void (*evt_cb)(void *, int, int), void *evt_hdl) { struct enc_write_file *wfil = hdl; wfil->evt_cb = evt_cb; wfil->evt_hdl = evt_hdl; } void enc_write_file_set_input(void *hdl, struct audio_enc_write_input *input, void *input_hdl, u32 input_frame_len) { struct enc_write_file *wfil = hdl; wfil->input = input; wfil->input_hdl = input_hdl; wfil->input_frame_len = input_frame_len; } void enc_write_file_set_limit(void *hdl, u32 cut_size, u32 limit_size) { struct enc_write_file *wfil = hdl; wfil->cut_size = cut_size; wfil->limit_size = limit_size; } int get_enc_file_len(void *hdl) { struct enc_write_file *wfil = hdl; int filelen = 0; if (!wfil) { return -1; } if (wfil->file) { filelen = wfil->file_size; /* filelen = fpos(wfil->file); */ /* filelen = flen(wfil->file); */ } return filelen; } void *get_wfil_head_hdl(void *enc_whdl) { struct enc_write_file *wfil = (struct enc_write_file *)enc_whdl; return wfil->set_head_hdl; } FILE *get_wfil_file(void *enc_whdl) { struct enc_write_file *wfil = (struct enc_write_file *)enc_whdl; return wfil->file; } ////////////////////////////////////////////////////////////////////////////// #if 0 #define W_OUTBUF_LEN (1 * 1024) struct enc_write_test { volatile u32 start : 1; volatile u32 err : 1; void *hdl; OS_SEM sem_in; OS_SEM sem_out; u8 output_buf[W_OUTBUF_LEN]; cbuffer_t output_cbuf; s16 output_frame[512 / 2]; //align 4Bytes }; static void enc_w_evt(void *hdl, int err) { struct enc_write_test *tst = hdl; printf("err: %d ", err); if (err) { tst->err = 1; os_sem_set(&tst->sem_in, 0); os_sem_post(&tst->sem_in); os_sem_set(&tst->sem_out, 0); os_sem_post(&tst->sem_out); } } static int enc_w_set_head(void *hdl, char **head) { struct enc_write_test *tst = hdl; u8 hdtab[] = "i'm head!!! "; memcpy(tst->output_frame, hdtab, sizeof(hdtab)); *head = tst->output_frame; return sizeof(hdtab); } static int enc_w_get(void *hdl, s16 **frame, u16 frame_len) { int rlen; struct enc_write_test *tst = hdl; do { rlen = cbuf_read(&tst->output_cbuf, tst->output_frame, frame_len); if (rlen == frame_len) { break; } if (rlen == -EINVAL) { return 0; } if (!tst->start) { return 0; } if (tst->err) { return 0; } os_sem_set(&tst->sem_in, 0); os_sem_post(&tst->sem_in); os_sem_pend(&tst->sem_out, 2); } while (1); *frame = tst->output_frame; return rlen; } static void enc_w_put(void *hdl, s16 *frame) { } const struct audio_enc_write_input enc_w_input = { .get = enc_w_get, .put = enc_w_put, }; void enc_w_test(void) { struct enc_write_test *tst = zalloc(sizeof(struct enc_write_test)); printf("%s,%d ", __func__, __LINE__); if (!tst) { return ; } printf("%s,%d ", __func__, __LINE__); os_sem_create(&tst->sem_in, 0); os_sem_create(&tst->sem_out, 0); cbuf_init(&tst->output_cbuf, tst->output_buf, W_OUTBUF_LEN); printf("%s,%d ", __func__, __LINE__); tst->hdl = enc_write_file_open("sd0", "/"REC_FOLDER_NAME, "AC690000.MP3"); printf("%s,%d ", __func__, __LINE__); if (!tst->hdl) { goto __exit; } printf("%s,%d ", __func__, __LINE__); enc_write_file_set_evt_handler(tst->hdl, enc_w_evt, tst); enc_write_file_set_input(tst->hdl, &enc_w_input, tst, sizeof(tst->output_frame)); enc_write_file_set_head_handler(tst->hdl, enc_w_set_head, tst); enc_write_file_set_limit(tst->hdl, 123, 5000); printf("%s,%d ", __func__, __LINE__); tst->start = 1; enc_write_file_start(tst->hdl); int cnt = 0; u8 str[] = "This is a test string."; while (cnt < 1000) { /* printf("%s,%d ", __func__, __LINE__); */ int len = cbuf_write(&tst->output_cbuf, str, sizeof(str)); os_sem_set(&tst->sem_out, 0); os_sem_post(&tst->sem_out); enc_write_file_resume(tst->hdl); /* printf("%s,%d ", __func__, __LINE__); */ if (len != sizeof(str)) { putchar('N'); os_sem_pend(&tst->sem_in, 2); } else { putchar('Y'); cnt++; } if (tst->err) { os_sem_set(&tst->sem_out, 0); os_sem_post(&tst->sem_out); break; } } __exit: printf("%s,%d ", __func__, __LINE__); tst->start = 0; if (tst->hdl) { enc_write_file_stop(tst->hdl, 1000); enc_write_file_close(tst->hdl); tst->hdl = 0; } printf("%s,%d ", __func__, __LINE__); free(tst); } #endif #endif