花見 太郎
/
Voise_control
Using KNN to realize Voise Control
main.cpp
- Committer:
- jianger_88
- Date:
- 2020-02-07
- Revision:
- 1:2fa6911afef3
- Parent:
- 0:61014bfdf244
File content as of revision 1:2fa6911afef3:
#include "mbed.h" #include "SdUsbConnect.h" #include "AUDIO_GRBoard.h" #define MOUNT_NAME "storage" #define FINE_PATH "/"MOUNT_NAME"/wav_rec.wav" #define SAMPLE_RATE (8000) #define AUDIO_IN_BUF_SIZE (2048) #define AUDIO_IN_BUF_NUM (16) #define AUDIO_OUT_BUF_SIZE (2048) #define AUDIO_OUT_BUF_NUM (8) #define AUDIO_OUT_WAIT ((AUDIO_OUT_BUF_SIZE * AUDIO_OUT_BUF_NUM / 4) * 1000 / SAMPLE_RATE) #define INFO_TYPE_OPEN (0) #define INFO_TYPE_CLOSE (1) #define INFO_TYPE_WRITE_DATA (2) DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); AUDIO_GRBoard audio(0x80, AUDIO_OUT_BUF_NUM - 1, AUDIO_IN_BUF_NUM); // I2S Codec int led_rec; int led_play; InterruptIn button_0(USER_BUTTON0); #if defined(TARGET_GR_LYCHEE) InterruptIn button_1(USER_BUTTON1); #endif static bool play_req = false; typedef struct { uint32_t info_type; void * p_data; int32_t result; } mail_t; Mail<mail_t, (AUDIO_IN_BUF_NUM + 2)> mail_box; static Thread audioInTask(osPriorityNormal, 1024 * 8); //4 bytes aligned! No cache memory #if defined(__ICCARM__) #pragma data_alignment=4 static uint8_t audio_in_buf[AUDIO_IN_BUF_NUM][AUDIO_IN_BUF_SIZE]@ ".mirrorram"; #pragma data_alignment=4 static uint8_t audio_out_buf[AUDIO_OUT_BUF_NUM][AUDIO_OUT_BUF_SIZE]@ ".mirrorram"; #else static uint8_t audio_in_buf[AUDIO_IN_BUF_NUM][AUDIO_IN_BUF_SIZE]__attribute((section("NC_BSS"),aligned(4))); static uint8_t audio_out_buf[AUDIO_OUT_BUF_NUM][AUDIO_OUT_BUF_SIZE]__attribute((section("NC_BSS"),aligned(4))); #endif // wav file header static const char wav_header_tbl[] = { 0x52,0x49,0x46,0x46,0x00,0x00,0x00,0x00,0x57,0x41,0x56,0x45,0x66,0x6D,0x74,0x20, 0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x80,0xBB,0x00,0x00,0x00,0xEE,0x02,0x00, 0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61,0x00,0x00,0x00,0x00 }; #if MBED_CONF_APP_LCD #include "EasyAttach_CameraAndLCD.h" #define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * 2) + 31u) & ~31u) #define FRAME_BUFFER_HEIGHT (LCD_PIXEL_HEIGHT) #if defined(__ICCARM__) #pragma data_alignment=32 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; #else static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); #endif DisplayBase Display; static void Start_LCD_Display(void) { DisplayBase::rect_t rect; memset(user_frame_buffer0, 0xFF, sizeof(user_frame_buffer0)); rect.vs = 0; rect.vw = LCD_PIXEL_HEIGHT; rect.hs = 0; rect.hw = LCD_PIXEL_WIDTH; Display.Graphics_Read_Setting( DisplayBase::GRAPHICS_LAYER_0, (void *)user_frame_buffer0, FRAME_BUFFER_STRIDE, DisplayBase::GRAPHICS_FORMAT_RGB565, DisplayBase::WR_RD_WRSWA_32_16BIT, &rect ); Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); Thread::wait(50); EasyAttach_LcdBacklight(true); } static void disp_audio_wave(int16_t * p_data, int32_t size, uint32_t color) { uint16_t * p_bottom_left_pos = (uint16_t *)&user_frame_buffer0[FRAME_BUFFER_STRIDE * (FRAME_BUFFER_HEIGHT - 1)]; uint16_t * p_frame_buf; uint32_t x = 0; uint32_t data_pos; uint32_t data_pos_last = ((p_data[0] + 0x8000ul) >> 8) + 8; int loop_num; if (size < 0) { return; } memset(user_frame_buffer0, 0xFF, sizeof(user_frame_buffer0)); for (int i = 0; i < size; i += 2) { data_pos = ((p_data[i] + 0x8000ul) >> 8) + 8; p_frame_buf = &p_bottom_left_pos[x]; if (data_pos == data_pos_last) { loop_num = 3; p_frame_buf -= ((data_pos - 1) * LCD_PIXEL_WIDTH); } else if (data_pos > data_pos_last) { loop_num = data_pos - data_pos_last + 2; p_frame_buf -= (data_pos_last * LCD_PIXEL_WIDTH); } else { loop_num = data_pos_last - data_pos + 2; p_frame_buf -= ((data_pos - 1) * LCD_PIXEL_WIDTH); } for (int j = 0; j < loop_num; j++) { *p_frame_buf = color; p_frame_buf -= LCD_PIXEL_WIDTH; } data_pos_last = data_pos; x++; if (x >= LCD_PIXEL_WIDTH) { break; } } } static void callback_audio_write_end(void * p_data, int32_t result, void * p_app_data) { disp_audio_wave((int16_t *)p_data, result / 2, 0x07E0); // Green } #endif // MBED_CONF_APP_LCD static void send_mail(uint32_t info_type, void * p_data, int32_t result) { mail_t *mail = mail_box.alloc(); if (mail != NULL) { mail->info_type = info_type; mail->p_data = p_data; mail->result = result; mail_box.put(mail); } } static void rec_start(void) { send_mail(INFO_TYPE_OPEN, NULL, 0); } static void rec_stop(void) { send_mail(INFO_TYPE_CLOSE, NULL, 0); } static void play_start(void) { play_req = true; } static void KNN(char *file_name, int dat_size) { double *cal_dat; double *com_dat; int record; int NUM_LIB=119; int class_num; double knn=10000000000; double temp=0; com_dat=(double*)malloc(sizeof(double)*dat_size); FILE *input_res,*compare_res; char *lib_name; input_res=fopen(file_name,"rb"); for(int i=0;i<dat_size;i++) { fscanf(input_res,"lf",&cal_dat[i]); } fclose(input_res); for(int i=0;i<NUM_LIB;i++) { temp=0; sprintf(lib_name,"sample%03d.dat",i); compare_res=fopen(lib_name,"w"); for(int i=0;i<dat_size;i++){ fscanf(compare_res,"lf",&com_dat[i]); } for(int i=0;i<dat_size;i++) { temp+=pow((cal_dat[i]-com_dat[i]),2); } if (temp<knn) { knn=temp; record=i; } } if(0<record||record<=25||115<record||record<=119) //output is bird { class_num=1; led1=!led1; } //output is monkey else if(25<record||record<=54) { class_num=2; led2=!led2;} //output is cat else if(54<record||record<=85||record==115) { class_num=3; led3=!led3; } //output is dog else if(85<record||record<=114) {class_num=4; led4=!led4; } } static void callback_audio_read_end(void * p_data, int32_t result, void * p_app_data) { #if MBED_CONF_APP_LCD if (led_play == 0) { uint32_t color; if (led_rec == 0) { color = 0x001F; // Blue } else { color = 0xF800; // Red } disp_audio_wave((int16_t *)p_data, result / 2, color); } #endif send_mail(INFO_TYPE_WRITE_DATA, p_data, result); } static void wire_data_4byte(uint32_t data, FILE * fp) { char work_buf[4]; work_buf[0] = (uint8_t)(data >> 0); work_buf[1] = (uint8_t)(data >> 8); work_buf[2] = (uint8_t)(data >> 16); work_buf[3] = (uint8_t)(data >> 24); fwrite(work_buf, sizeof(char), 4, fp); } void audio_in_task(void) { FILE * wav_fp = NULL; uint32_t pcm_size = 0; rbsp_data_conf_t audio_read_data = {&callback_audio_read_end, NULL}; // Read buffer setting for (uint32_t i = 0; i < AUDIO_IN_BUF_NUM; i++) { if (audio.read(audio_in_buf[i], AUDIO_IN_BUF_SIZE, &audio_read_data) < 0) { printf("read error\n"); } } while (1) { osEvent evt = mail_box.get(); if (evt.status == osEventMail) { mail_t *mail = (mail_t *)evt.value.p; switch (mail->info_type) { case INFO_TYPE_OPEN: wav_fp = fopen(FINE_PATH, "wb"); if (wav_fp != NULL) { led_rec = 1; // REC start pcm_size = 0; fwrite(wav_header_tbl, sizeof(char), sizeof(wav_header_tbl), wav_fp); } break; case INFO_TYPE_CLOSE: if (wav_fp != NULL) { // Set "RIFF" ChunkSize fseek(wav_fp, 4, SEEK_SET); wire_data_4byte(sizeof(wav_header_tbl) - 8 + pcm_size, wav_fp); // Set SampleRate fseek(wav_fp, 24, SEEK_SET); wire_data_4byte(SAMPLE_RATE, wav_fp); // Set ByteRate wire_data_4byte(SAMPLE_RATE * 2 * 2, wav_fp); // Set "data" ChunkSize fseek(wav_fp, 40, SEEK_SET); wire_data_4byte(pcm_size, wav_fp); fclose(wav_fp); wav_fp = NULL; led_rec = 0; // REC end #if !defined(TARGET_GR_LYCHEE) play_start(); #endif } break; case INFO_TYPE_WRITE_DATA: if ((mail->result > 0) && (wav_fp != NULL)) { pcm_size += mail->result; fwrite(mail->p_data, sizeof(char), mail->result, wav_fp); } audio.read(mail->p_data, AUDIO_IN_BUF_SIZE, &audio_read_data); // Resetting read buffer break; default: // do nothing break; } mail_box.free(mail); } } } int main() { int count=0; #if MBED_CONF_APP_LCD rbsp_data_conf_t audio_write_data = {&callback_audio_write_end, NULL}; EasyAttach_Init(Display); Start_LCD_Display(); #else rbsp_data_conf_t audio_write_data = {NULL, NULL}; #endif // Microphone audio.micVolume(0.50); audio.outputVolume(0.50, 0.50); audio.power(true); audio.frequency(SAMPLE_RATE); SdUsbConnect storage(MOUNT_NAME); audioInTask.start(callback(audio_in_task)); // button setting button_0.fall(&rec_start); button_0.rise(&rec_stop); #if defined(TARGET_GR_LYCHEE) button_1.fall(&play_start); #endif while (1) { storage.wait_connect(); // Audio playback if (play_req != false) { while (led_rec == 1) { Thread::wait(10); // Wait write end } size_t read_size = AUDIO_OUT_BUF_SIZE; uint32_t index = 0; play_req = false; #if(0) //KNN(FINE_PATH,); char test_name[32]; sprintf(test_name,"/"MOUNT_NAME"/sample%03d.dat",count++); FILE *test_lib=fopen(test_name,"w"); fseek(test_lib, sizeof(wav_header_tbl), SEEK_SET); while (read_size == AUDIO_OUT_BUF_SIZE) { read_size = fread(audio_out_buf[index], sizeof(char), AUDIO_OUT_BUF_SIZE, test_lib); fclose(test_name); #else led_play = 1; FILE * fp_rb = fopen(FINE_PATH, "rb"); char test_name[32]; // sprintf(test_name,"/"MOUNT_NAME"/sample%03d.dat",count++); sprintf(test_name,"/"MOUNT_NAME"/recogniaze.dat"); FILE *test_lib=fopen(test_name,"w"); if (fp_rb != NULL) { fseek(fp_rb, sizeof(wav_header_tbl), SEEK_SET); while (read_size == AUDIO_OUT_BUF_SIZE) { read_size = fread(audio_out_buf[index], sizeof(char), AUDIO_OUT_BUF_SIZE, fp_rb); // audio.write(audio_out_buf[index], read_size, &audio_write_data); fwrite(audio_out_buf[index], sizeof(char), read_size, test_lib); index++; if (index >= AUDIO_OUT_BUF_NUM) { index = 0; } } fclose(fp_rb); fclose(test_lib); KNN("/"MOUNT_NAME"/recogniaze.dat",5000); // Thread::wait(AUDIO_OUT_WAIT); } led_play = 0; #endif } Thread::wait(100); } }