/** * @brief Calculates the remaining file size and new position of the pointer. * @param None * @retval None */ void BSP_AUDIO_OUT_TransferComplete_CallBack() { uint32_t replay = 0; if (AudioRemSize > 0) { /* Replay from the current position */ BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)CurrentPos, DMA_MAX(AudioRemSize)); /* Update the current pointer position */ CurrentPos += DMA_MAX(AudioRemSize); /* Update the remaining number of data to be played */ AudioRemSize -= DMA_MAX(AudioRemSize); } else { /* Request to replay audio file from beginning */ replay = 1; } /* Audio sample used for play*/ if((AudioTest == 0) && (replay == 1)) { /* Replay from the beginning */ /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS); /* Replay from the beginning */ BSP_AUDIO_OUT_Play(CurrentPos, DMA_MAX(AudioTotalSize)); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); } /*Audio sample saved during record*/ if((AudioTest == 1) && (replay == 1)) { /* Set the total number of data to be played */ AudioTotalSize = WR_BUFFER_SIZE; /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos = WrBufffer + DMA_MAX(AudioTotalSize); /* Replay from the beginning */ BSP_AUDIO_OUT_Play(WrBufffer, DMA_MAX(AudioTotalSize)); } }
/** * @brief Manages the full Transfer complete event. * @param None * @retval None */ void BSP_AUDIO_OUT_TransferComplete_CallBack(void) { /* Calculate the remaining audio data in the file and the new size for the DMA transfer. If the Audio files size is less than the DMA max data transfer size, so there is no calculation to be done, just restart from the beginning of the file ... */ /* Check if the end of file has been reached */ if(AudioRemSize > 0) { /* Replay from the current position */ BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)CurrentPos, DMA_MAX(AudioRemSize)); /* Update the current pointer position */ CurrentPos += DMA_MAX(AudioRemSize); /* Update the remaining number of data to be played */ AudioRemSize -= DMA_MAX(AudioRemSize); } else { /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS + AUDIO_START_OFFSET_ADDRESS); /* Replay from the beginning */ BSP_AUDIO_OUT_Play((uint16_t*)CurrentPos, (AUDIO_FILE_SIZE - AUDIO_START_OFFSET_ADDRESS)); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); } }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_Play(uint32_t frequency) { uint32_t numOfReadBytes; BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, DEFAULT_REC_AUDIO_VOLUME, DEFAULT_AUDIO_IN_FREQ); BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); /* Fill whole buffer @ first time */ if(f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes != 0) { if(haudio.in.state == AUDIO_RECORDER_SUSPENDED) { osThreadResume(AudioThreadId); } haudio.in.state = AUDIO_RECORDER_PLAYING; BSP_AUDIO_OUT_Play((uint16_t*)&haudio.buff[0], AUDIO_OUT_BUFFER_SIZE); return AUDIO_RECORDER_ERROR_NONE; } } return AUDIO_RECORDER_ERROR_IO; }
/** * @brief Starts Audio streaming. * @param idx: File index * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_Start(uint8_t idx) { uint32_t bytesread; if(MTP_GetWavObjectNumber() > idx) { AUDIO_GetFileInfo(idx, &wav_info); BSP_AUDIO_OUT_SetFrequency(wav_info.SampleRate); buffer_ctl.offset = BUFFER_OFFSET_NONE; if(MTP_GetData(idx, 44, AUDIO_BUFFER_SIZE, &buffer_ctl.buff[0], &bytesread) == 0) { audio_state = AUDIO_STATE_PLAY; BSP_LCD_DisplayStringAt(250, LINE(14), (uint8_t *)" [PLAY ]", LEFT_MODE); { if(bytesread != 0) { BSP_AUDIO_OUT_Play((uint16_t*)&buffer_ctl.buff[0], AUDIO_BUFFER_SIZE); buffer_ctl.fptr = bytesread; return AUDIO_ERROR_NONE; } } } } return AUDIO_ERROR_IO; }
/** * @brief Handles AUDIO command. * @param pbuf: Pointer to buffer of data to be sent * @param size: Number of data to be sent (in bytes) * @param cmd: Command opcode * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t Audio_PlaybackCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd) { switch(cmd) { case AUDIO_CMD_START: BSP_AUDIO_OUT_Play((uint16_t *)pbuf, 2*size); break; case AUDIO_CMD_PLAY: BSP_AUDIO_OUT_ChangeBuffer((uint16_t *)pbuf, 2*size); break; } return 0; }
/** * @brief Calculates the remaining file size and new position of the pointer. * @param None * @retval None */ void BSP_AUDIO_OUT_TransferComplete_CallBack() { uint32_t replay = 0; if (AudioRemSize > 0) { /* Replay from the current position */ if (BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)CurrentPos, DMA_MAX(AudioRemSize)) != 0) { Error_Handler(); } /* Update the current pointer position */ CurrentPos += DMA_MAX(AudioRemSize); /* Update the remaining number of data to be played */ AudioRemSize -= DMA_MAX(AudioRemSize); } else { /* Request to replay audio file from beginning */ replay = 1; } /* Audio sample used for play*/ if(replay == 1) { /* Replay from the beginning */ /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS); /* Replay from the beginning */ if (BSP_AUDIO_OUT_Play(CurrentPos,DMA_MAX(AudioTotalSize)) != 0) { Error_Handler(); } /* Toggle Green Led, each time a replay is requested */ BSP_LED_Toggle(LED_GREEN); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); } }
/** * @brief Starts Audio streaming. * @param None * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_Start(void) { uint32_t bytesread; buffer_ctl.state = BUFFER_OFFSET_NONE; bytesread = GetData( (void *)AUDIO_FILE_ADDRESS, 0, &buffer_ctl.buff[0], AUDIO_BUFFER_SIZE); if(bytesread > 0) { BSP_AUDIO_OUT_Play((uint16_t*)&buffer_ctl.buff[0], AUDIO_BUFFER_SIZE); audio_state = AUDIO_STATE_PLAYING; buffer_ctl.fptr = bytesread; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_IO; }
/** * @brief Starts Audio streaming. * @param None * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_Start(uint32_t audio_start_address, uint32_t audio_file_size) { uint32_t bytesread; buffer_ctl.state = BUFFER_OFFSET_NONE; AudioStartAddress = audio_start_address; AudioFileSize = audio_file_size; bytesread = GetData( (void *)AudioStartAddress, 0, &buffer_ctl.buff[0], AUDIO_BUFFER_SIZE); if(bytesread > 0) { BSP_AUDIO_OUT_Play((uint16_t*)&buffer_ctl.buff[0], AUDIO_BUFFER_SIZE); audio_state = AUDIO_STATE_PLAYING; buffer_ctl.fptr = bytesread; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_IO; }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Play(uint32_t frequency) { uint32_t numOfReadBytes; haudio.state = AUDIOPLAYER_PLAY; /* Fill whole buffer @ first time */ if(f_read(&wav_file, &haudio.buffer[0], AUDIO_BUFFER_SIZE, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes != 0) { BSP_AUDIO_OUT_SetFrequency(frequency); osThreadResume(AudioThreadId); BSP_AUDIO_OUT_Play((uint16_t*)&haudio.buffer[0], AUDIO_BUFFER_SIZE); return AUDIOPLAYER_ERROR_NONE; } } return AUDIOPLAYER_ERROR_IO; }
/** * @brief Starts Audio streaming. * @param idx: File index * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_PLAYER_Start(uint8_t idx) { uint32_t bytesread; f_close(&WavFile); if(AUDIO_GetWavObjectNumber() > idx) { GetFileInfo(idx, &WaveFormat); /*Adjust the Audio frequency */ PlayerInit(WaveFormat.SampleRate); BufferCtl.state = BUFFER_OFFSET_NONE; /* Get Data from USB Flash Disk */ f_lseek(&WavFile, 0); /* Fill whole buffer at first time */ if(f_read(&WavFile, &BufferCtl.buff[0], AUDIO_OUT_BUFFER_SIZE, (void *)&bytesread) == FR_OK) { AudioState = AUDIO_STATE_PLAY; AUDIO_PlaybackDisplayButtons(); BSP_LCD_DisplayStringAt(250, LINE(9), (uint8_t *)" [PLAY ]", LEFT_MODE); { if(bytesread != 0) { BSP_AUDIO_OUT_Play((uint16_t*)&BufferCtl.buff[0], AUDIO_OUT_BUFFER_SIZE); BufferCtl.fptr = bytesread; return AUDIO_ERROR_NONE; } } } } return AUDIO_ERROR_IO; }
/** * @brief Starts Wave player. * @param None * @retval None */ void WavePlayerStart(WAVE_FormatTypeDef waveformat, WavePlayer_getDataCB_type getDataCB, uint8_t volume) { int32_t bytesread = 0; int32_t length; int16_t *pBuf = NULL; uint32_t AudioRemSize = 0; uint32_t WaveDataLength = 0; /* Set WaveDataLenght to the Speech Wave length */ WaveDataLength = waveformat.FileSize; AudioRemSize = WaveDataLength - sizeof(WAVE_FormatTypeDef); /* Initialize Wave player (Codec, DMA, I2C) */ if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, volume, waveformat.SampleRate) != 0) { Error_Handler(); } /* Start playing Wave */ BSP_AUDIO_OUT_Play((uint16_t*)&Audio_BufferStereo[0], sizeof(Audio_BufferStereo)); LEDsState = LED6_TOGGLE; /* Toggling LED6 to signal Play */ LEDsState = LED6_TOGGLE; /* Resume playing Wave */ BSP_AUDIO_OUT_Resume(); if (CHANNEL_MONO == waveformat.NbrChannels) { length = AUDIO_BUFFER_STEREO_LENGTH/4; } else { length = AUDIO_BUFFER_STEREO_LENGTH/2; } while (AudioRemSize > 0) { if (BUFFER_OFFSET_HALF == BufferOffset) { pBuf = &Audio_BufferStereo[0]; } if (BUFFER_OFFSET_FULL == BufferOffset) { pBuf = &Audio_BufferStereo[AUDIO_BUFFER_STEREO_LENGTH/2]; } if (NULL != pBuf) { bytesread = getDataCB(pBuf, length); if (CHANNEL_MONO == waveformat.NbrChannels) { convertToStereo(pBuf, pBuf, length); } BufferOffset = BUFFER_OFFSET_NONE; pBuf = NULL; if (bytesread <= 0) { AudioRemSize = 0; } else { AudioRemSize -= bytesread; if (AudioRemSize < (length*2)) { AudioRemSize = 0; } } } } LEDsState = LEDS_OFF; BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* Configure the MPU attributes as Write Through */ MPU_Config(); /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* STM32F7xx HAL library initialization: - Configure the Flash ART accelerator on ITCM interface - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 200 MHz */ SystemClock_Config(); /* Configure LED1 and LED3 */ BSP_LED_Init(LED1); HAL_Delay(100); setbuf(stdout, NULL); BSP_LED_On(LED1); SD_init(); HAL_Delay(100); fluid_settings_t* settings; int sfont_id; /* Create the settings. */ settings = new_fluid_settings(); fluid_settings_setnum(settings, "synth.sample-rate", SAMPLE_RATE); fluid_settings_setstr(settings, "synth.reverb.active", "no"); fluid_settings_setstr(settings, "synth.chorus.active", "no"); fluid_settings_setint(settings, "synth.polyphony", POLYPHONY); /* Create the synthesizer. */ synth = new_fluid_synth(settings); sfont_id = fluid_synth_sfload(synth, SOUNDFONT_FILE, 1); fluid_synth_set_interp_method(synth, -1, FLUID_INTERP_NONE); // fluid_synth_set_interp_method(synth, -1, FLUID_INTERP_LINEAR); /* Make the connection and initialize to USB_OTG/usbdc_core */ USBD_Init(&USBD_Device, &AUDIO_Desc, 0); USBD_RegisterClass(&USBD_Device, &USBD_Midi_ClassDriver); USBD_Midi_RegisterInterface(&USBD_Device, &USBD_Midi_fops); USBD_Start(&USBD_Device); HAL_Delay(5); BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, MASTER_VOLUME, SAMPLE_RATE); BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); // PCM 2-channel #ifdef AUDIO_FORMAT_32BITS BSP_AUDIO_OUT_Play((uint32_t *)&buf[0], AUDIO_BUF_SIZE); #else BSP_AUDIO_OUT_Play((uint16_t *)&buf[0], AUDIO_BUF_SIZE); #endif BSP_LED_Off(LED1); while (1) { BSP_LED_Toggle(LED1); HAL_Delay(1000); } }
AUDIO_ErrorTypeDef Play_WAV(FIL *WavFile,uint32_t SR,uint32_t uwVolume)/////////////////////////// WAV PLAY { uint8_t buff[AUDIO_OUT_BUFFER_SIZE]; //uint32_t prev_elapsed_time = 0xFFFFFFFF; uint32_t bytesread; //uint32_t elapsed_time; //uint8_t str[10]; f_lseek(WavFile, 0); //Fill whole buffer at first time if(f_read(WavFile,&buff[0], AUDIO_OUT_BUFFER_SIZE,(void *)&bytesread) == FR_OK) { BSP_AUDIO_OUT_Play((uint16_t*)&buff[0], AUDIO_OUT_BUFFER_SIZE); BufferCtl.fptr = bytesread; AudioState=AUDIO_STATE_PLAY; // Zaradi Call Back while(bytesread)// AudioState != AUDIO_STATE_NEXT) { if(BufferCtl.fptr >= WavFile->fsize) { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); AudioState = AUDIO_STATE_NEXT; } if(BufferCtl.state == BUFFER_OFFSET_HALF) { if(f_read(WavFile,&buff[0],AUDIO_OUT_BUFFER_SIZE/2,(void *)&bytesread) != FR_OK) { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); return AUDIO_ERROR_IO; } BufferCtl.state = BUFFER_OFFSET_NONE; BufferCtl.fptr += bytesread; } if(BufferCtl.state == BUFFER_OFFSET_FULL) { if(f_read(WavFile, &buff[AUDIO_OUT_BUFFER_SIZE /2],AUDIO_OUT_BUFFER_SIZE/2,(void *)&bytesread) != FR_OK) { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); return AUDIO_ERROR_IO; } ///////////////////////////////////////////////////TUK BufferCtl.state = BUFFER_OFFSET_NONE; BufferCtl.fptr += bytesread; } /* // Display elapsed time elapsed_time = BufferCtl.fptr / WaveFormat.ByteRate; if(prev_elapsed_time != elapsed_time) { prev_elapsed_time = elapsed_time; s((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); BSP_LCD_SetTextColor(LCD_COLOR_WHITE); } */ }//while }else return AUDIO_ERROR_IO; return AUDIO_ERROR_NONE; }
uint32_t Play_MOV(FIL *mfile) { uint8_t _aucLine[2048]; register uint32_t i, j; int ret = 0; uint32_t fps, frames, prevFrames, sample_time_limit; uint32_t samples, frameDuration, numEntry; uint32_t prevChunkSound, prevSamplesSound, firstChunkSound, samplesSound; uint32_t firstChunk = 0, totalSamples = 0, prevChunk = 0, prevSamples = 0, totalBytes = 0; uint32_t videoStcoCount, soundStcoCount, stco_reads; uint32_t prevSamplesBuff[60]; FILE fp_sound, fp_frame, fp_frame_cp, \ fp_stsc, fp_stsz, fp_stco, \ fp_sound_stsc, fp_sound_stsz, fp_sound_stco; uint8_t fpsCnt = 0; //danko const char fps1Hz[] = "|/-\\"; char timeStr[20]; raw_video_typedef raw; int soundEndFlag = 0; media.sound.flag.process = 0; media.sound.flag.complete = 0; media.video.flag.process = 0; media.video.flag.complete = 0; memcpy((void*)&fp_global, (void*)mfile, sizeof(FIL)); int hasChild = atomHasChild[UDTA]; // atomHasChild[UDTA] = 0; // No child printf("\r\n[Atoms]"); if(collectAtoms(mfile, mfile->fsize, 0) != 0) { printf("\r\nread error file contents."); /// dani f_close(fp); //DANI/// LCDStatusStruct.waitExitKey = 0; atomHasChild[UDTA] = hasChild; // Moje da ima child return -99; } atomHasChild[UDTA] = hasChild; // Moje da ima child printf("\r\n\n[Video Sample Tables]"); printf("\r\nstts:%d", video_stts.numEntry); printf("\r\nstsc:%d", video_stsc.numEntry); printf("\r\nstsz:%d %d", video_stsz.sampleSize, video_stsz.numEntry); printf("\r\nstco:%d", video_stco.numEntry); printf("\r\n\n[Sound Sample Tables]"); printf("\r\nstts:%d", sound_stts.numEntry); printf("\r\nstsc:%d", sound_stsc.numEntry); printf("\r\nstsz:%d %d", sound_stsz.sampleSize, sound_stsz.numEntry); printf("\r\nstco:%d", sound_stco.numEntry); printf("\r\n\n[Video Track]"); printf("\r\nformat:%s", media.video.videoFmtString); printf("\r\ncompression:%s", media.video.videoCmpString); printf("\r\nwidth:%d", media.video.width); printf("\r\nheight:%d", media.video.height); printf("\r\ntimeScale:%d", media.video.timeScale); printf("\r\nduration:%d", media.video.duration); setStrSec(timeStr, (int)((float)media.video.duration / (float)media.video.timeScale + 0.5f)); //Kvo Pravi media.video.frameRate = (int16_t)((float)(media.video.timeScale * video_stsz.numEntry) / media.video.duration + 0.5f); printf("\r\nframe rate:%d", media.video.frameRate); printf("\r\ntime:%s", timeStr); printf("\r\n\n[Sound Track]"); char s[5]; s[4] = '\0'; memcpy(s, (void*)media.sound.format.audioFmtString, 4); printf("\r\ntype:%s", s); printf("\r\nnumChannel:%d", media.sound.format.numChannel); printf("\r\nsampleSize:%d", media.sound.format.sampleSize); printf("\r\nsampleRate:%d", media.sound.format.sampleRate); printf("\r\ntimeScale:%d", media.sound.timeScale); printf("\r\nduration:%d", media.sound.duration); setStrSec(timeStr, (int)((float)media.sound.duration / (float)media.sound.timeScale + 0.5f)); printf("\r\ntime:%s", timeStr); if(media.video.width > LCD_WIDTH || media.video.height > LCD_HEIGHT){ printf("\r\ntoo large video dimension size."); f_close(mfile);// //DANI////////////////////////////LCDStatusStruct.waitExitKey = 0; atomHasChild[UDTA] = hasChild; return 0; //DANI/////////////////RET_PLAY_STOP; } //DANI///////////////// FUNC_VIDEO_BGIMG; media.video.startPosX = (LCD_WIDTH - media.video.width) / 2 - 1; media.video.startPosY = (LCD_HEIGHT - media.video.height) / 2 - 1; media.video.startPosX = media.video.startPosX > 0 ? media.video.startPosX : 0; media.video.startPosY = media.video.startPosY > 0 ? media.video.startPosY : 0; // media.video.height += (media.video.height % 2); // if value is odd number, convert to even printf("\r\nmedia.video.startPosX:%d", media.video.startPosX); printf("\r\nmedia.video.startPosY:%d", media.video.startPosY); printf("\r\nmedia.video.width:%d", media.video.width); printf("\r\nmedia.video.height:%d", media.video.height); //////////////////////////////////////////////////////////////////////// printf("\r\n\n[Play]\n");/*** MotionJPEG Play Process ***/ //Prehw v STEKA f_lseek(mfile, 0); memcpy((void*)&fp_frame, (void*)mfile, sizeof(FIL)); memcpy((void*)&fp_stsz, (void*)&video_stsz.fp, sizeof(FIL)); memcpy((void*)&fp_stco, (void*)&video_stco.fp, sizeof(FIL)); memcpy((void*)&fp_stsc, (void*)&video_stsc.fp, sizeof(FIL)); numEntry = video_stsc.numEntry; fps = frames = prevFrames = 0; totalSamples = firstChunk = prevChunk = prevSamples = 0; if(abs(video_stco.numEntry - sound_stco.numEntry) > 50) { // not interleaved correctly printf("\r\nError!! this is not an interleaved media."); goto EXIT_PROCESS; } else { prevChunk = getSampleSize(atombuf, 12, &fp_stsc); // firstChunk samplesPerChunk sampleDescriptionID // The firstChunk of the first one to prevChunk prevSamples = getAtomSize(&atombuf[4]); //The samplesPerChunk of the first one to prevSamples firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // The second firstChunk samples = firstChunk - prevChunk; } //A 32-bit integer that indicates how long each frame lasts in real time. frameDuration = getVideoSampleTime(atombuf, totalSamples); //Ot time to sample table // SOUND memcpy((void*)&fp_sound_stsz, (void*)&sound_stsz.fp, sizeof(FILE)); memcpy((void*)&fp_sound_stco, (void*)&sound_stco.fp, sizeof(FILE)); memcpy((void*)&fp_sound_stsc, (void*)&sound_stsc.fp, sizeof(FILE)); memcpy((void*)&fp_sound, (void*)mfile, sizeof(FILE)); prevChunkSound = getSampleSize(atombuf, 12, &fp_sound_stsc); // firstChunk samplesPerChunk sampleDescriptionID ????firstChunk?prevChunk? prevSamplesSound = (getAtomSize(&atombuf[4]) / 100) * 100; //The samplesPerChunk of the first ////////////////////////////////////////////////////////////one so not out half of the sound buffer to prevSamples firstChunkSound = getSampleSize(atombuf, 4, &fp_sound_stsc); // ????firstChunk samplesSound = (firstChunkSound - prevChunkSound) * prevSamplesSound; // uint8_t SOUND_BUFFER[38400]; // uint8_t SOUND_BUFFER[12800]; uint16_t soundSampleByte = media.sound.format.sampleSize / 8; uint32_t soundSampleBlocks = soundSampleByte * media.sound.format.numChannel; float timeScaleCoeff = (1.0f / media.video.timeScale) * 100000; dac_intr.fp = &fp_sound; dac_intr.buff = (uint8_t*)frame_buffer; //////////////////////////////////////////////////////////////// TUK ZVUKA e VAV FREIMA //////////////////////////////////////////////////////dac_intr.buff = SOUND_BUFFER; dac_intr.bufferSize = ((media.sound.format.sampleRate / 10) * 2) * soundSampleByte * media.sound.format.numChannel; // kakva chast ot freima e zvuk // if(media.sound.format.sampleSize == 16){ // dac_intr.func = DAC_Buffer_Process_Stereo_S16bit; // } else { // dac_intr.func = DAC_Buffer_Process_Mono_U8bit; // } memset(dac_intr.buff, 0, dac_intr.bufferSize); f_lseek(&fp_sound, getSampleSize(atombuf, 4, &fp_sound_stco)); dac_intr.sound_reads = 0; stco_reads = 1; printf("\r\nframeDuration:%d", frameDuration); TIM_HandleTypeDef Tim1SecHandle, TimDurationHandle; // TIM3 specified in 0.01ms seconds for sample time TimDurationHandle.Instance = TIM_DURATION; HAL_TIM_Base_DeInit(&TimDurationHandle); TimDurationHandle.Init.Period = (100000 * frameDuration) / media.video.timeScale - 1; TimDurationHandle.Init.Prescaler = ((SystemCoreClock / 2) / 100000) * 2 - 1; // 0.01ms TimDurationHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimDurationHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if(HAL_TIM_Base_Init(&TimDurationHandle) != HAL_OK) { while(1); } HAL_TIM_Base_Start(&TimDurationHandle); /* while(1) { if(TIM3_SR_UIF_BB){ TIM3_SR_UIF_BB = 0; HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); TIM3->CNT = 0; } } */ Tim1SecHandle.Instance = TIM_1SEC; HAL_TIM_Base_DeInit(&Tim1SecHandle); Tim1SecHandle.Init.Prescaler = 100 - 1; Tim1SecHandle.Init.Period = 10000 - 1; Tim1SecHandle.Init.RepetitionCounter = (SystemCoreClock / 1000000UL) - 1; Tim1SecHandle.Init.CounterMode = TIM_COUNTERMODE_UP; Tim1SecHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if(HAL_TIM_Base_Init(&Tim1SecHandle) != HAL_OK) { while(1); } HAL_TIM_Base_Start_IT(&Tim1SecHandle); // Video pv_src.firstChunk = &firstChunk; pv_src.prevChunk = &prevChunk; pv_src.prevSamples = &prevSamples; pv_src.samples = &samples; pv_src.totalSamples = &totalSamples; pv_src.videoStcoCount = &videoStcoCount; pv_src.fp_video_stsc = &fp_stsc; pv_src.fp_video_stsz = &fp_stsz; pv_src.fp_video_stco = &fp_stco; pv_src.fp_frame = &fp_frame; // Sound ps_src.firstChunk = &firstChunkSound; ps_src.prevChunk = &prevChunkSound; ps_src.prevSamples = &prevSamplesSound; ps_src.samples = &samplesSound; ps_src.soundStcoCount = &soundStcoCount; ps_src.fp_sound_stsc = &fp_sound_stsc; ps_src.fp_sound_stsz = &fp_sound_stsz; ps_src.fp_sound_stco = &fp_sound_stco; //DANI mjpeg_touch.resynch = 0; //DANI LCD_SetRegion(media.video.startPosX, media.video.startPosY, media.video.startPosX + media.video.width - 1, media.video.startPosY + media.video.height - 1); float limitter; switch(SystemCoreClock){ case 168000000: limitter = 0.91f; break; case 200000000: limitter = 0.93f; break; case 240000000: limitter = 0.96f; break; case 250000000: limitter = 0.98f; break; default: limitter = 0.8f; break; } videoStcoCount = 0, soundStcoCount = 0; //DANI //DANI pcf_font_typedef pcf_font_bak; //DANI if(pcf_font.ext_loaded) //DANI { //DANI memcpy((void*)&pcf_font_bak, (void*)&pcf_font, sizeof(pcf_font_typedef)); //DANI /* internal flash pcf font */ //DANI C_PCFFontInit((uint32_t)internal_flash_pcf_font, (size_t)_sizeof_internal_flash_pcf_font); //DANI PCF_RENDER_FUNC_C_PCF(); //DANI } //DANI BSP_AUDIO_OUT_Init(0, 0, media.sound.format.sampleSize, media.sound.format.numChannel >= 2 ? media.sound.format.sampleRate : media.sound.format.sampleRate / 2); if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_SPEAKER,50, \ media.sound.format.numChannel >= 2 ? media.sound.format.sampleRate : media.sound.format.sampleRate / 2)!=0) {printf("\r\nAudio Init Error..");}; BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); // wm8731_left_headphone_volume_set(121 + vol); //DANI printf("\r\nhaudio_i2s.State:%d", haudio_i2s.State); //HAL_StatusTypeDef errorState; //HAL_I2S_Transmit_DMA(&haudio_i2s, (uint16_t*)dac_intr.buff, DMA_MAX(dac_intr.bufferSize / ( AUDIODATA_SIZE ))); BSP_AUDIO_OUT_Play( (uint16_t*)dac_intr.buff,DMA_MAX(dac_intr.bufferSize / ( AUDIODATA_SIZE ))); Play_WAV(dac_intr.fp,DMA_MAX(dac_intr.bufferSize / ( AUDIODATA_SIZE )),70); //DANI DMA_SOUND_IT_ENABLE; //DANI LCDStatusStruct.waitExitKey = 1; int outflag = 0, count = 0, pause = 0; while(1){ CHUNK_OFFSET_HEAD: for(j = 0;j < samples;j++){ f_lseek(&fp_frame, getSampleSize(atombuf, 4, &fp_stco) ); //Chunk offset atom if(media.video.playJpeg) { //my_fread(prevSamplesBuff, 1, prevSamples * 4, &fp_stsz); f_read(&fp_stsz, prevSamplesBuff, prevSamples * 4,NULL); //Sample Size Atoms } for(i = 0;i < prevSamples;i++) { sample_time_limit = TIM_DURATION->ARR * limitter; frameDuration = getVideoSampleTime(atombuf, ++totalSamples); // get next frame duration //DANKO LCD_SetGramAddr(media.video.startPosX, media.video.startPosY); //DANKO LCD_CMD(0x002C); raw.output_scanline = 0; raw.frame_size = media.video.width * media.video.height * sizeof(uint16_t); raw.rasters = RASTER; raw.buf_size = raw.rasters * media.video.width * sizeof(uint16_t); memcpy((void*)&fp_frame_cp, (void*)&fp_frame, sizeof(FIL)); f_lseek(&fp_frame, raw.frame_size); totalBytes += raw.frame_size; //danko DMA_SOUND_IT_ENABLE; // Enable DAC interrupt uint32_t tim=1; while(tim--)//!TIM3_SR_UIF_BB) { // while TIM3->SR Update Flag is unset //danko if ((raw.output_scanline < media.video.height) && (TIM_DURATION->CNT < sample_time_limit)) { // Uncompress draw rasters if(raw.frame_size < raw.buf_size){ raw.buf_size = raw.frame_size; } //danko while(SpiLcdHandle.State != HAL_SPI_STATE_READY) { //danko if((TIM_DURATION->CNT >= sample_time_limit)){ //danko HAL_DMA_Abort(SpiLcdHandle.hdmatx); //danko SPI_LCD_NSS_PIN_DEASSERT; //danko goto EXIT_LOOP; } } //danko DMA_SOUND_IT_DISABLE; //danko my_fread((void*)LINE_BUFFER, 1, raw.buf_size, &fp_frame_cp); ////////////jpeg_decode(&fp_frame_cp, IMAGE_WIDTH, _aucLine, Jpeg_CallbackFunction); //danko DMA_SOUND_IT_ENABLE; //danko SPI_LCD_NSS_PIN_ASSERT; //danko SPI_LCD_RS_PIN_DEASSERT; //!!! HAL_SPI_Transmit_DMA(&SpiLcdHandle, (uint8_t*)LINE_BUFFER, raw.buf_size / sizeof(uint16_t)); raw.frame_size -= raw.buf_size; raw.output_scanline += raw.rasters; if((abs(soundStcoCount - videoStcoCount) > 1) && !soundEndFlag) { // correct synch unmatch if(soundStcoCount >= (sound_stco.numEntry - 2) || videoStcoCount >= (video_stco.numEntry - 2)) {goto EXIT_PROCESS;} //danko mjpeg_touch.resynch = 1; //danko mjpeg_touch.resynch_entry = soundStcoCount > videoStcoCount ? videoStcoCount : soundStcoCount; printf("\r\n*synch unmatch at video_stco:%d sound_stco:%d\n", videoStcoCount, soundStcoCount); //danko DMA_SOUND_IT_DISABLE; // Disable DAC interrupt //danko mjpegTouch(id, mjpeg_touch.resynch_entry); //Touch pen interrupt processing samples /= prevSamples; //danko mjpeg_touch.resynch = 0; getVideoSampleTime(atombuf, 0); // reset sample time getVideoSampleTime(atombuf, totalSamples); // get next sample time dac_intr.sound_reads = prevSamplesSound * soundSampleBlocks; // fill DAC buffer videoStcoCount -= 2, soundStcoCount -= 2; goto CHUNK_OFFSET_HEAD; } if(dac_intr.sound_reads >= (prevSamplesSound * soundSampleBlocks)) { if(++soundStcoCount < sound_stco.numEntry) { soundEndFlag = 0; totalBytes += dac_intr.sound_reads; //my_fseek(dac_intr.fp, getSampleSize(atombuf, 4, &fp_sound_stco), SEEK_SET); f_lseek(dac_intr.fp, getSampleSize(atombuf, 4, &fp_sound_stco)); dac_intr.sound_reads = 0; if(++stco_reads > samplesSound){ stco_reads = 0; prevChunkSound = firstChunkSound; // ???firstChunk?prevChunk? prevSamplesSound = getSampleSize(atombuf, 12, &fp_sound_stsc); // samplesPerChunk sampleDescriptionID firstChunkSound = getAtomSize(&atombuf[8]); // ??firstChunk samplesSound = firstChunkSound - prevChunkSound; // The number of samples of the next time playback chunk } } else { soundEndFlag = 1; dac_intr.sound_reads = 0; //danko DMA_SOUND_IT_DISABLE; } } /*//danko if(!outflag && (++count >= 100000)) { outflag = 1; if(!music_control.b.mute){ HAL_I2S_DMAPause(&haudio_i2s); Delay_us(3); wm8731_left_headphone_volume_set(121 + vol); HAL_I2S_DMAResume(&haudio_i2s); } } *///danko //case PLAY_LOOP_MODE: { //danko HAL_I2S_DMAPause(&haudio_i2s); //danko Delay_us(3); //danko wm8731_left_headphone_volume_set(0); //danko HAL_I2S_DMAResume(&haudio_i2s); //danko DMA_SOUND_IT_DISABLE; raw.frame_size = media.video.width * media.video.height * sizeof(uint16_t); memcpy((void*)&fp_frame_cp, (void*)&fp_frame, sizeof(FIL)); //my_fseek(&fp_frame_cp, -raw.frame_size, SEEK_CUR); f_lseek(&fp_frame_cp, -raw.frame_size); memset((void*)frame_buffer, 0, FRAME_BUFFER_SIZE); int v; for(v = 0;v < media.video.height;v++) { //my_fread(&frame_buffer[media.video.startPosX + v * LCD_WIDTH + media.video.startPosY * LCD_WIDTH], 2, media.video.width, &fp_frame_cp); f_read(&fp_frame_cp,&frame_buffer[media.video.startPosX + v * LCD_WIDTH + media.video.startPosY * LCD_WIDTH],2* media.video.width ,NULL); } //danko ret = mjpegPause(id); outflag = 0, count = 0; /* if(ret == RET_PLAY_STOP || ret == RET_PLAY_NEXT || ret == RET_PLAY_PREV){ goto END_PROCESS; } if(ret == 1){ // ????????? ???:0 ?????? :1 ?????????????? samples /= prevSamples; getVideoSampleTime(atombuf, 0); // ?????????? getVideoSampleTime(atombuf, totalSamples); // ????????????? dac_intr.sound_reads = prevSamplesSound * soundSampleBlocks; // DAC??????????????? // videoStcoCount -= 2, soundStcoCount -= 2; ret = 0; goto CHUNK_OFFSET_HEAD; } LCDStatusStruct.waitExitKey = 1; break; */ } } EXIT_LOOP: // Per frame time duration timer (specified in the 1 / 100ms units) //danko TIM_DURATION->ARR = frameDuration * timeScaleCoeff - 1; //danko TIM_DURATION->CR1 = 0; //danko TIM_DURATION->CNT = 0; // clear counter //danko TIM3_SR_UIF_BB = 0; // clear update flag //DANKO/////////////////////////////////////TIM3_DIER_UIE_BB = 1; // set update interrupt //DANKO/////////////////////////////////////TIM3_CR1_CEN_BB = 1; // enable tim3 frames++; /* if(TIM1_SR_UIF_BB){ // ?????????? TIM1_SR_UIF_BB = 0; fps = frames - prevFrames; debug.printf("\r%c%dfps %dkbps v:%d s:%d ", fps1Hz[fpsCnt++ & 3], fps, (int)((float)(totalBytes * 8) * 0.001f), videoStcoCount, soundStcoCount); prevFrames = frames; totalBytes = 0; } */ } // AUDIO_OUT_ENABLE; if(++videoStcoCount >= video_stco.numEntry) {// || soundStcoCount >= (sound_stco.numEntry)){ goto END_PROCESS; // Play the end how much video chunk count until the last } } //FOR SAMPLES prevChunk = firstChunk; // ???firstChunk?prevChunk? prevSamples = getSampleSize(atombuf, 12, &fp_stsc); // samplesPerChunk sampleDescriptionID firstChunk = getAtomSize(&atombuf[8]); // ??firstChunk samples = firstChunk - prevChunk; // Number of samples for the next play chunk }//WHILE END_PROCESS: // ?????? // AUDIO_OUT_SHUTDOWN; printf("\r\ntotal_samples:%d video_stco_count:%d sound_stco_count:%d", totalSamples, videoStcoCount, soundStcoCount); // debug.printf("\r\ntotalRasters:%d", totalRasters); //danko HAL_I2S_DMAStop(&haudio_i2s); //danko DMA_SOUND_IT_DISABLE; HAL_Delay(10); //us // wm8731_set_active(0); //danko wm8731_left_headphone_volume_set(121 -121); // if(media.video.playJpeg){ // (void) jpeg_finish_decompress(&jdinfo); // jpeg_destroy_decompress(&jdinfo); // } EXIT_PROCESS: memset(dac_intr.buff, 0, dac_intr.bufferSize); //HAL_I2S_Transmit(&haudio_i2s, (uint16_t*)dac_intr.buff, dac_intr.bufferSize / sizeof(uint16_t), 100); BSP_AUDIO_OUT_Play((uint16_t*)dac_intr.buff, dac_intr.bufferSize / sizeof(uint16_t)); dac_intr.func = '\0'; //danko f_close(fp); //danko LCD_SetRegion(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1); //danko LCD_DrawSquare(0, 0, LCD_WIDTH, LCD_HEIGHT, BLACK); //danko if(pcf_font.ext_loaded) { //danko memcpy((void*)&pcf_font, (void*)&pcf_font_bak, sizeof(pcf_font_typedef)); //danko PCF_RENDER_FUNC_PCF(); } //danko LCDStatusStruct.waitExitKey = 0; return ret; }
/** * @brief Main program. * @param None * @retval None */ int main(void) { WAVE_FormatTypeDef *waveformat = NULL; /* STM32F3xx HAL library initialization: - Configure the Flash prefetch - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Initialize the LEDs */ BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); BSP_LED_Init(LED4); /* Configure the system clock to 72 MHz */ SystemClock_Config(); /*##-1- Initialize the Keys Push buttons and LCD #####################*/ /* Initialize the Push buttons */ /* Key push button used for Pause/Resume */ BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); /* Joystick UP push button used for Volume High */ BSP_PB_Init(BUTTON_DOWN, BUTTON_MODE_GPIO); /* Joystick DOWN push button used for Volume Low */ BSP_PB_Init(BUTTON_UP, BUTTON_MODE_GPIO); /* Initialize the LCD */ BSP_LCD_Init(); /*##-2- Display welcome messages on LCD ####################################*/ Display_ExampleDescription(); /* Wait for Key push-button press before starting the Example */ while (BSP_PB_GetState(BUTTON_KEY) != GPIO_PIN_RESET) { } /* Wait for Key push-button release before starting the Example */ while (BSP_PB_GetState(BUTTON_KEY) != GPIO_PIN_SET) { } /*##-3- Display Example Template ###########################################*/ AudioPlay_SetHint(); /*##-4- Turn on LEDs available on STM32303E-EVAL RevC Eval board ###################*/ BSP_LED_On(LED1); BSP_LED_On(LED2); BSP_LED_On(LED3); BSP_LED_On(LED4); /* Initialize the Audio codec and all related peripherals (I2S, I2C, IOs...) */ if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, uwVolume, I2S_AUDIOFREQ_8K) != AUDIO_OK) { /* Initialization Error */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, 115, (uint8_t*)"Initialization problem", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 130, (uint8_t*)"Verify that jumper JP5 and JP6", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 145, (uint8_t*)"are well set to I2C2 position", CENTER_MODE); Error_Handler(); } else { BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_SetFont(&Font12); BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"Audio Codec Ready", LEFT_MODE); } /*##-5- Display information related to control and Playback state #*/ /* Retrieve Wave Sample rate*/ waveformat = (WAVE_FormatTypeDef*)AUDIO_FILE_ADDRESS; AudioPlay_DisplayInfos(waveformat); /*##-6- Start AUDIO playback #####################################*/ /* Normal mode description: Start playing the audio file (using DMA). Using this mode, the application can run other tasks in parallel since the DMA is handling the Audio Transfer instead of the CPU. The only task remaining for the CPU will be the management of the DMA Transfer Complete interrupt or the Half Transfer Complete interrupt in order to load again the buffer and to calculate the remaining data. Circular mode description: Start playing the file from a circular buffer, once the DMA is enabled it always run. User has to fill periodically the buffer with the audio data using Transfer complete and/or half transfer complete interrupts callbacks (EVAL_AUDIO_TransferComplete_CallBack() or EVAL_AUDIO_HalfTransfer_CallBack()... In this case the audio data file is smaller than the DMA max buffer size 65535 so there is no need to load buffer continuously or manage the transfer complete or Half transfer interrupts callbacks. */ /* Set the total number of data to be played (count in half-word) */ AudioTotalSize = (AUDIO_FILE_SIZE - AUDIO_START_OFFSET_ADDRESS)/(waveformat->NbrChannels); /* Set the current audio pointer position */ CurrentPos = (uint16_t*)(AUDIO_FILE_ADDRESS + AUDIO_START_OFFSET_ADDRESS); /* Start the audio player */ BSP_AUDIO_OUT_Play((uint16_t*)CurrentPos, (uint32_t)(AUDIO_FILE_SIZE - AUDIO_START_OFFSET_ADDRESS)); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); /* Display the state on the screen */ BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(0, 160, (uint8_t *)"Playback on-going", CENTER_MODE); BSP_LCD_SetTextColor(LCD_COLOR_BLACK); /* Infinite loop */ while (1) { /* Check on the Pause/Resume button */ if (BSP_PB_GetState(BUTTON_KEY) == GPIO_PIN_RESET) { /* Wait to avoid rebound */ while (BSP_PB_GetState(BUTTON_KEY) == GPIO_PIN_RESET); if (uwCommand == AUDIO_PAUSE) { BSP_AUDIO_OUT_Pause(); /* Display the current state of the player */ BSP_LCD_SetTextColor(LCD_COLOR_BLUE); BSP_LCD_DisplayStringAt(0, 160, (uint8_t *)"Playback paused ", CENTER_MODE); BSP_LCD_SetTextColor(LCD_COLOR_BLACK); /* Next time Resume command should be processed */ uwCommand = AUDIO_RESUME; } else { BSP_AUDIO_OUT_Resume(); /* Display the current state of the player */ BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(0, 160, (uint8_t *)"Playback on-going", CENTER_MODE); BSP_LCD_SetTextColor(LCD_COLOR_BLACK); /* Next time Pause command should be processed */ uwCommand = AUDIO_PAUSE; } } /* Check on the Volume Low button */ if (BSP_PB_GetState(BUTTON_DOWN) == GPIO_PIN_SET) { /* Wait to avoid rebound */ while (BSP_PB_GetState(BUTTON_DOWN) == GPIO_PIN_SET); /* Decrease volume by 5% */ if (uwVolume > 5) { uwVolume -= 5; } else { uwVolume = 0; } /* Apply the new volume to the codec */ BSP_AUDIO_OUT_SetVolume(uwVolume); sprintf((char *) Volume_string, " Volume : %lu%% ", uwVolume); BSP_LCD_DisplayStringAt((uint16_t)(-6), BSP_LCD_GetYSize()-60, Volume_string, RIGHT_MODE); } /* Check on the Volume High button */ if (BSP_PB_GetState(BUTTON_UP) == GPIO_PIN_SET) { /* Wait to avoid rebound */ while (BSP_PB_GetState(BUTTON_UP) == GPIO_PIN_SET); /* Increase volume by 5% */ if (uwVolume < 95) { uwVolume += 5; } else { uwVolume = 100; } /* Apply the new volume to the codec */ BSP_AUDIO_OUT_SetVolume(uwVolume); sprintf((char *) Volume_string, " Volume : %lu%% ", uwVolume); BSP_LCD_DisplayStringAt((uint16_t)(-6), BSP_LCD_GetYSize()-60, Volume_string, RIGHT_MODE); } /* Toggle LED3 */ BSP_LED_Toggle(LED3); /* Insert 100 ms delay */ HAL_Delay(100); /* Toggle LED2 */ BSP_LED_Toggle(LED2); /* Insert 100 ms delay */ HAL_Delay(100); } }
/** * @brief Test Audio Hardware. * The main objective of this test is to check the hardware connection of the * Audio peripheral. * @param None * @retval None */ void AudioPlay_demo(void) { WAVE_FormatTypeDef *waveformat = NULL; uint8_t Volume_string[20] = {0}; AudioPlay_SetHint(); /* Configuration of the EXTI for the joystick SEL push button for pause/resume */ /* UP/DOWN push buttons for change the volume */ BSP_JOY_Init(JOY_MODE_EXTI); /* Retrieve Wave Sample rate */ waveformat = (WAVE_FormatTypeDef*) AUDIO_FILE_ADDRESS; /* Check waveformat validity */ /* In case of audio file pre-loaded into Flash memory, to check audio data */ /* integrity. */ if ((waveformat->SampleRate < SAMPLE_RATE_MIN) || (waveformat->SampleRate > SAMPLE_RATE_MAX)) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, 130, (uint8_t*)"Audio file not valid", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 145, (uint8_t*)"Check audio data integrity", CENTER_MODE); Error_Handler(); } /* Display audio file Wave parameters */ AudioPlay_DisplayInfos(waveformat); /* Initialize Audio Device */ if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_BOTH, volume, waveformat->SampleRate) != 0) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, 130, (uint8_t*)"Initialization problem", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 145, (uint8_t*)"Audio Codec not detected", CENTER_MODE); Error_Handler(); } /* Set the total number of data to be played */ AudioTotalSize = (AUDIO_FILE_SIZE - AUDIO_START_ADDRESS) / 2; /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS); /* Initialize Volume */ if(BSP_AUDIO_OUT_SetVolume(volume) != 0) { Error_Handler(); } /* Start the audio player */ if(BSP_AUDIO_OUT_Play(CurrentPos, DMA_MAX(AudioTotalSize)) != 0) { Error_Handler(); } /* Turn ON LED green: start of Audio file play */ BSP_LED_On(LED_GREEN); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"Playback on-going", LEFT_MODE); sprintf((char *) Volume_string, " Volume : %d%% ", volume); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, Volume_string, RIGHT_MODE); /* Infinite loop */ while(!CheckForUserInput()) { if (PauseResumeStatus == PAUSE_STATUS) { /* Turn ON LED orange: Audio play in pause */ BSP_LED_On(LED_ORANGE); /* Pause playing */ if(BSP_AUDIO_OUT_Pause() != 0) { Error_Handler(); } BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"Playback paused ", LEFT_MODE); PauseResumeStatus = IDLE_STATUS; } else if (PauseResumeStatus == RESUME_STATUS) { /* Turn OFF LED orange: Audio play running */ BSP_LED_Off(LED_ORANGE); /* Resume playing */ if(BSP_AUDIO_OUT_Resume() != 0) { Error_Handler(); } BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"Playback on-going", LEFT_MODE); PauseResumeStatus = IDLE_STATUS; } if (VolumeChange != 0) { VolumeChange = 0; if(BSP_AUDIO_OUT_SetVolume(volume) != 0) { Error_Handler(); } sprintf((char *) Volume_string, " Volume : %d%% ", volume); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, Volume_string, RIGHT_MODE); } if (UserOutputMode != UserOutputModePreviousState) { /* Change audio output */ BSP_AUDIO_OUT_SetOutputMode(UserOutputMode); UserOutputModePreviousState = UserOutputMode; } } /* Reset the EXTI configuration for Joystick SEL, UP and DOWN push buttons */ /* Configuration of the joystick in GPIO mode and no more EXTI */ BSP_PB_Init(BUTTON_SEL, BUTTON_MODE_GPIO); BSP_PB_Init(BUTTON_UP, BUTTON_MODE_GPIO); BSP_PB_Init(BUTTON_DOWN, BUTTON_MODE_GPIO); /* Stop Player before close Test */ if (BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW) != AUDIO_OK) { /* Audio Stop error */ Error_Handler(); } else { /* Turn OFF LED green: stop of Audio file play */ BSP_LED_Off(LED_GREEN); BSP_LED_Off(LED_ORANGE); } }
/** * @brief Test Audio Hardware. * The main objective of this test is to check the hardware connection of the * Audio peripheral. * @param None * @retval None */ void AudioRecord_Test(void) { BufferCtl.offset = BUFFER_OFFSET_NONE; if(BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) != AUDIO_OK) { /* Record Error */ Error_Handler(); } /* Turn ON LED3: start record */ BSP_LED_On(LED3); /* Start the record */ if (BSP_AUDIO_IN_Record((uint16_t*)&InternalBuffer[0], INTERNAL_BUFF_SIZE) != AUDIO_OK) { /* Record Error */ Error_Handler(); } BufferCtl.fptr = 0; AUDIODataReady = 0; /* Wait for the data to be ready with PCM form */ while (AUDIODataReady != 2) { if(BufferCtl.offset == BUFFER_OFFSET_HALF) { /* PDM to PCM data convert */ BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[0], (uint16_t*)&RecBuf[0]); /* Copy PCM data in internal buffer */ memcpy((uint16_t*)&WrBuffer[ITCounter * (PCM_OUT_SIZE*2)], RecBuf, PCM_OUT_SIZE*4); BufferCtl.offset = BUFFER_OFFSET_NONE; if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*4))-1) { AUDIODataReady = 1; AUDIOBuffOffset = 0; ITCounter++; } else if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) { AUDIODataReady = 2; AUDIOBuffOffset = WR_BUFFER_SIZE/2; ITCounter = 0; } else { ITCounter++; } } if(BufferCtl.offset == BUFFER_OFFSET_FULL) { /* PDM to PCM data convert */ BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[INTERNAL_BUFF_SIZE/2], (uint16_t*)&RecBuf[0]); /* Copy PCM data in internal buffer */ memcpy((uint16_t*)&WrBuffer[ITCounter * (PCM_OUT_SIZE*2)], RecBuf, PCM_OUT_SIZE*4); BufferCtl.offset = BUFFER_OFFSET_NONE; if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*4))-1) { AUDIODataReady = 1; AUDIOBuffOffset = 0; ITCounter++; } else if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) { AUDIODataReady = 2; AUDIOBuffOffset = WR_BUFFER_SIZE/2; ITCounter = 0; } else { ITCounter++; } } }; /* Stop audio record */ if (BSP_AUDIO_IN_Stop() != AUDIO_OK) { /* Record Error */ Error_Handler(); } /* Turn OFF LED3: record stopped */ BSP_LED_Off(LED3); /* Turn ON LED6: play recorded file */ BSP_LED_On(LED6); /* Play in the loop the recorded file */ /* Set variable to indicate play from record buffer */ AudioTest = 1; /* Set variable used to stop player before starting */ UserPressButton = 0; /* Initialize audio IN at REC_FREQ */ BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, 70, DEFAULT_AUDIO_IN_FREQ); /* Set the total number of data to be played */ AudioTotalSize = AUDIODATA_SIZE * WR_BUFFER_SIZE; /* Update the remaining number of data to be played */ AudioRemSize = 0; /* Update the WrBuffer audio pointer position */ CurrentPos = (uint16_t *)(WrBuffer); /* Play the recorded buffer */ BSP_AUDIO_OUT_Play(WrBuffer , AudioTotalSize); while(!UserPressButton) { } /* Stop Player before close Test */ if (BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW) != AUDIO_OK) { /* Audio Stop error */ Error_Handler(); } }
/** * @brief Test Audio Hardware. * The main objective of this test is to check the hardware connection of the * Audio peripheral. * @param None * @retval None */ void AudioPlay_demo(void) { WAVE_FormatTypeDef *waveformat = NULL; uint8_t Volume_string[20] = {0}; AudioPlay_SetHint(); /* Configuration of the EXTI for the joystick SEL push button for pause/resume */ /* UP/DOWN push buttons for change the volume */ BSP_PB_Init(BUTTON_SEL, BUTTON_MODE_EXTI); BSP_PB_Init(BUTTON_UP, BUTTON_MODE_EXTI); BSP_PB_Init(BUTTON_DOWN, BUTTON_MODE_EXTI); /* Retrieve Wave Sample rate*/ waveformat = (WAVE_FormatTypeDef*) AUDIO_FILE_ADDRESS; AudioPlay_DisplayInfos(waveformat); /* Initialize Audio Device */ if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, volume, waveformat->SampleRate) != 0) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, 130, (uint8_t*)"Initialization problem", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 145, (uint8_t*)"Audio Codec not detected", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 160, (uint8_t*)"Verify that jumper JP4 and JP5", CENTER_MODE); BSP_LCD_DisplayStringAt(0, 175, (uint8_t*)"are well set to I2C2 position", CENTER_MODE); Error_Handler(); } /* Set the total number of data to be played */ AudioTotalSize = (AUDIO_FILE_SIZE / AUDIODATA_SIZE); /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS); /* Start the audio player */ if(BSP_AUDIO_OUT_Play(CurrentPos,DMA_MAX((AudioTotalSize))) != 0) { Error_Handler(); } /* Turn ON LED green: start of Audio file play */ BSP_LED_On(LED_GREEN); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"Playback on-going", LEFT_MODE); sprintf((char *) Volume_string, " Volume : %d%% ", volume); BSP_LCD_DisplayStringAt((uint16_t)(-20), BSP_LCD_GetYSize()-30, Volume_string, RIGHT_MODE); /* Infinite loop */ while(!CheckForUserInput()) { if (PauseResumeStatus == PAUSE_STATUS) { /* Turn ON LED orange: Audio play in pause */ BSP_LED_On(LED_ORANGE); /* Pause playing */ if(BSP_AUDIO_OUT_Pause() != 0) { Error_Handler(); } BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"Playback paused ", LEFT_MODE); PauseResumeStatus = IDLE_STATUS; } else if (PauseResumeStatus == RESUME_STATUS) { /* Turn OFF LED orange: Audio play running */ BSP_LED_Off(LED_ORANGE); /* Resume playing */ if(BSP_AUDIO_OUT_Resume() != 0) { Error_Handler(); } BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"Playback on-going", LEFT_MODE); PauseResumeStatus = IDLE_STATUS; } if (VolumeChange != 0) { VolumeChange = 0; if(BSP_AUDIO_OUT_SetVolume(volume) != 0) { Error_Handler(); } sprintf((char *) Volume_string, " Volume : %d%% ", volume); BSP_LCD_DisplayStringAt((uint16_t)(-20), BSP_LCD_GetYSize()-30, Volume_string, RIGHT_MODE); } } /* Reset the EXTI configuration for Joystick SEL, UP and DOWN push buttons */ /* Configuration of the joystick in GPIO mode and no more EXTI */ BSP_PB_Init(BUTTON_SEL, BUTTON_MODE_GPIO); BSP_PB_Init(BUTTON_UP, BUTTON_MODE_GPIO); BSP_PB_Init(BUTTON_DOWN, BUTTON_MODE_GPIO); /* Stop Player before close Test */ if (BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW) != AUDIO_OK) { /* Audio Stop error */ Error_Handler(); } else { /* Turn OFF LED green: stop of Audio file play */ BSP_LED_Off(LED_GREEN); BSP_LED_Off(LED_ORANGE); } }
/** * @brief Test Audio Hardware. * The main objective of this test is to check the hardware connection of the * Audio peripheral. * @param None * @retval None */ void AudioPlay_Test(void) { /* Initial volume level (from 0 (Mute) to 100 (Max)) */ __IO uint8_t volume = 70; /* Initialize MEMS Accelerometer mounted on STM32F4-Discovery board */ if(BSP_ACCELERO_Init() != ACCELERO_OK) { /* Initialization Error */ Error_Handler(); } /* MEMS Accelerometer configure to manage PAUSE, RESUME operations */ BSP_ACCELERO_Click_ITConfig(); /* Turn ON LED6: start of Audio file play */ BSP_LED_On(LED6); /* Retrieve Wave Sample rate*/ waveformat = (WAVE_FormatTypeDef*) AUDIO_FILE_ADDRESS; /* Initialize Audio Device */ if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, volume, waveformat->SampleRate) != 0) { Error_Handler(); } /*Set variable used to stop player before starting */ UserPressButton = 0; AudioTest = 0; /* Set the total number of data to be played */ AudioTotalSize = AUDIO_FILE_SIZE; /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS); /* Start the audio player */ BSP_AUDIO_OUT_Play(CurrentPos, AudioTotalSize); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - AUDIODATA_SIZE * DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); /* Infinite loop */ while(!UserPressButton) { if (PauseResumeStatus == PAUSE_STATUS) { /* Turn ON LED4: Audio play in pause */ BSP_LED_On(LED4); /* Pause playing */ BSP_AUDIO_OUT_Pause(); PauseResumeStatus = IDLE_STATUS; } else if (PauseResumeStatus == RESUME_STATUS) { /* Turn OFF LED4: Audio play running */ BSP_LED_Off(LED4); /* Resume playing */ BSP_AUDIO_OUT_Resume(); PauseResumeStatus = IDLE_STATUS; } } /* Stop Player before close Test */ if (BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW) != AUDIO_OK) { /* Audio Stop error */ Error_Handler(); } }
/** * @brief Plays Wave from a mass storage. * @param AudioFreq: Audio Sampling Frequency * @retval None */ void WavePlayBack(uint32_t AudioFreq) { UINT bytesread = 0; /* Start playing */ AudioPlayStart = 1; RepeatState = REPEAT_ON; /* Initialize Wave player (Codec, DMA, I2C) */ if(WavePlayerInit(AudioFreq) != 0) { Error_Handler(); } /* Get Data from USB Flash Disk */ f_lseek(&FileRead, 0); f_read (&FileRead, &Audio_Buffer[0], AUDIO_BUFFER_SIZE, &bytesread); AudioRemSize = WaveDataLength - bytesread; /* Start playing Wave */ BSP_AUDIO_OUT_Play((uint16_t*)&Audio_Buffer[0], AUDIO_BUFFER_SIZE); LEDsState = LED6_TOGGLE; PauseResumeStatus = RESUME_STATUS; PressCount = 0; /* Check if the device is connected.*/ while((AudioRemSize != 0) && (AppliState != APPLICATION_IDLE)) { /* Test on the command: Playing */ if(CmdIndex == CMD_PLAY) { if(PauseResumeStatus == PAUSE_STATUS) { /* Stop Toggling LED2 to signal Pause */ LEDsState = STOP_TOGGLE; /* Pause playing Wave */ WavePlayerPauseResume(PauseResumeStatus); PauseResumeStatus = IDLE_STATUS; } else if(PauseResumeStatus == RESUME_STATUS) { /* Toggling LED6 to signal Play */ LEDsState = LED6_TOGGLE; /* Resume playing Wave */ WavePlayerPauseResume(PauseResumeStatus); PauseResumeStatus = IDLE_STATUS; } bytesread = 0; if(buffer_offset == BUFFER_OFFSET_HALF) { f_read(&FileRead, &Audio_Buffer[0], AUDIO_BUFFER_SIZE/2, (void *)&bytesread); buffer_offset = BUFFER_OFFSET_NONE; } if(buffer_offset == BUFFER_OFFSET_FULL) { f_read(&FileRead, &Audio_Buffer[AUDIO_BUFFER_SIZE/2], AUDIO_BUFFER_SIZE/2, (void *)&bytesread); buffer_offset = BUFFER_OFFSET_NONE; } if(AudioRemSize > (AUDIO_BUFFER_SIZE / 2)) { AudioRemSize -= bytesread; } else { AudioRemSize = 0; } } else { /* Stop playing Wave */ WavePlayerStop(); /* Close file */ f_close(&FileRead); AudioRemSize = 0; RepeatState = REPEAT_ON; break; } } #ifdef PLAY_REPEAT_DISABLED RepeatState = REPEAT_OFF; /* Stop playing Wave */ WavePlayerStop(); /* Close file */ f_close(&FileRead); /* Test on the command: Playing */ if(CmdIndex == CMD_PLAY) { LEDsState = LED4_TOGGLE; } #else LEDsState = LEDS_OFF; RepeatState = REPEAT_ON; AudioPlayStart = 0; /* Stop playing Wave */ WavePlayerStop(); /* Close file */ f_close(&FileRead); #endif /* PLAY_REPEAT_DISABLED */ }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 180 Mhz */ SystemClock_Config(); /* Configure LED1, LED2, LED3 and LED4 */ BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); BSP_LED_Init(LED4); /* Initialize the Push buttons */ /* Wakeup button used for Volume Low */ BSP_PB_Init(BUTTON_WAKEUP, BUTTON_MODE_GPIO); /* Tamper button used for Volume High */ BSP_PB_Init(BUTTON_TAMPER, BUTTON_MODE_GPIO); /* Initialize the LCD */ BSP_LCD_Init(); BSP_LCD_LayerDefaultInit(1, 0xC0130000); BSP_LCD_SelectLayer(1); /* Display message on EVAL LCD **********************************************/ /* Clear the LCD */ BSP_LCD_Clear(LCD_COLOR_BLUE); /* Set the LCD Back Color */ BSP_LCD_SetBackColor(LCD_COLOR_BLUE); /* Set the LCD Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_WHITE); BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)MESSAGE1, CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(1), (uint8_t *)MESSAGE2, CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(2), (uint8_t *)MESSAGE3, CENTER_MODE); /* Turn on LEDs available on EVAL *******************************************/ BSP_LED_On(LED1); BSP_LED_On(LED2); BSP_LED_On(LED3); BSP_LED_On(LED4); /* Initialize the Audio codec and all related peripherals (SAI, I2C, IOs...) */ if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_BOTH, uwVolume, SAI_AUDIO_FREQUENCY_48K) == 0) { BSP_LCD_DisplayStringAt(0, LINE(4), (uint8_t *)"====================", CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"Tamper: Vol+ ", CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)"Wakeup: Vol- ", CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(7), (uint8_t *)"====================", CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(8), (uint8_t *)" AUDIO CODEC OK ", CENTER_MODE); } else { BSP_LCD_DisplayStringAt(0, LINE(4), (uint8_t *)" AUDIO CODEC FAIL ", CENTER_MODE); BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)" Try to reset board ", CENTER_MODE); } /* Normal mode description: Start playing the audio file (using DMA stream) . Using this mode, the application can run other tasks in parallel since the DMA is handling the Audio Transfer instead of the CPU. The only task remaining for the CPU will be the management of the DMA Transfer Complete interrupt or the Half Transfer Complete interrupt in order to load again the buffer and to calculate the remaining data. Circular mode description: Start playing the file from a circular buffer, once the DMA is enabled it always run. User has to fill periodically the buffer with the audio data using Transfer complete and/or half transfer complete interrupts callbacks (EVAL_AUDIO_TransferComplete_CallBack() or EVAL_AUDIO_HalfTransfer_CallBack()... In this case the audio data file is smaller than the DMA max buffer size 65535 so there is no need to load buffer continuously or manage the transfer complete or Half transfer interrupts callbacks. */ AudioTotalSize = (AUDIO_FILE_SIZE - AUDIO_START_OFFSET_ADDRESS)/AUDIODATA_SIZE; /* Set the current audio pointer position */ CurrentPos = (uint16_t *)(AUDIO_FILE_ADDRESS + AUDIO_START_OFFSET_ADDRESS); /* Start the audio player */ BSP_AUDIO_OUT_Play((uint16_t*)CurrentPos, (AUDIO_FILE_SIZE - AUDIO_START_OFFSET_ADDRESS)); /* Update the remaining number of data to be played */ AudioRemSize = AudioTotalSize - DMA_MAX(AudioTotalSize); /* Update the current audio pointer position */ CurrentPos += DMA_MAX(AudioTotalSize); /* Display the state on the screen */ BSP_LCD_DisplayStringAt(0, LINE(9), (uint8_t *)" PLAYING... ", CENTER_MODE); /* Infinite loop */ while(1) { /* Check on the Volume high button */ if (BSP_PB_GetState(BUTTON_WAKEUP) != RESET) { /* wait to avoid rebound */ while (BSP_PB_GetState(BUTTON_WAKEUP) != RESET); /* Decrease volume by 5% */ if (uwVolume > 5) uwVolume -= 5; else uwVolume = 0; /* Apply the new volume to the codec */ BSP_AUDIO_OUT_SetVolume(uwVolume); BSP_LCD_DisplayStringAt(0, LINE(10), (uint8_t *)" VOL: - ", CENTER_MODE); } /* Check on the Volume high button */ if (BSP_PB_GetState(BUTTON_TAMPER) == RESET) { /* Wait to avoid rebound */ while (BSP_PB_GetState(BUTTON_TAMPER) == RESET); /* Increase volume by 5% */ if (uwVolume < 95) uwVolume += 5; else uwVolume = 100; /* Apply the new volume to the codec */ BSP_AUDIO_OUT_SetVolume(uwVolume); BSP_LCD_DisplayStringAt(0, LINE(10), (uint8_t *)" VOL: + ", CENTER_MODE); } /* Toggle LED4 */ BSP_LED_Toggle(LED3); /* Insert 100 ms delay */ HAL_Delay(100); /* Toggle LED2 */ BSP_LED_Toggle(LED2); /* Insert 100 ms delay */ HAL_Delay(100); } }
void BSP_Start_Audio(uint8_t filename[255]) { UINT bytesread = 0; char path[] = "0:/"; char* wavefilename = NULL; WAVE_FormatTypeDef waveformat; uint32_t WaveDataLength = 0; /* Get the read out protection status */ if(f_opendir(&Directory, path) == FR_OK) { wavefilename = filename; /* Open the Wave file to be played */ if(f_open(&FileRead, wavefilename , FA_READ) == FR_OK) { HAL_Delay(1); /* Read sizeof(WaveFormat) from the selected file */ f_read (&FileRead, &waveformat, sizeof(waveformat), &bytesread); /* Set WaveDataLenght to the Speech Wave length */ WaveDataLength = waveformat.FileSize; /* Play */ /* Initialize I2S */ I2S3_Init(waveformat.SampleRate); /* Initialize Wave player (Codec, DMA, I2C) */ if(WavePlayerInit(waveformat.SampleRate) != 0) { while(1); } /* Get Data from USB Flash Disk */ f_lseek(&FileRead, 0); f_read (&FileRead, &Audio_Buffer[0], AUDIO_BUFFER_SIZE, &bytesread); AudioRemSize = WaveDataLength - bytesread; /* Start playing Wave */ BSP_AUDIO_OUT_Play((uint16_t*)&Audio_Buffer[0], AUDIO_BUFFER_SIZE); PauseResumeStatus = RESUME_STATUS; PressCount = 0; /* Check if the device is connected.*/ while((AudioRemSize != 0) && (Appli_state != APPLICATION_IDLE)) { /* Test on the command: Playing */ if(CmdIndex == CMD_PLAY) { if(PauseResumeStatus == PAUSE_STATUS) { /* Stop Toggling LED2 to signal Pause */ /* Pause playing Wave */ WavePlayerPauseResume(PauseResumeStatus); PauseResumeStatus = IDLE_STATUS; } else if(PauseResumeStatus == RESUME_STATUS) { /* Toggling LED6 to signal Play */ /* Resume playing Wave */ WavePlayerPauseResume(PauseResumeStatus); PauseResumeStatus = IDLE_STATUS; } bytesread = 0; if(buffer_offset == BUFFER_OFFSET_HALF) { f_read(&FileRead,&Audio_Buffer[0], AUDIO_BUFFER_SIZE/2,(void *)&bytesread); buffer_offset = BUFFER_OFFSET_NONE; } if(buffer_offset == BUFFER_OFFSET_FULL) { f_read(&FileRead,&Audio_Buffer[AUDIO_BUFFER_SIZE/2], AUDIO_BUFFER_SIZE/2,(void *)&bytesread); buffer_offset = BUFFER_OFFSET_NONE; } if(AudioRemSize > (AUDIO_BUFFER_SIZE / 2)) { AudioRemSize -= bytesread; } else { /* Stop playing Wave */ WavePlayerStop(); f_close(&FileRead); HAL_I2S_DeInit(&hAudioOutI2s); break; } } } } } }
/** * @brief Starts Wave player. * @param None * @retval None */ void WavePlayerStart(WAVE_FormatTypeDef waveformat, WavePlayer_getDataCB_type getDataCB, uint8_t volume) { int32_t bytesread = 0; int32_t length; int16_t *pBuf = NULL; uint32_t AudioRemSize = 0; uint32_t WaveDataLength = 0; int16_t ValorEficaz = 0; int16_t Contador = 0; int16_t Bandera = 0; uint32_t tickcontar = 0; /* Set WaveDataLenght to the Speech Wave length */ WaveDataLength = waveformat.FileSize; AudioRemSize = WaveDataLength - sizeof(WAVE_FormatTypeDef); /* Initialize Wave player (Codec, DMA, I2C) */ if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, volume, waveformat.SampleRate) != 0) { Error_Handler(); } /* Start playing Wave */ BSP_AUDIO_OUT_Play((uint16_t*)&Audio_BufferStereo[0], sizeof(Audio_BufferStereo)); LEDsState = LED6_TOGGLE; /* Toggling LED6 to signal Play */ LEDsState = LED6_TOGGLE; LEDsState = LEDS_OFF; /* Resume playing Wave */ BSP_AUDIO_OUT_Resume(); if (CHANNEL_MONO == waveformat.NbrChannels) { length = AUDIO_BUFFER_STEREO_LENGTH/4; } else { length = AUDIO_BUFFER_STEREO_LENGTH/2; } while (AudioRemSize > 0) { if (BUFFER_OFFSET_HALF == BufferOffset) { pBuf = &Audio_BufferStereo[0]; } if (BUFFER_OFFSET_FULL == BufferOffset) { pBuf = &Audio_BufferStereo[AUDIO_BUFFER_STEREO_LENGTH/2]; } if (NULL != pBuf) { bytesread = getDataCB(pBuf, length); arm_rms_q15(pBuf, length, &ValorEficaz); // printf("Valor Eficaz = %d\r\n", ValorEficaz); // 0x03E8 Hexadecimal = 1000 Decimal // se comprobo con la salida printf("Valor Eficaz = %d\r\n", ValorEficaz); // que los valores de los tonos de 1 KHz tenian un valor eficaz superior // a 1000. if (ValorEficaz > 0x03E8) { Bandera = 1; Contador = Contador + 1; } else { if (Bandera == 1) { Bandera = 2; } } BSP_LED_Off(LED3); BSP_LED_Off(LED6); if (Bandera == 2) { Bandera = 0; if (Contador > 10) { BSP_LED_On(LED3); Contador = 0; if (firstfind == 0) { firstfind = 1; } } else { BSP_LED_On(LED6); Contador = 0; } } if (firstfind != 0 ) { tickcontar = HAL_GetTick(); if (firstfind == 1) { tickstart = tickcontar; firstfind = 2; } if ((tickcontar - tickstart) > T60SEG) { tickstart=tickcontar; } if ((tickcontar - tickstart) <= T1SEG) { BSP_LED_On(LED5); } else { BSP_LED_Off(LED5); } } if (CHANNEL_MONO == waveformat.NbrChannels) { convertToStereo(pBuf, pBuf, length); } BufferOffset = BUFFER_OFFSET_NONE; pBuf = NULL; if (bytesread <= 0) { AudioRemSize = 0; } else { AudioRemSize -= bytesread; if (AudioRemSize < (length*2)) { AudioRemSize = 0; } } } } BSP_LED_Off(LED3); BSP_LED_Off(LED6); // LEDsState = LEDS_OFF; BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW); }