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
90
94
95
100
104
105
111
123
124
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
158
159
160
161
162
166
170
174
175
176
178
179
180
181
182
183
188
189
190
191
192
193
194
195
196
197
198
199
200
201
205
206
207
208
209
210
211
216
221
222
223
224
225
230
231
232
233
234
235
236
240
241
242
243
244
249
259
260
261
266
276
281
282
283
284
285
286
287
288
289
290
291
292
293
294
300
306
307
313
314
315
316
317
318
319
331
332
333
334
339
349
350
355
359
360
365
373
374
379
387
388
393
397
398
403
460
461
464
465
/* ... */
#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)
{
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);
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 (;;) { ... }
}{ ... }
/* ... */
/* ... */