Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" 00002 #include "SdUsbConnect.h" 00003 #include "AUDIO_GRBoard.h" 00004 00005 #define MOUNT_NAME "storage" 00006 #define FINE_PATH "/"MOUNT_NAME"/wav_rec.wav" 00007 00008 #define SAMPLE_RATE (8000) 00009 #define AUDIO_IN_BUF_SIZE (2048) 00010 #define AUDIO_IN_BUF_NUM (16) 00011 #define AUDIO_OUT_BUF_SIZE (2048) 00012 #define AUDIO_OUT_BUF_NUM (8) 00013 #define AUDIO_OUT_WAIT ((AUDIO_OUT_BUF_SIZE * AUDIO_OUT_BUF_NUM / 4) * 1000 / SAMPLE_RATE) 00014 00015 #define INFO_TYPE_OPEN (0) 00016 #define INFO_TYPE_CLOSE (1) 00017 #define INFO_TYPE_WRITE_DATA (2) 00018 00019 AUDIO_GRBoard audio(0x80, AUDIO_OUT_BUF_NUM - 1, AUDIO_IN_BUF_NUM); // I2S Codec 00020 DigitalOut led_rec(LED_RED); 00021 DigitalOut led_play(LED_GREEN); 00022 InterruptIn button_0(USER_BUTTON0); 00023 #if defined(TARGET_GR_LYCHEE) 00024 InterruptIn button_1(USER_BUTTON1); 00025 #endif 00026 static bool play_req = false; 00027 00028 typedef struct { 00029 uint32_t info_type; 00030 void * p_data; 00031 int32_t result; 00032 } mail_t; 00033 Mail<mail_t, (AUDIO_IN_BUF_NUM + 2)> mail_box; 00034 00035 static Thread audioInTask(osPriorityNormal, 1024 * 8); 00036 //4 bytes aligned! No cache memory 00037 #if defined(__ICCARM__) 00038 #pragma data_alignment=4 00039 static uint8_t audio_in_buf[AUDIO_IN_BUF_NUM][AUDIO_IN_BUF_SIZE]@ ".mirrorram"; 00040 #pragma data_alignment=4 00041 static uint8_t audio_out_buf[AUDIO_OUT_BUF_NUM][AUDIO_OUT_BUF_SIZE]@ ".mirrorram"; 00042 #else 00043 static uint8_t audio_in_buf[AUDIO_IN_BUF_NUM][AUDIO_IN_BUF_SIZE]__attribute((section("NC_BSS"),aligned(4))); 00044 static uint8_t audio_out_buf[AUDIO_OUT_BUF_NUM][AUDIO_OUT_BUF_SIZE]__attribute((section("NC_BSS"),aligned(4))); 00045 #endif 00046 00047 // wav file header 00048 static const char wav_header_tbl[] = { 00049 0x52,0x49,0x46,0x46,0x00,0x00,0x00,0x00,0x57,0x41,0x56,0x45,0x66,0x6D,0x74,0x20, 00050 0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x80,0xBB,0x00,0x00,0x00,0xEE,0x02,0x00, 00051 0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61,0x00,0x00,0x00,0x00 00052 }; 00053 00054 #if MBED_CONF_APP_LCD 00055 #include "EasyAttach_CameraAndLCD.h" 00056 00057 #define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * 2) + 31u) & ~31u) 00058 #define FRAME_BUFFER_HEIGHT (LCD_PIXEL_HEIGHT) 00059 #if defined(__ICCARM__) 00060 #pragma data_alignment=32 00061 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; 00062 #else 00063 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); 00064 #endif 00065 DisplayBase Display; 00066 00067 static void Start_LCD_Display(void) { 00068 DisplayBase::rect_t rect; 00069 00070 memset(user_frame_buffer0, 0xFF, sizeof(user_frame_buffer0)); 00071 00072 rect.vs = 0; 00073 rect.vw = LCD_PIXEL_HEIGHT; 00074 rect.hs = 0; 00075 rect.hw = LCD_PIXEL_WIDTH; 00076 Display.Graphics_Read_Setting( 00077 DisplayBase::GRAPHICS_LAYER_0, 00078 (void *)user_frame_buffer0, 00079 FRAME_BUFFER_STRIDE, 00080 DisplayBase::GRAPHICS_FORMAT_RGB565, 00081 DisplayBase::WR_RD_WRSWA_32_16BIT, 00082 &rect 00083 ); 00084 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); 00085 00086 Thread::wait(50); 00087 EasyAttach_LcdBacklight(true); 00088 } 00089 00090 static void disp_audio_wave(int16_t * p_data, int32_t size, uint32_t color) { 00091 uint16_t * p_bottom_left_pos = (uint16_t *)&user_frame_buffer0[FRAME_BUFFER_STRIDE * (FRAME_BUFFER_HEIGHT - 1)]; 00092 uint16_t * p_frame_buf; 00093 uint32_t x = 0; 00094 uint32_t data_pos; 00095 uint32_t data_pos_last = ((p_data[0] + 0x8000ul) >> 8) + 8; 00096 int loop_num; 00097 00098 if (size < 0) { 00099 return; 00100 } 00101 00102 memset(user_frame_buffer0, 0xFF, sizeof(user_frame_buffer0)); 00103 for (int i = 0; i < size; i += 2) { 00104 data_pos = ((p_data[i] + 0x8000ul) >> 8) + 8; 00105 p_frame_buf = &p_bottom_left_pos[x]; 00106 00107 if (data_pos == data_pos_last) { 00108 loop_num = 3; 00109 p_frame_buf -= ((data_pos - 1) * LCD_PIXEL_WIDTH); 00110 } else if (data_pos > data_pos_last) { 00111 loop_num = data_pos - data_pos_last + 2; 00112 p_frame_buf -= (data_pos_last * LCD_PIXEL_WIDTH); 00113 } else { 00114 loop_num = data_pos_last - data_pos + 2; 00115 p_frame_buf -= ((data_pos - 1) * LCD_PIXEL_WIDTH); 00116 } 00117 00118 for (int j = 0; j < loop_num; j++) { 00119 *p_frame_buf = color; 00120 p_frame_buf -= LCD_PIXEL_WIDTH; 00121 } 00122 data_pos_last = data_pos; 00123 00124 x++; 00125 if (x >= LCD_PIXEL_WIDTH) { 00126 break; 00127 } 00128 } 00129 } 00130 00131 static void callback_audio_write_end(void * p_data, int32_t result, void * p_app_data) { 00132 disp_audio_wave((int16_t *)p_data, result / 2, 0x07E0); // Green 00133 } 00134 #endif // MBED_CONF_APP_LCD 00135 00136 static void send_mail(uint32_t info_type, void * p_data, int32_t result) { 00137 mail_t *mail = mail_box.alloc(); 00138 00139 if (mail != NULL) { 00140 mail->info_type = info_type; 00141 mail->p_data = p_data; 00142 mail->result = result; 00143 mail_box.put(mail); 00144 } 00145 } 00146 00147 static void rec_start(void) { 00148 send_mail(INFO_TYPE_OPEN, NULL, 0); 00149 } 00150 00151 static void rec_stop(void) { 00152 send_mail(INFO_TYPE_CLOSE, NULL, 0); 00153 } 00154 00155 static void play_start(void) { 00156 play_req = true; 00157 } 00158 00159 static void callback_audio_read_end(void * p_data, int32_t result, void * p_app_data) { 00160 #if MBED_CONF_APP_LCD 00161 if (led_play == 0) { 00162 uint32_t color; 00163 00164 if (led_rec == 0) { 00165 color = 0x001F; // Blue 00166 } else { 00167 color = 0xF800; // Red 00168 } 00169 disp_audio_wave((int16_t *)p_data, result / 2, color); 00170 } 00171 #endif 00172 send_mail(INFO_TYPE_WRITE_DATA, p_data, result); 00173 } 00174 00175 static void wire_data_4byte(uint32_t data, FILE * fp) { 00176 char work_buf[4]; 00177 00178 work_buf[0] = (uint8_t)(data >> 0); 00179 work_buf[1] = (uint8_t)(data >> 8); 00180 work_buf[2] = (uint8_t)(data >> 16); 00181 work_buf[3] = (uint8_t)(data >> 24); 00182 fwrite(work_buf, sizeof(char), 4, fp); 00183 } 00184 00185 void audio_in_task(void) { 00186 FILE * wav_fp = NULL; 00187 uint32_t pcm_size = 0; 00188 rbsp_data_conf_t audio_read_data = {&callback_audio_read_end, NULL}; 00189 00190 // Read buffer setting 00191 for (uint32_t i = 0; i < AUDIO_IN_BUF_NUM; i++) { 00192 if (audio.read(audio_in_buf[i], AUDIO_IN_BUF_SIZE, &audio_read_data) < 0) { 00193 printf("read error\n"); 00194 } 00195 } 00196 00197 while (1) { 00198 osEvent evt = mail_box.get(); 00199 if (evt.status == osEventMail) { 00200 mail_t *mail = (mail_t *)evt.value.p; 00201 00202 switch (mail->info_type) { 00203 case INFO_TYPE_OPEN: 00204 wav_fp = fopen(FINE_PATH, "wb"); 00205 if (wav_fp != NULL) { 00206 led_rec = 1; // REC start 00207 pcm_size = 0; 00208 fwrite(wav_header_tbl, sizeof(char), sizeof(wav_header_tbl), wav_fp); 00209 } 00210 break; 00211 00212 case INFO_TYPE_CLOSE: 00213 if (wav_fp != NULL) { 00214 // Set "RIFF" ChunkSize 00215 fseek(wav_fp, 4, SEEK_SET); 00216 wire_data_4byte(sizeof(wav_header_tbl) - 8 + pcm_size, wav_fp); 00217 // Set SampleRate 00218 fseek(wav_fp, 24, SEEK_SET); 00219 wire_data_4byte(SAMPLE_RATE, wav_fp); 00220 // Set ByteRate 00221 wire_data_4byte(SAMPLE_RATE * 2 * 2, wav_fp); 00222 // Set "data" ChunkSize 00223 fseek(wav_fp, 40, SEEK_SET); 00224 wire_data_4byte(pcm_size, wav_fp); 00225 fclose(wav_fp); 00226 wav_fp = NULL; 00227 led_rec = 0; // REC end 00228 #if !defined(TARGET_GR_LYCHEE) 00229 play_start(); 00230 #endif 00231 } 00232 break; 00233 00234 case INFO_TYPE_WRITE_DATA: 00235 if ((mail->result > 0) && (wav_fp != NULL)) { 00236 pcm_size += mail->result; 00237 fwrite(mail->p_data, sizeof(char), mail->result, wav_fp); 00238 } 00239 audio.read(mail->p_data, AUDIO_IN_BUF_SIZE, &audio_read_data); // Resetting read buffer 00240 break; 00241 00242 default: 00243 // do nothing 00244 break; 00245 } 00246 mail_box.free(mail); 00247 } 00248 } 00249 } 00250 00251 int main() { 00252 #if MBED_CONF_APP_LCD 00253 rbsp_data_conf_t audio_write_data = {&callback_audio_write_end, NULL}; 00254 00255 EasyAttach_Init(Display); 00256 Start_LCD_Display(); 00257 #else 00258 rbsp_data_conf_t audio_write_data = {NULL, NULL}; 00259 #endif 00260 00261 // Microphone 00262 audio.micVolume(0.50); 00263 audio.outputVolume(0.50, 0.50); 00264 audio.power(true); 00265 audio.frequency(SAMPLE_RATE); 00266 00267 SdUsbConnect storage(MOUNT_NAME); 00268 audioInTask.start(callback(audio_in_task)); 00269 00270 // button setting 00271 button_0.fall(&rec_start); 00272 button_0.rise(&rec_stop); 00273 #if defined(TARGET_GR_LYCHEE) 00274 button_1.fall(&play_start); 00275 #endif 00276 00277 while (1) { 00278 storage.wait_connect(); 00279 00280 // Audio playback 00281 if (play_req != false) { 00282 while (led_rec == 1) { 00283 Thread::wait(10); // Wait write end 00284 } 00285 00286 size_t read_size = AUDIO_OUT_BUF_SIZE; 00287 uint32_t index = 0; 00288 00289 play_req = false; 00290 led_play = 1; 00291 FILE * fp_rb = fopen(FINE_PATH, "rb"); 00292 if (fp_rb != NULL) { 00293 fseek(fp_rb, sizeof(wav_header_tbl), SEEK_SET); 00294 while (read_size == AUDIO_OUT_BUF_SIZE) { 00295 read_size = fread(audio_out_buf[index], sizeof(char), AUDIO_OUT_BUF_SIZE, fp_rb); 00296 audio.write(audio_out_buf[index], read_size, &audio_write_data); 00297 index++; 00298 if (index >= AUDIO_OUT_BUF_NUM) { 00299 index = 0; 00300 } 00301 } 00302 fclose(fp_rb); 00303 Thread::wait(AUDIO_OUT_WAIT); 00304 } 00305 led_play = 0; 00306 } 00307 Thread::wait(100); 00308 } 00309 }
Generated on Thu Jul 14 2022 00:08:17 by
1.7.2