1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
28
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
88
89
90
91
92
93
94
95
96
102
106
107
112
116
117
122
123
124
125
126
127
128
129
130
131
132
133
134
143
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
228
229
230
231
232
233
234
235
236
237
238
244
250
254
255
256
261
262
263
264
265
266
267
268
269
270
271
277
283
287
288
289
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
314
315
316
317
323
324
325
331
338
344
350
356
360
364
371
377
381
385
391
392
393
394
395
396
397
398
399
400
401
402
408
409
410
417
418
419
420
421
422
423
424
425
426
427
428
/* ... */
#include "main.h"
#include "waverecorder.h"
#include "string.h"
/* ... */
Includes
typedef struct {
int32_t offset;
uint32_t fptr;
...}Audio_BufferTypeDef;
Private typedef
__IO uint32_t WaveCounter = 0;
extern __IO uint32_t CmdIndex, LEDsState, TimeRecBase;
FIL WavFile;
extern MSC_ApplicationTypeDef AppliState;
uint32_t WaveRecStatus = 0;
uint8_t pHeaderBuff[44];
uint16_t WrBuffer[WR_BUFFER_SIZE];
static uint16_t RecBuf[PCM_OUT_SIZE*2];
static uint16_t InternalBuffer[INTERNAL_BUFF_SIZE];
__IO uint32_t ITCounter = 0;
Audio_BufferTypeDef BufferCtl;
__IO uint32_t AUDIODataReady = 0, AUDIOBuffOffset = 0;
WAVE_FormatTypeDef WaveFormat;
__IO FRESULT res;Private variables
static uint32_t WavProcess_EncInit(uint32_t Freq, uint8_t* pHeader);
static uint32_t WavProcess_HeaderInit(uint8_t* pHeader, WAVE_FormatTypeDef* pWaveFormatStruct);
static uint32_t WavProcess_HeaderUpdate(uint8_t* pHeader, WAVE_FormatTypeDef* pWaveFormatStruct);
/* ... */
/* ... */
uint8_t WaveRecorderStart(uint16_t* pBuf, uint32_t wSize)
{
return (BSP_AUDIO_IN_Record(pBuf, wSize));
}{ ... }
/* ... */
uint32_t WaveRecorderStop(void)
{
return BSP_AUDIO_IN_Stop();
}{ ... }
/* ... */
void WaveRecorderProcess(void)
{
uint32_t byteswritten = 0;
WaveCounter = 0;
LEDsState = LEDS_OFF;
f_unlink(REC_WAVE_NAME);
if((AppliState == APPLICATION_IDLE) || (f_open(&WavFile, REC_WAVE_NAME, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK))
{
while(1)
{
/* ... */
BSP_LED_Toggle(LED5);
}while (1) { ... }
}if ((AppliState == APPLICATION_IDLE) || (f_open(&WavFile, REC_WAVE_NAME, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)) { ... }
else
{
WaveRecStatus = 1;
}else { ... }
WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff);
f_write(&WavFile, pHeaderBuff, 44, (void *)&byteswritten);
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);
TimeRecBase = 0;
ITCounter = 0;
LEDsState = LED3_TOGGLE;
while(AppliState != APPLICATION_IDLE)
{
if(TimeRecBase <= DEFAULT_TIME_REC)
{
if(AUDIODataReady == 1)
{
res = f_write(&WavFile, (uint8_t*)(WrBuffer+AUDIOBuffOffset), WR_BUFFER_SIZE, (void*)&byteswritten);
if(res != FR_OK)
{
Error_Handler();
}if (res != FR_OK) { ... }
BufferCtl.fptr += byteswritten;
AUDIODataReady = 0;
}if (AUDIODataReady == 1) { ... }
if(CmdIndex != CMD_RECORD)
{
WaveRecorderStop();
CmdIndex = CMD_PLAY;
LEDsState = LED6_TOGGLE;
break;
}if (CmdIndex != CMD_RECORD) { ... }
}if (TimeRecBase <= DEFAULT_TIME_REC) { ... }
else
{
WaveRecorderStop();
CmdIndex = CMD_STOP;
LEDsState = LED4_TOGGLE;
AUDIODataReady = 0;
break;
}else { ... }
}while (AppliState != APPLICATION_IDLE) { ... }
f_lseek(&WavFile, 0);
WavProcess_HeaderUpdate(pHeaderBuff, &WaveFormat);
f_write(&WavFile, pHeaderBuff, 44, (void*)&byteswritten);
f_close (&WavFile);
f_mount(NULL, 0, 1);
CmdIndex = CMD_PLAY;
}{ ... }
/* ... */
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[INTERNAL_BUFF_SIZE/2], (uint16_t*)&RecBuf[0]);
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++;
}if (ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*4))-1) { ... }
else if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1)
{
AUDIODataReady = 1;
AUDIOBuffOffset = WR_BUFFER_SIZE/2;
ITCounter = 0;
}else if (ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) { ... }
else
{
ITCounter++;
}else { ... }
}{ ... }
/* ... */
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[0], (uint16_t*)&RecBuf[0]);
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++;
}if (ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*4))-1) { ... }
else if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1)
{
AUDIODataReady = 1;
AUDIOBuffOffset = WR_BUFFER_SIZE/2;
ITCounter = 0;
}else if (ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) { ... }
else
{
ITCounter++;
}else { ... }
}{ ... }
/* ... */
static uint32_t WavProcess_EncInit(uint32_t Freq, uint8_t* pHeader)
{
WaveFormat.SampleRate = Freq;
WaveFormat.NbrChannels = 2;
WaveFormat.BitPerSample = 16;
WaveFormat.FileSize = 0x001D4C00;
WaveFormat.SubChunk1Size = 44;
WaveFormat.ByteRate = (WaveFormat.SampleRate * \
(WaveFormat.BitPerSample/8) * \
WaveFormat.NbrChannels);
WaveFormat.BlockAlign = WaveFormat.NbrChannels * \
(WaveFormat.BitPerSample/8);
if(WavProcess_HeaderInit(pHeader, &WaveFormat))
{
return 1;
}if (WavProcess_HeaderInit(pHeader, &WaveFormat)) { ... }
return 0;
}{ ... }
/* ... */
static uint32_t WavProcess_HeaderInit(uint8_t* pHeader, WAVE_FormatTypeDef* pWaveFormatStruct)
{
pHeader[0] = 'R';
pHeader[1] = 'I';
pHeader[2] = 'F';
pHeader[3] = 'F';
write chunkID, must be 'RIFF'
/* ... */
pHeader[4] = 0x00;
pHeader[5] = 0x4C;
pHeader[6] = 0x1D;
pHeader[7] = 0x00;Write the file length
pHeader[8] = 'W';
pHeader[9] = 'A';
pHeader[10] = 'V';
pHeader[11] = 'E';
Write the file format, must be 'WAVE'
pHeader[12] = 'f';
pHeader[13] = 'm';
pHeader[14] = 't';
pHeader[15] = ' ';
Write the format chunk, must be'fmt '
pHeader[16] = 0x10;
pHeader[17] = 0x00;
pHeader[18] = 0x00;
pHeader[19] = 0x00;
Write the length of the 'fmt' data, must be 0x10
pHeader[20] = 0x01;
pHeader[21] = 0x00;
Write the audio format, must be 0x01 (PCM)
pHeader[22] = pWaveFormatStruct->NbrChannels;
pHeader[23] = 0x00;
Write the number of channels, ie. 0x01 (Mono)
pHeader[24] = (uint8_t)((pWaveFormatStruct->SampleRate & 0xFF));
pHeader[25] = (uint8_t)((pWaveFormatStruct->SampleRate >> 8) & 0xFF);
pHeader[26] = (uint8_t)((pWaveFormatStruct->SampleRate >> 16) & 0xFF);
pHeader[27] = (uint8_t)((pWaveFormatStruct->SampleRate >> 24) & 0xFF);
Write the Sample Rate in Hz
pHeader[28] = (uint8_t)((pWaveFormatStruct->ByteRate & 0xFF));
pHeader[29] = (uint8_t)((pWaveFormatStruct->ByteRate >> 8) & 0xFF);
pHeader[30] = (uint8_t)((pWaveFormatStruct->ByteRate >> 16) & 0xFF);
pHeader[31] = (uint8_t)((pWaveFormatStruct->ByteRate >> 24) & 0xFF);
Write the Byte Rate
pHeader[32] = pWaveFormatStruct->BlockAlign;
pHeader[33] = 0x00;
Write the block alignment
pHeader[34] = pWaveFormatStruct->BitPerSample;
pHeader[35] = 0x00;
Write the number of bits per sample
pHeader[36] = 'd';
pHeader[37] = 'a';
pHeader[38] = 't';
pHeader[39] = 'a';
Write the Data chunk, must be 'data'
pHeader[40] = 0x00;
pHeader[41] = 0x4C;
pHeader[42] = 0x1D;
pHeader[43] = 0x00;
return 0;
}{ ... }
/* ... */
static uint32_t WavProcess_HeaderUpdate(uint8_t* pHeader, WAVE_FormatTypeDef* pWaveFormatStruct)
{
/* ... */
pHeader[4] = (uint8_t)(BufferCtl.fptr);
pHeader[5] = (uint8_t)(BufferCtl.fptr >> 8);
pHeader[6] = (uint8_t)(BufferCtl.fptr >> 16);
pHeader[7] = (uint8_t)(BufferCtl.fptr >> 24);Write the file length
BufferCtl.fptr -=44;
pHeader[40] = (uint8_t)(BufferCtl.fptr);
pHeader[41] = (uint8_t)(BufferCtl.fptr >> 8);
pHeader[42] = (uint8_t)(BufferCtl.fptr >> 16);
pHeader[43] = (uint8_t)(BufferCtl.fptr >> 24);
return 0;
}{ ... }
/* ... */