1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
32
33
34
35
36
43
46
52
53
54
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
92
96
97
102
106
107
113
125
126
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
160
161
162
163
164
168
172
176
177
178
180
181
182
183
184
185
190
191
192
193
194
195
196
197
198
199
200
201
202
203
207
208
209
210
211
212
213
218
223
224
225
226
227
232
233
234
235
236
237
238
242
243
244
245
246
251
261
262
263
268
278
283
284
285
286
287
288
289
290
291
292
293
294
295
296
302
308
309
315
316
317
318
319
320
321
333
334
335
336
341
351
352
357
361
362
367
375
376
381
389
390
395
399
400
405
462
463
466
467
/* ... */
#include "audio_player_app.h"
/* ... */
/* ... */
Includes
static FIL wav_file;
static osMessageQId AudioEvent = 0;
static osThreadId AudioThreadId = 0;
Private variables
static void Audio_Thread(void const * argument);
Private function prototypes
static void Audio_Thread(void const * argument);
static void AUDIO_TransferComplete_CallBack(void);
static void AUDIO_HalfTransfer_CallBack(void);
static void AUDIO_Error_CallBack(void);
Private function prototypes
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Init(uint8_t volume)
{
portENTER_CRITICAL();
BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, volume, I2S_AUDIOFREQ_48K);
haudio.out.state = AUDIOPLAYER_STOP;
haudio.out.mute = MUTE_OFF;
haudio.out.volume = volume;
AUDIO_IF_RegisterCallbacks(AUDIO_TransferComplete_CallBack,
AUDIO_HalfTransfer_CallBack,
AUDIO_Error_CallBack);
osMessageQDef(AUDIO_Queue, 1, uint16_t);
AudioEvent = osMessageCreate (osMessageQ(AUDIO_Queue), NULL);
osThreadDef(osAudio_Thread, Audio_Thread, osPriorityRealtime, 0, 512);
AudioThreadId = osThreadCreate (osThread(osAudio_Thread), NULL);
portEXIT_CRITICAL();
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_StateTypdef AUDIOPLAYER_GetState(void)
{
return haudio.out.state;
}{ ... }
/* ... */
uint32_t AUDIOPLAYER_GetVolume(void)
{
return haudio.out.volume;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_SetVolume(uint32_t volume)
{
if(BSP_AUDIO_OUT_SetVolume(volume) == AUDIO_OK)
{
haudio.out.volume = volume;
return AUDIOPLAYER_ERROR_NONE;
}if (BSP_AUDIO_OUT_SetVolume(volume) == AUDIO_OK) { ... }
else
{
return AUDIOPLAYER_ERROR_HW;
}else { ... }
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Play(uint32_t frequency)
{
uint32_t numOfReadBytes;
haudio.out.state = AUDIOPLAYER_PLAY;
if(f_read(&wav_file,
&haudio.buff[0],
AUDIO_OUT_BUFFER_SIZE,
(void *)&numOfReadBytes) == FR_OK)
{
if(numOfReadBytes != 0)
{
BSP_AUDIO_OUT_Pause();
BSP_AUDIO_OUT_SetFrequency(frequency);
osThreadResume(AudioThreadId);
BSP_AUDIO_OUT_Play((uint16_t*)&haudio.buff[0], AUDIO_OUT_BUFFER_SIZE);
return AUDIOPLAYER_ERROR_NONE;
}if (numOfReadBytes != 0) { ... }
}if (f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE, (void *)&numOfReadBytes) == FR_OK) { ... }
return AUDIOPLAYER_ERROR_IO;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Process(void)
{
switch(haudio.out.state)
{
case AUDIOPLAYER_START:
haudio.out.state = AUDIOPLAYER_PLAY;
break;
case AUDIOPLAYER_START:
case AUDIOPLAYER_EOF:
AUDIOPLAYER_NotifyEndOfFile();
break;
case AUDIOPLAYER_EOF:
case AUDIOPLAYER_ERROR:
AUDIOPLAYER_Stop();
break;
case AUDIOPLAYER_ERROR:
case AUDIOPLAYER_STOP:
case AUDIOPLAYER_PLAY:
default:
break;default
}switch (haudio.out.state) { ... }
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_DeInit(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
haudio.out.state = AUDIOPLAYER_STOP;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48;
PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLI2SQ;
PeriphClkInitStruct.PLLI2S.PLLI2SM = 8;
PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;
PeriphClkInitStruct.PLLI2S.PLLI2SQ = 4;
PeriphClkInitStruct.PLLI2S.PLLI2SR = 4;
if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
while(1);
}if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { ... }
BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW);
BSP_AUDIO_OUT_DeInit();
f_close(&wav_file);
if(AudioEvent != 0)
{
vQueueDelete(AudioEvent);
AudioEvent = 0;
}if (AudioEvent != 0) { ... }
if(AudioThreadId != 0)
{
osThreadTerminate(AudioThreadId);
AudioThreadId = 0;
}if (AudioThreadId != 0) { ... }
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Stop(void)
{
BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW);
haudio.out.state = AUDIOPLAYER_STOP;
f_close(&wav_file);
if(AudioThreadId != 0)
{
osThreadSuspend(AudioThreadId);
}if (AudioThreadId != 0) { ... }
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Pause(void)
{
if(AudioThreadId != 0)
{
osThreadSuspend(AudioThreadId);
}if (AudioThreadId != 0) { ... }
haudio.out.state = AUDIOPLAYER_PAUSE;
BSP_AUDIO_OUT_Pause();
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Resume(void)
{
if(AudioThreadId != 0)
{
osThreadResume(AudioThreadId);
}if (AudioThreadId != 0) { ... }
haudio.out.state = AUDIOPLAYER_PLAY;
BSP_AUDIO_OUT_Resume();
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_SetPosition(uint32_t position)
{
long file_pos;
file_pos = f_size(&wav_file) / AUDIO_OUT_BUFFER_SIZE / 100;
file_pos *= (position * AUDIO_OUT_BUFFER_SIZE);
AUDIOPLAYER_Pause();
f_lseek(&wav_file, file_pos);
AUDIOPLAYER_Resume();
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Mute(uint8_t state)
{
BSP_AUDIO_OUT_SetMute(state);
return AUDIOPLAYER_ERROR_NONE;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_GetFileInfo(char* file, WAV_InfoTypedef* info)
{
uint32_t numOfReadBytes;
AUDIOPLAYER_ErrorTypdef ret = AUDIOPLAYER_ERROR_IO;
FIL fsfile;
if( f_open(&fsfile, file, FA_OPEN_EXISTING | FA_READ) == FR_OK)
{
if(f_read(&fsfile, info, sizeof(WAV_InfoTypedef), (void *)&numOfReadBytes) == FR_OK)
{
if((info->ChunkID == 0x46464952) && (info->AudioFormat == 1))
{
ret = AUDIOPLAYER_ERROR_NONE;
}if ((info->ChunkID == 0x46464952) && (info->AudioFormat == 1)) { ... }
}if (f_read(&fsfile, info, sizeof(WAV_InfoTypedef), (void *)&numOfReadBytes) == FR_OK) { ... }
f_close(&fsfile);
}if (f_open(&fsfile, file, FA_OPEN_EXISTING | FA_READ) == FR_OK) { ... }
return ret;
}{ ... }
/* ... */
AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_SelectFile(char* file)
{
AUDIOPLAYER_ErrorTypdef ret = AUDIOPLAYER_ERROR_IO;
if( f_open(&wav_file, file, FA_OPEN_EXISTING | FA_READ) == FR_OK)
{
f_lseek(&wav_file, sizeof(WAV_InfoTypedef));
ret = AUDIOPLAYER_ERROR_NONE;
}if (f_open(&wav_file, file, FA_OPEN_EXISTING | FA_READ) == FR_OK) { ... }
return ret;
}{ ... }
/* ... */
uint32_t AUDIOPLAYER_GetProgress(void)
{
return (wav_file.fptr);
}{ ... }
/* ... */
static void AUDIO_TransferComplete_CallBack(void)
{
if(haudio.out.state == AUDIOPLAYER_PLAY)
{
BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&haudio.buff[0], AUDIO_OUT_BUFFER_SIZE /2);
osMessagePut ( AudioEvent, PLAY_BUFFER_OFFSET_FULL, 0);
}if (haudio.out.state == AUDIOPLAYER_PLAY) { ... }
}{ ... }
/* ... */
static void AUDIO_HalfTransfer_CallBack(void)
{
if(haudio.out.state == AUDIOPLAYER_PLAY)
{
BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&haudio.buff[AUDIO_OUT_BUFFER_SIZE /2], AUDIO_OUT_BUFFER_SIZE /2);
osMessagePut ( AudioEvent, PLAY_BUFFER_OFFSET_HALF, 0);
}if (haudio.out.state == AUDIOPLAYER_PLAY) { ... }
}{ ... }
/* ... */
static void AUDIO_Error_CallBack(void)
{
haudio.out.state = AUDIOPLAYER_ERROR;
}{ ... }
/* ... */
static void Audio_Thread(void const * argument)
{
uint32_t numOfReadBytes;
osEvent event;
for(;;)
{
event = osMessageGet(AudioEvent, 100 );
if( event.status == osEventMessage )
{
if(haudio.out.state == AUDIOPLAYER_PLAY)
{
switch(event.value.v)
{
case PLAY_BUFFER_OFFSET_HALF:
if(f_read(&wav_file,
&haudio.buff[0],
AUDIO_OUT_BUFFER_SIZE/2,
(void *)&numOfReadBytes) == FR_OK)
{
if(numOfReadBytes == 0)
{
haudio.out.state = AUDIOPLAYER_EOF;
}if (numOfReadBytes == 0) { ... }
}if (f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { ... }
else
{
haudio.out.state = AUDIOPLAYER_ERROR;
}else { ... }
break;
case PLAY_BUFFER_OFFSET_HALF:
case PLAY_BUFFER_OFFSET_FULL:
if(f_read(&wav_file,
&haudio.buff[AUDIO_OUT_BUFFER_SIZE/2],
AUDIO_OUT_BUFFER_SIZE/2,
(void *)&numOfReadBytes) == FR_OK)
{
if(numOfReadBytes == 0)
{
haudio.out.state = AUDIOPLAYER_EOF;
}if (numOfReadBytes == 0) { ... }
}if (f_read(&wav_file, &haudio.buff[AUDIO_OUT_BUFFER_SIZE/2], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { ... }
else
{
haudio.out.state = AUDIOPLAYER_ERROR;
}else { ... }
break;
case PLAY_BUFFER_OFFSET_FULL:
default:
break;default
}switch (event.value.v) { ... }
}if (haudio.out.state == AUDIOPLAYER_PLAY) { ... }
}if (event.status == osEventMessage) { ... }
}for (;;) { ... }
}{ ... }
/* ... */
/* ... */