/** * @brief Stop audio stream. * @param None. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StopRec(void) { uint32_t byteswritten = 0; AUDIO_RECORDER_ErrorTypdef audio_error = AUDIO_RECORDER_ERROR_IO; BSP_AUDIO_IN_Stop(); haudio.in.state = AUDIO_RECORDER_IDLE; if(f_lseek(&wav_file, 0) == FR_OK) { /* Update the wav file header save it into wav file */ WavProcess_HeaderUpdate(pHeaderBuff, &AudioInfo); if(f_write(&wav_file, pHeaderBuff, sizeof(WAV_InfoTypedef), (void*)&byteswritten) == FR_OK) { audio_error = AUDIO_RECORDER_ERROR_NONE; } } haudio.in.state = AUDIO_RECORDER_SUSPENDED; f_close(&wav_file); _cbNotifyStateChange(); if(AudioThreadId != 0) { osThreadSuspend(AudioThreadId); } return audio_error; }
/** * @brief Update the recorded data. * @param None * @retval None */ void WaveRecorderProcess(void) { /* Current size of the recorded buffer */ uint32_t byteswritten = 0; WaveCounter = 0; LEDsState = LEDS_OFF; /* Remove Wave file if it exists on USB Flash Disk */ f_unlink(REC_WAVE_NAME); /* Open the file to write on it */ if((AppliState == APPLICATION_IDLE) || (f_open(&WavFile, REC_WAVE_NAME, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)) { while(1) { /* Toggle LED5 in infinite loop to signal that: USB Flash Disk is not connected/removed or an issue has occurred when creating/opening Wave file */ BSP_LED_Toggle(LED5); } } else { WaveRecStatus = 1; } /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); /* Write the header Wave */ f_write(&WavFile, pHeaderBuff, 44, (void *)&byteswritten); /* Increment the Wave counter */ BufferCtl.fptr = byteswritten; BufferCtl.offset = BUFFER_OFFSET_NONE; BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_AUDIO_IN_Record((uint16_t*)&InternalBuffer[0], INTERNAL_BUFF_SIZE); /* Reset the time recording base variable */ TimeRecBase = 0; ITCounter = 0; LEDsState = LED3_TOGGLE; while(AppliState != APPLICATION_IDLE) { /* Wait for the recording time */ if(TimeRecBase <= DEFAULT_TIME_REC) { /* Check if there are Data to write in Usb Key */ if(AUDIODataReady == 1) { /* write buffer in file */ res = f_write(&WavFile, (uint8_t*)(WrBuffer+AUDIOBuffOffset), WR_BUFFER_SIZE, (void*)&byteswritten); if(res != FR_OK) { Error_Handler(); } BufferCtl.fptr += byteswritten; AUDIODataReady = 0; } /* User button pressed */ if(CmdIndex != CMD_RECORD) { /* Stop Audio Recording */ WaveRecorderStop(); /* Switch Command Index to Play */ CmdIndex = CMD_PLAY; /* Toggoling LED6 to signal Play */ LEDsState = LED6_TOGGLE; break; } } else /* End of recording time DEFAULT_TIME_REC */ { /* Stop Audio Recording */ WaveRecorderStop(); /* Change Command Index to Stop */ CmdIndex = CMD_STOP; /* Toggoling LED4 to signal Stop */ LEDsState = LED4_TOGGLE; AUDIODataReady = 0; break; } } /* Update the data length in the header of the recorded Wave */ f_lseek(&WavFile, 0); /* Parse the wav file header and extract required information */ WavProcess_HeaderUpdate(pHeaderBuff, &WaveFormat); f_write(&WavFile, pHeaderBuff, 44, (void*)&byteswritten); /* Close file and unmount MyFilesystem */ f_close (&WavFile); f_mount(NULL, 0, 1); /* Change Command Index to Play */ CmdIndex = CMD_PLAY; }
/** * @brief Manages Audio process. * @param None * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_REC_Process(void) { uint32_t byteswritten = 0; AUDIO_ErrorTypeDef audio_error = AUDIO_ERROR_NONE; uint32_t elapsed_time; static uint32_t prev_elapsed_time = 0xFFFFFFFF; uint8_t str[10]; switch(AudioState) { case AUDIO_STATE_RECORD: /* MAX Recording time reached, so stop audio interface and close file */ if(BufferCtl.fptr >= REC_SAMPLE_LENGTH) { AudioState = AUDIO_STATE_STOP; break; } /* Check if there are Data to write in Usb Key */ if(BufferCtl.wr_state == BUFFER_FULL) { /* write buffer in file */ if(f_write(&WavFile, (uint8_t*)(BufferCtl.pcm_buff + BufferCtl.offset), AUDIO_IN_PCM_BUFFER_SIZE, (void*)&byteswritten) != FR_OK) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(16, (uint8_t *)"RECORD FAIL"); return AUDIO_ERROR_IO; } BufferCtl.fptr += byteswritten; BufferCtl.wr_state = BUFFER_EMPTY; } /* Display elapsed time */ elapsed_time = BufferCtl.fptr / (DEFAULT_AUDIO_IN_FREQ * DEFAULT_AUDIO_IN_CHANNEL_NBR * 2); if(prev_elapsed_time != elapsed_time) { prev_elapsed_time = elapsed_time; sprintf((char *)str, "[%02d:%02d]", (int)(elapsed_time /60), (int)(elapsed_time%60)); BSP_LCD_SetTextColor(LCD_COLOR_CYAN); BSP_LCD_DisplayStringAt(263, LINE(8), str, LEFT_MODE); sprintf((char *)str, "%4d KB", (int)((int32_t)BufferCtl.fptr/1024)); BSP_LCD_DisplayStringAt(83, LINE(8), str, LEFT_MODE); } break; case AUDIO_STATE_STOP: /* Stop recorder */ BSP_AUDIO_IN_Stop(); /* Create a new file system */ if(f_lseek(&WavFile, 0) == FR_OK) { /* Update the wav file header save it into wav file */ WavProcess_HeaderUpdate(pHeaderBuff, &WaveFormat); if(f_write(&WavFile, pHeaderBuff, sizeof(WAVE_FormatTypeDef), (void*)&byteswritten) == FR_OK) { audio_error = AUDIO_ERROR_EOF; } else { audio_error = AUDIO_ERROR_IO; BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(16, (uint8_t *)"RECORD FAIL"); } } else { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(16, (uint8_t *)"RECORD FAIL"); audio_error = AUDIO_ERROR_IO; } AudioState = AUDIO_STATE_IDLE; /* Close file */ f_close(&WavFile); break; case AUDIO_STATE_PAUSE: BSP_LCD_DisplayStringAt(250, LINE(14), (uint8_t *)" [PAUSE] ", LEFT_MODE); BSP_AUDIO_IN_Pause(); AudioState = AUDIO_STATE_WAIT; break; case AUDIO_STATE_RESUME: BSP_LCD_DisplayStringAt(250, LINE(14), (uint8_t *)" [RECORD] ", LEFT_MODE); BSP_AUDIO_IN_Resume(); AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_VOLUME_UP: if(AudioInVolume <= 90) { AudioInVolume += 10; } BSP_AUDIO_IN_SetVolume(AudioInVolume); AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_VOLUME_DOWN: if(AudioInVolume >= 10) { AudioInVolume -= 10; } BSP_AUDIO_IN_SetVolume(AudioInVolume); AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_NEXT: case AUDIO_STATE_PREVIOUS: AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_WAIT: case AUDIO_STATE_IDLE: case AUDIO_STATE_INIT: default: /* Do Nothing */ break; } return audio_error; }
/** * @brief Manages Audio process. * @param None * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_REC_Process(void) { uint32_t byteswritten = 0; AUDIO_ErrorTypeDef audio_error = AUDIO_ERROR_NONE; uint32_t elapsed_time; static uint32_t prev_elapsed_time = 0xFFFFFFFF; uint8_t str[10]; static TS_StateTypeDef TS_State={0}; switch(AudioState) { case AUDIO_STATE_PRERECORD: if(TS_State.touchDetected == 1) /* If previous touch has not been released, we don't proceed any touch command */ { BSP_TS_GetState(&TS_State); } else { BSP_TS_GetState(&TS_State); if(TS_State.touchDetected == 1) { if ((TS_State.touchX[0] > TOUCH_STOP_XMIN) && (TS_State.touchX[0] < TOUCH_STOP_XMAX) && (TS_State.touchY[0] > TOUCH_STOP_YMIN) && (TS_State.touchY[0] < TOUCH_STOP_YMAX)) { AudioState = AUDIO_STATE_STOP; } else if ((TS_State.touchX[0] > TOUCH_RECORD_XMIN) && (TS_State.touchX[0] < TOUCH_RECORD_XMAX) && (TS_State.touchY[0] > TOUCH_RECORD_YMIN) && (TS_State.touchY[0] < TOUCH_RECORD_YMAX)) { display_update = 1; AudioState = AUDIO_STATE_RECORD; } else if((TS_State.touchX[0] > TOUCH_VOL_MINUS_XMIN) && (TS_State.touchX[0] < TOUCH_VOL_MINUS_XMAX) && (TS_State.touchY[0] > TOUCH_VOL_MINUS_YMIN) && (TS_State.touchY[0] < TOUCH_VOL_MINUS_YMAX)) { AudioState = AUDIO_STATE_VOLUME_DOWN; if(uwVolume >= 5) { uwVolume -= 5; } } else if((TS_State.touchX[0] > TOUCH_VOL_PLUS_XMIN) && (TS_State.touchX[0] < TOUCH_VOL_PLUS_XMAX) && (TS_State.touchY[0] > TOUCH_VOL_PLUS_YMIN) && (TS_State.touchY[0] < TOUCH_VOL_PLUS_YMAX)) { AudioState = AUDIO_STATE_VOLUME_UP; if(uwVolume <= 95) { uwVolume += 5; } } if ((AudioState == AUDIO_STATE_VOLUME_DOWN) || (AudioState == AUDIO_STATE_VOLUME_UP)) { sprintf((char *)str, "Volume : %d ", (int)uwVolume); BSP_LCD_ClearStringLine(7); BSP_LCD_DisplayStringAtLine(7, str); BSP_AUDIO_IN_SetVolume(uwVolume); AudioState = AUDIO_STATE_PRERECORD; } } else { AudioState = AUDIO_STATE_PRERECORD; } } break; case AUDIO_STATE_RECORD: if (display_update) { BSP_LCD_SetTextColor(LCD_COLOR_RED); /* Display red record circle */ BSP_LCD_FillCircle((TOUCH_RECORD_XMAX+TOUCH_RECORD_XMIN)/2, (TOUCH_RECORD_YMAX+TOUCH_RECORD_YMIN)/2, (TOUCH_RECORD_XMAX-TOUCH_RECORD_XMIN)/2); BSP_LCD_SetFont(&LCD_LOG_TEXT_FONT); BSP_LCD_SetTextColor(LCD_COLOR_YELLOW); BSP_LCD_DisplayStringAt(247, LINE(6), (uint8_t *)" [RECORD]", LEFT_MODE); display_update = 0; } if(TS_State.touchDetected == 1) /* If previous touch has not been released, we don't proceed any touch command */ { BSP_TS_GetState(&TS_State); } else { BSP_TS_GetState(&TS_State); if(TS_State.touchDetected == 1) { if ((TS_State.touchX[0] > TOUCH_STOP_XMIN) && (TS_State.touchX[0] < TOUCH_STOP_XMAX) && (TS_State.touchY[0] > TOUCH_STOP_YMIN) && (TS_State.touchY[0] < TOUCH_STOP_YMAX)) { AudioState = AUDIO_STATE_STOP; } else if ((TS_State.touchX[0] > TOUCH_PAUSE_XMIN) && (TS_State.touchX[0] < TOUCH_PAUSE_XMAX) && (TS_State.touchY[0] > TOUCH_PAUSE_YMIN) && (TS_State.touchY[0] < TOUCH_PAUSE_YMAX)) { AudioState = AUDIO_STATE_PAUSE; } else if((TS_State.touchX[0] > TOUCH_VOL_MINUS_XMIN) && (TS_State.touchX[0] < TOUCH_VOL_MINUS_XMAX) && (TS_State.touchY[0] > TOUCH_VOL_MINUS_YMIN) && (TS_State.touchY[0] < TOUCH_VOL_MINUS_YMAX)) { AudioState = AUDIO_STATE_VOLUME_DOWN; } else if((TS_State.touchX[0] > TOUCH_VOL_PLUS_XMIN) && (TS_State.touchX[0] < TOUCH_VOL_PLUS_XMAX) && (TS_State.touchY[0] > TOUCH_VOL_PLUS_YMIN) && (TS_State.touchY[0] < TOUCH_VOL_PLUS_YMAX)) { AudioState = AUDIO_STATE_VOLUME_UP; } } } /* MAX Recording time reached, so stop audio interface and close file */ if(BufferCtl.fptr >= REC_SAMPLE_LENGTH) { display_update = 1; AudioState = AUDIO_STATE_STOP; break; } /* Check if there are Data to write to USB Key */ if(BufferCtl.wr_state == BUFFER_FULL) { /* write buffer in file */ if(f_write(&WavFile, (uint8_t*)(BufferCtl.pcm_buff + BufferCtl.offset), AUDIO_IN_PCM_BUFFER_SIZE, (void*)&byteswritten) != FR_OK) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(14, (uint8_t *)"RECORD FAIL"); return AUDIO_ERROR_IO; } BufferCtl.fptr += byteswritten; BufferCtl.wr_state = BUFFER_EMPTY; } /* Display elapsed time */ elapsed_time = BufferCtl.fptr / (DEFAULT_AUDIO_IN_FREQ * DEFAULT_AUDIO_IN_CHANNEL_NBR * 2); if(prev_elapsed_time != elapsed_time) { prev_elapsed_time = elapsed_time; sprintf((char *)str, "[%02d:%02d]", (int)(elapsed_time /60), (int)(elapsed_time%60)); BSP_LCD_SetTextColor(LCD_COLOR_YELLOW); BSP_LCD_DisplayStringAt(263, LINE(8), str, LEFT_MODE); sprintf((char *)str, "%4d KB", (int)((int32_t)BufferCtl.fptr/1024)); BSP_LCD_DisplayStringAt(83, LINE(8), str, LEFT_MODE); } break; case AUDIO_STATE_STOP: /* Stop recorder */ BSP_AUDIO_IN_Stop(); BSP_LCD_SetTextColor(LCD_COLOR_CYAN); /* Display blue cyan record circle */ BSP_LCD_FillCircle((TOUCH_RECORD_XMAX+TOUCH_RECORD_XMIN)/2, (TOUCH_RECORD_YMAX+TOUCH_RECORD_YMIN)/2, (TOUCH_RECORD_XMAX-TOUCH_RECORD_XMIN)/2); BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_FillRect(TOUCH_STOP_XMIN, TOUCH_STOP_YMIN , /* Stop rectangle */ TOUCH_STOP_XMAX - TOUCH_STOP_XMIN, TOUCH_STOP_YMAX - TOUCH_STOP_YMIN); BSP_LCD_SetTextColor(LCD_COLOR_CYAN); display_update = 1; HAL_Delay(150); if(f_lseek(&WavFile, 0) == FR_OK) { /* Update the wav file header save it into wav file */ WavProcess_HeaderUpdate(pHeaderBuff, &WaveFormat); if(f_write(&WavFile, pHeaderBuff, sizeof(WAVE_FormatTypeDef), (void*)&byteswritten) == FR_OK) { audio_error = AUDIO_ERROR_EOF; } else { audio_error = AUDIO_ERROR_IO; BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(14, (uint8_t *)"RECORD FAIL"); } } else { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(14, (uint8_t *)"RECORD FAIL"); audio_error = AUDIO_ERROR_IO; } AudioState = AUDIO_STATE_IDLE; /* Close file */ f_close(&WavFile); break; case AUDIO_STATE_PAUSE: BSP_LCD_SetTextColor(LCD_COLOR_RED); /* Displays red pause rectangles */ BSP_LCD_FillRect(TOUCH_PAUSE_XMIN, TOUCH_PAUSE_YMIN , 15, TOUCH_PAUSE_YMAX - TOUCH_PAUSE_YMIN); BSP_LCD_FillRect(TOUCH_PAUSE_XMIN + 20, TOUCH_PAUSE_YMIN, 15, TOUCH_PAUSE_YMAX - TOUCH_PAUSE_YMIN); BSP_LCD_SetTextColor(LCD_COLOR_CYAN); /* Display blue cyan record circle */ BSP_LCD_FillCircle((TOUCH_RECORD_XMAX+TOUCH_RECORD_XMIN)/2, (TOUCH_RECORD_YMAX+TOUCH_RECORD_YMIN)/2, (TOUCH_RECORD_XMAX-TOUCH_RECORD_XMIN)/2); BSP_LCD_SetTextColor(LCD_COLOR_YELLOW); BSP_LCD_DisplayStringAt(247, LINE(6), (uint8_t *)" [PAUSE] ", LEFT_MODE); BSP_AUDIO_IN_Pause(); AudioState = AUDIO_STATE_WAIT; break; case AUDIO_STATE_RESUME: BSP_LCD_SetTextColor(LCD_COLOR_CYAN); /* Displays blue cyan pause rectangles */ BSP_LCD_FillRect(TOUCH_PAUSE_XMIN, TOUCH_PAUSE_YMIN , 15, TOUCH_PAUSE_YMAX - TOUCH_PAUSE_YMIN); BSP_LCD_FillRect(TOUCH_PAUSE_XMIN + 20, TOUCH_PAUSE_YMIN, 15, TOUCH_PAUSE_YMAX - TOUCH_PAUSE_YMIN); BSP_LCD_SetTextColor(LCD_COLOR_RED); /* Display red record circle */ BSP_LCD_FillCircle((TOUCH_RECORD_XMAX+TOUCH_RECORD_XMIN)/2, (TOUCH_RECORD_YMAX+TOUCH_RECORD_YMIN)/2, (TOUCH_RECORD_XMAX-TOUCH_RECORD_XMIN)/2); BSP_LCD_SetTextColor(LCD_COLOR_YELLOW); BSP_LCD_DisplayStringAt(247, LINE(6), (uint8_t *)" [RECORD]", LEFT_MODE); BSP_AUDIO_IN_Resume(); AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_VOLUME_UP: if(uwVolume <= 95) { uwVolume += 5; } sprintf((char *)str, "Volume : %d ", (int)uwVolume); BSP_LCD_SetTextColor(LCD_COLOR_YELLOW); BSP_LCD_ClearStringLine(7); BSP_LCD_DisplayStringAtLine(7, str); BSP_AUDIO_IN_SetVolume(uwVolume); AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_VOLUME_DOWN: if(uwVolume >= 5) { uwVolume -= 5; } sprintf((char *)str, "Volume : %d ", (int)uwVolume); BSP_LCD_SetTextColor(LCD_COLOR_YELLOW); BSP_LCD_ClearStringLine(7); BSP_LCD_DisplayStringAtLine(7, str); BSP_AUDIO_IN_SetVolume(uwVolume); AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_NEXT: case AUDIO_STATE_PREVIOUS: AudioState = AUDIO_STATE_RECORD; break; case AUDIO_STATE_WAIT: if(TS_State.touchDetected == 1) /* If previous touch has not been released, we don't proceed any touch command */ { BSP_TS_GetState(&TS_State); } else { BSP_TS_GetState(&TS_State); if(TS_State.touchDetected == 1) { if ((TS_State.touchX[0] > TOUCH_RECORD_XMIN) && (TS_State.touchX[0] < TOUCH_RECORD_XMAX) && (TS_State.touchY[0] > TOUCH_RECORD_YMIN) && (TS_State.touchY[0] < TOUCH_RECORD_YMAX)) { AudioState = AUDIO_STATE_RESUME; } else if ((TS_State.touchX[0] > TOUCH_PAUSE_XMIN) && (TS_State.touchX[0] < TOUCH_PAUSE_XMAX) && (TS_State.touchY[0] > TOUCH_PAUSE_YMIN) && (TS_State.touchY[0] < TOUCH_PAUSE_YMAX)) { AudioState = AUDIO_STATE_RESUME; } } } case AUDIO_STATE_IDLE: case AUDIO_STATE_INIT: default: /* Do Nothing */ break; } return audio_error; }