Using KNN to realize Voise Control
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "mbed.h" 00002 #include "SdUsbConnect.h" 00003 #include "AUDIO_GRBoard.h" 00004 00005 00006 #define MOUNT_NAME "storage" 00007 #define FINE_PATH "/"MOUNT_NAME"/wav_rec.wav" 00008 00009 00010 00011 #define SAMPLE_RATE (8000) 00012 #define AUDIO_IN_BUF_SIZE (2048) 00013 #define AUDIO_IN_BUF_NUM (16) 00014 #define AUDIO_OUT_BUF_SIZE (2048) 00015 #define AUDIO_OUT_BUF_NUM (8) 00016 #define AUDIO_OUT_WAIT ((AUDIO_OUT_BUF_SIZE * AUDIO_OUT_BUF_NUM / 4) * 1000 / SAMPLE_RATE) 00017 00018 #define INFO_TYPE_OPEN (0) 00019 #define INFO_TYPE_CLOSE (1) 00020 #define INFO_TYPE_WRITE_DATA (2) 00021 00022 DigitalOut led1(LED1); 00023 DigitalOut led2(LED2); 00024 DigitalOut led3(LED3); 00025 DigitalOut led4(LED4); 00026 00027 AUDIO_GRBoard audio(0x80, AUDIO_OUT_BUF_NUM - 1, AUDIO_IN_BUF_NUM); // I2S Codec 00028 int led_rec; 00029 int led_play; 00030 InterruptIn button_0(USER_BUTTON0); 00031 #if defined(TARGET_GR_LYCHEE) 00032 InterruptIn button_1(USER_BUTTON1); 00033 #endif 00034 static bool play_req = false; 00035 00036 typedef struct { 00037 uint32_t info_type; 00038 void * p_data; 00039 int32_t result; 00040 } mail_t; 00041 Mail<mail_t, (AUDIO_IN_BUF_NUM + 2)> mail_box; 00042 00043 static Thread audioInTask(osPriorityNormal, 1024 * 8); 00044 //4 bytes aligned! No cache memory 00045 #if defined(__ICCARM__) 00046 #pragma data_alignment=4 00047 static uint8_t audio_in_buf[AUDIO_IN_BUF_NUM][AUDIO_IN_BUF_SIZE]@ ".mirrorram"; 00048 #pragma data_alignment=4 00049 static uint8_t audio_out_buf[AUDIO_OUT_BUF_NUM][AUDIO_OUT_BUF_SIZE]@ ".mirrorram"; 00050 #else 00051 static uint8_t audio_in_buf[AUDIO_IN_BUF_NUM][AUDIO_IN_BUF_SIZE]__attribute((section("NC_BSS"),aligned(4))); 00052 static uint8_t audio_out_buf[AUDIO_OUT_BUF_NUM][AUDIO_OUT_BUF_SIZE]__attribute((section("NC_BSS"),aligned(4))); 00053 #endif 00054 00055 // wav file header 00056 static const char wav_header_tbl[] = { 00057 0x52,0x49,0x46,0x46,0x00,0x00,0x00,0x00,0x57,0x41,0x56,0x45,0x66,0x6D,0x74,0x20, 00058 0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x80,0xBB,0x00,0x00,0x00,0xEE,0x02,0x00, 00059 0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61,0x00,0x00,0x00,0x00 00060 }; 00061 00062 #if MBED_CONF_APP_LCD 00063 #include "EasyAttach_CameraAndLCD.h" 00064 00065 #define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * 2) + 31u) & ~31u) 00066 #define FRAME_BUFFER_HEIGHT (LCD_PIXEL_HEIGHT) 00067 #if defined(__ICCARM__) 00068 #pragma data_alignment=32 00069 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; 00070 #else 00071 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); 00072 #endif 00073 DisplayBase Display; 00074 00075 static void Start_LCD_Display(void) { 00076 DisplayBase::rect_t rect; 00077 00078 memset(user_frame_buffer0, 0xFF, sizeof(user_frame_buffer0)); 00079 00080 rect.vs = 0; 00081 rect.vw = LCD_PIXEL_HEIGHT; 00082 rect.hs = 0; 00083 rect.hw = LCD_PIXEL_WIDTH; 00084 Display.Graphics_Read_Setting( 00085 DisplayBase::GRAPHICS_LAYER_0, 00086 (void *)user_frame_buffer0, 00087 FRAME_BUFFER_STRIDE, 00088 DisplayBase::GRAPHICS_FORMAT_RGB565, 00089 DisplayBase::WR_RD_WRSWA_32_16BIT, 00090 &rect 00091 ); 00092 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); 00093 00094 Thread::wait(50); 00095 EasyAttach_LcdBacklight(true); 00096 } 00097 00098 static void disp_audio_wave(int16_t * p_data, int32_t size, uint32_t color) { 00099 uint16_t * p_bottom_left_pos = (uint16_t *)&user_frame_buffer0[FRAME_BUFFER_STRIDE * (FRAME_BUFFER_HEIGHT - 1)]; 00100 uint16_t * p_frame_buf; 00101 uint32_t x = 0; 00102 uint32_t data_pos; 00103 uint32_t data_pos_last = ((p_data[0] + 0x8000ul) >> 8) + 8; 00104 int loop_num; 00105 00106 if (size < 0) { 00107 return; 00108 } 00109 00110 memset(user_frame_buffer0, 0xFF, sizeof(user_frame_buffer0)); 00111 for (int i = 0; i < size; i += 2) { 00112 data_pos = ((p_data[i] + 0x8000ul) >> 8) + 8; 00113 p_frame_buf = &p_bottom_left_pos[x]; 00114 00115 if (data_pos == data_pos_last) { 00116 loop_num = 3; 00117 p_frame_buf -= ((data_pos - 1) * LCD_PIXEL_WIDTH); 00118 } else if (data_pos > data_pos_last) { 00119 loop_num = data_pos - data_pos_last + 2; 00120 p_frame_buf -= (data_pos_last * LCD_PIXEL_WIDTH); 00121 } else { 00122 loop_num = data_pos_last - data_pos + 2; 00123 p_frame_buf -= ((data_pos - 1) * LCD_PIXEL_WIDTH); 00124 } 00125 00126 for (int j = 0; j < loop_num; j++) { 00127 *p_frame_buf = color; 00128 p_frame_buf -= LCD_PIXEL_WIDTH; 00129 } 00130 data_pos_last = data_pos; 00131 00132 x++; 00133 if (x >= LCD_PIXEL_WIDTH) { 00134 break; 00135 } 00136 } 00137 } 00138 00139 00140 static void callback_audio_write_end(void * p_data, int32_t result, void * p_app_data) { 00141 disp_audio_wave((int16_t *)p_data, result / 2, 0x07E0); // Green 00142 } 00143 #endif // MBED_CONF_APP_LCD 00144 00145 static void send_mail(uint32_t info_type, void * p_data, int32_t result) { 00146 mail_t *mail = mail_box.alloc(); 00147 00148 if (mail != NULL) { 00149 mail->info_type = info_type; 00150 mail->p_data = p_data; 00151 mail->result = result; 00152 mail_box.put(mail); 00153 } 00154 } 00155 00156 static void rec_start(void) { 00157 send_mail(INFO_TYPE_OPEN, NULL, 0); 00158 } 00159 00160 static void rec_stop(void) { 00161 send_mail(INFO_TYPE_CLOSE, NULL, 0); 00162 } 00163 00164 static void play_start(void) { 00165 play_req = true; 00166 } 00167 00168 00169 00170 static void KNN(char *file_name, int dat_size) 00171 { 00172 double *cal_dat; 00173 double *com_dat; 00174 int record; 00175 int NUM_LIB=119; 00176 int class_num; 00177 double knn=10000000000; 00178 double temp=0; 00179 com_dat=(double*)malloc(sizeof(double)*dat_size); 00180 00181 FILE *input_res,*compare_res; 00182 char *lib_name; 00183 input_res=fopen(file_name,"rb"); 00184 for(int i=0;i<dat_size;i++) 00185 { 00186 fscanf(input_res,"lf",&cal_dat[i]); 00187 } 00188 fclose(input_res); 00189 00190 for(int i=0;i<NUM_LIB;i++) 00191 { 00192 temp=0; 00193 sprintf(lib_name,"sample%03d.dat",i); 00194 compare_res=fopen(lib_name,"w"); 00195 for(int i=0;i<dat_size;i++){ 00196 fscanf(compare_res,"lf",&com_dat[i]); 00197 } 00198 for(int i=0;i<dat_size;i++) 00199 { 00200 temp+=pow((cal_dat[i]-com_dat[i]),2); 00201 } 00202 if (temp<knn) 00203 { 00204 knn=temp; 00205 record=i; 00206 } 00207 } 00208 if(0<record||record<=25||115<record||record<=119) 00209 //output is bird 00210 { 00211 class_num=1; 00212 led1=!led1; 00213 } 00214 //output is monkey 00215 else if(25<record||record<=54) 00216 { 00217 class_num=2; 00218 led2=!led2;} 00219 //output is cat 00220 else if(54<record||record<=85||record==115) 00221 { 00222 class_num=3; 00223 led3=!led3; 00224 } 00225 //output is dog 00226 else if(85<record||record<=114) 00227 {class_num=4; 00228 led4=!led4; 00229 } 00230 00231 } 00232 00233 00234 00235 static void callback_audio_read_end(void * p_data, int32_t result, void * p_app_data) { 00236 #if MBED_CONF_APP_LCD 00237 if (led_play == 0) { 00238 uint32_t color; 00239 00240 if (led_rec == 0) { 00241 color = 0x001F; // Blue 00242 } else { 00243 color = 0xF800; // Red 00244 } 00245 disp_audio_wave((int16_t *)p_data, result / 2, color); 00246 } 00247 #endif 00248 send_mail(INFO_TYPE_WRITE_DATA, p_data, result); 00249 } 00250 00251 static void wire_data_4byte(uint32_t data, FILE * fp) { 00252 char work_buf[4]; 00253 00254 work_buf[0] = (uint8_t)(data >> 0); 00255 work_buf[1] = (uint8_t)(data >> 8); 00256 work_buf[2] = (uint8_t)(data >> 16); 00257 work_buf[3] = (uint8_t)(data >> 24); 00258 fwrite(work_buf, sizeof(char), 4, fp); 00259 } 00260 00261 void audio_in_task(void) { 00262 FILE * wav_fp = NULL; 00263 uint32_t pcm_size = 0; 00264 rbsp_data_conf_t audio_read_data = {&callback_audio_read_end, NULL}; 00265 00266 // Read buffer setting 00267 for (uint32_t i = 0; i < AUDIO_IN_BUF_NUM; i++) { 00268 if (audio.read(audio_in_buf[i], AUDIO_IN_BUF_SIZE, &audio_read_data) < 0) { 00269 printf("read error\n"); 00270 } 00271 } 00272 00273 while (1) { 00274 osEvent evt = mail_box.get(); 00275 if (evt.status == osEventMail) { 00276 mail_t *mail = (mail_t *)evt.value.p; 00277 00278 switch (mail->info_type) { 00279 case INFO_TYPE_OPEN: 00280 wav_fp = fopen(FINE_PATH, "wb"); 00281 if (wav_fp != NULL) { 00282 led_rec = 1; // REC start 00283 pcm_size = 0; 00284 fwrite(wav_header_tbl, sizeof(char), sizeof(wav_header_tbl), wav_fp); 00285 } 00286 break; 00287 00288 case INFO_TYPE_CLOSE: 00289 if (wav_fp != NULL) { 00290 // Set "RIFF" ChunkSize 00291 fseek(wav_fp, 4, SEEK_SET); 00292 wire_data_4byte(sizeof(wav_header_tbl) - 8 + pcm_size, wav_fp); 00293 // Set SampleRate 00294 fseek(wav_fp, 24, SEEK_SET); 00295 wire_data_4byte(SAMPLE_RATE, wav_fp); 00296 // Set ByteRate 00297 wire_data_4byte(SAMPLE_RATE * 2 * 2, wav_fp); 00298 // Set "data" ChunkSize 00299 fseek(wav_fp, 40, SEEK_SET); 00300 wire_data_4byte(pcm_size, wav_fp); 00301 fclose(wav_fp); 00302 wav_fp = NULL; 00303 led_rec = 0; // REC end 00304 #if !defined(TARGET_GR_LYCHEE) 00305 play_start(); 00306 #endif 00307 } 00308 break; 00309 00310 case INFO_TYPE_WRITE_DATA: 00311 if ((mail->result > 0) && (wav_fp != NULL)) { 00312 pcm_size += mail->result; 00313 fwrite(mail->p_data, sizeof(char), mail->result, wav_fp); 00314 } 00315 audio.read(mail->p_data, AUDIO_IN_BUF_SIZE, &audio_read_data); // Resetting read buffer 00316 break; 00317 00318 default: 00319 // do nothing 00320 break; 00321 } 00322 mail_box.free(mail); 00323 } 00324 } 00325 } 00326 00327 int main() { 00328 00329 int count=0; 00330 00331 #if MBED_CONF_APP_LCD 00332 rbsp_data_conf_t audio_write_data = {&callback_audio_write_end, NULL}; 00333 00334 EasyAttach_Init(Display); 00335 Start_LCD_Display(); 00336 #else 00337 rbsp_data_conf_t audio_write_data = {NULL, NULL}; 00338 #endif 00339 00340 // Microphone 00341 audio.micVolume(0.50); 00342 audio.outputVolume(0.50, 0.50); 00343 audio.power(true); 00344 audio.frequency(SAMPLE_RATE); 00345 00346 SdUsbConnect storage(MOUNT_NAME); 00347 audioInTask.start(callback(audio_in_task)); 00348 00349 // button setting 00350 button_0.fall(&rec_start); 00351 button_0.rise(&rec_stop); 00352 #if defined(TARGET_GR_LYCHEE) 00353 button_1.fall(&play_start); 00354 #endif 00355 00356 while (1) { 00357 storage.wait_connect(); 00358 00359 // Audio playback 00360 if (play_req != false) { 00361 while (led_rec == 1) { 00362 Thread::wait(10); // Wait write end 00363 } 00364 00365 size_t read_size = AUDIO_OUT_BUF_SIZE; 00366 uint32_t index = 0; 00367 00368 play_req = false; 00369 #if(0) 00370 //KNN(FINE_PATH,); 00371 char test_name[32]; 00372 sprintf(test_name,"/"MOUNT_NAME"/sample%03d.dat",count++); 00373 FILE *test_lib=fopen(test_name,"w"); 00374 fseek(test_lib, sizeof(wav_header_tbl), SEEK_SET); 00375 while (read_size == AUDIO_OUT_BUF_SIZE) { 00376 read_size = fread(audio_out_buf[index], sizeof(char), AUDIO_OUT_BUF_SIZE, test_lib); 00377 fclose(test_name); 00378 #else 00379 led_play = 1; 00380 FILE * fp_rb = fopen(FINE_PATH, "rb"); 00381 00382 char test_name[32]; 00383 // sprintf(test_name,"/"MOUNT_NAME"/sample%03d.dat",count++); 00384 sprintf(test_name,"/"MOUNT_NAME"/recogniaze.dat"); 00385 FILE *test_lib=fopen(test_name,"w"); 00386 00387 00388 if (fp_rb != NULL) { 00389 fseek(fp_rb, sizeof(wav_header_tbl), SEEK_SET); 00390 while (read_size == AUDIO_OUT_BUF_SIZE) { 00391 read_size = fread(audio_out_buf[index], sizeof(char), AUDIO_OUT_BUF_SIZE, fp_rb); 00392 00393 // audio.write(audio_out_buf[index], read_size, &audio_write_data); 00394 00395 fwrite(audio_out_buf[index], sizeof(char), read_size, test_lib); 00396 00397 00398 00399 index++; 00400 if (index >= AUDIO_OUT_BUF_NUM) { 00401 index = 0; 00402 } 00403 } 00404 fclose(fp_rb); 00405 fclose(test_lib); 00406 KNN("/"MOUNT_NAME"/recogniaze.dat",5000); 00407 00408 // Thread::wait(AUDIO_OUT_WAIT); 00409 } 00410 led_play = 0; 00411 #endif 00412 } 00413 Thread::wait(100); 00414 00415 00416 } 00417 } 00418
Generated on Wed Sep 14 2022 10:43:43 by
1.7.2