1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
32
33
34
35
36
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
89
93
94
99
103
104
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
130
131
132
133
134
135
136
137
138
139
140
141
147
151
152
153
158
162
163
168
169
170
171
172
173
183
184
185
186
191
192
193
194
195
196
197
198
199
200
216
217
218
219
220
225
226
227
233
234
240
241
242
243
248
249
254
255
256
257
262
263
264
265
266
267
268
269
270
280
281
282
283
284
285
286
290
291
292
293
294
299
300
301
302
303
304
305
306
307
311
312
313
314
319
320
321
327
333
334
340
346
347
348
349
354
371
372
373
378
379
380
381
382
383
384
385
386
390
395
396
397
402
403
404
405
406
407
408
409
410
414
419
420
421
426
430
431
432
437
445
446
451
459
460
465
469
470
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
499
500
501
505
506
507
524
526
527
528
529
574
575
576
577
578
579
580
585
586
587
588
589
590
591
592
593
594
595
600
601
602
603
604
605
606
607
608
609
610
611
616
617
618
619
620
621
622
623
624
625
628
629
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
654
655
656
657
663
664
665
671
678
684
690
696
700
704
711
717
721
725
731
732
733
734
735
736
737
738
739
740
741
742
748
749
750
757
758
759
760
761
762
763
764
765
766
767
768
771
772
/* ... */
#include "audio_recorder_app.h"
/* ... */
/* ... */
Includes
static FIL wav_file;
static osMessageQId AudioEvent = 0;
static osThreadId AudioThreadId = 0;
static WAV_InfoTypedef AudioInfo;
static uint8_t pHeaderBuff[44];Private variables
static void Audio_Thread(void const * argument);
static uint32_t WavProcess_EncInit(uint32_t Freq, uint8_t* pHeader);
static uint32_t WavProcess_HeaderInit(uint8_t* pHeader, WAV_InfoTypedef* pAudioInfoStruct);
static uint32_t WavProcess_HeaderUpdate(uint8_t* pHeader, WAV_InfoTypedef* pAudioInfoStruct);
static void AUDIO_TransferComplete_CallBack(void);
static void AUDIO_HalfTransfer_CallBack(void);
static void AUDIO_Error_CallBack(void);
extern void _cbNotifyStateChange (void) ;
Private function prototypes
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_Init(uint8_t volume)
{
haudio.in.volume = DEFAULT_REC_AUDIO_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, osPriorityNormal, 0, 1024);
AudioThreadId = osThreadCreate (osThread(osAudio_Thread), NULL);
haudio.in.state = AUDIO_RECORDER_IDLE;
return AUDIO_RECORDER_ERROR_NONE;
}{ ... }
/* ... */
AUDIO_RECORDER_StateTypdef AUDIO_RECORDER_GetState(void)
{
return haudio.in.state;
}{ ... }
/* ... */
uint32_t AUDIO_RECORDER_GetVolume(void)
{
return haudio.in.volume;
}{ ... }
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StartRec(uint32_t frequency)
{
uint32_t byteswritten = 0;
WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff);
haudio.ppcm = 0;
if(f_write(&wav_file, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK)
{
if(byteswritten != 0)
{
BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR);
BSP_AUDIO_IN_Record((uint16_t*)&haudio.pdm[0], AUDIO_IN_PDM_BUFFER_SIZE);
if(haudio.in.state == AUDIO_RECORDER_SUSPENDED)
{
osThreadResume(AudioThreadId);
}if (haudio.in.state == AUDIO_RECORDER_SUSPENDED) { ... }
haudio.in.state = AUDIO_RECORDER_RECORDING;
haudio.in.fptr = byteswritten;
return AUDIO_RECORDER_ERROR_NONE;
}if (byteswritten != 0) { ... }
}if (f_write(&wav_file, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK) { ... }
return AUDIO_RECORDER_ERROR_IO;
}{ ... }
/* ... */
WAV_InfoTypedef* AUDIO_RECORDER_GetFileInfo(void)
{
return &AudioInfo;
}{ ... }
/* ... */
void AUDIO_RECORDER_RemoveAudioFile(char const *fname)
{
f_unlink(fname);
}{ ... }
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_SelectFile(char* file, uint8_t mode)
{
int numOfReadBytes;
AUDIO_RECORDER_ErrorTypdef ret = AUDIO_RECORDER_ERROR_IO;
if( f_open(&wav_file, file, mode) == FR_OK)
{
if (mode & FA_READ)
{
if(f_read(&wav_file, &AudioInfo, sizeof(WAV_InfoTypedef), (void *)&numOfReadBytes) == FR_OK)
{
ret = AUDIO_RECORDER_ERROR_NONE;
}if (f_read(&wav_file, &AudioInfo, sizeof(WAV_InfoTypedef), (void *)&numOfReadBytes) == FR_OK) { ... }
}if (mode & FA_READ) { ... }
}if (f_open(&wav_file, file, mode) == FR_OK) { ... }
return ret;
}{ ... }
/* ... */
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);
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);
}if (haudio.in.state == AUDIO_RECORDER_SUSPENDED) { ... }
haudio.in.state = AUDIO_RECORDER_PLAYING;
BSP_AUDIO_OUT_Play((uint16_t*)&haudio.buff[0], AUDIO_OUT_BUFFER_SIZE);
return AUDIO_RECORDER_ERROR_NONE;
}if (numOfReadBytes != 0) { ... }
}if (f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE, (void *)&numOfReadBytes) == FR_OK) { ... }
return AUDIO_RECORDER_ERROR_IO;
}{ ... }
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_DeInit(void)
{
if(haudio.in.state == AUDIO_RECORDER_RECORDING)
{
BSP_AUDIO_IN_Stop();
BSP_AUDIO_IN_DeInit();
f_close(&wav_file);
}if (haudio.in.state == AUDIO_RECORDER_RECORDING) { ... }
if(haudio.in.state == AUDIO_RECORDER_PLAYING)
{
BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW);
BSP_AUDIO_OUT_DeInit();
f_close(&wav_file);
}if (haudio.in.state == AUDIO_RECORDER_PLAYING) { ... }
haudio.in.state = AUDIO_RECORDER_IDLE;
if(AudioEvent != 0)
{
vQueueDelete(AudioEvent);
AudioEvent = 0;
}if (AudioEvent != 0) { ... }
if(AudioThreadId != 0)
{
osThreadTerminate(AudioThreadId);
AudioThreadId = 0;
}if (AudioThreadId != 0) { ... }
return AUDIO_RECORDER_ERROR_NONE;
}{ ... }
/* ... */
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)
{
WavProcess_HeaderUpdate(pHeaderBuff, &AudioInfo);
if(f_write(&wav_file, pHeaderBuff, sizeof(WAV_InfoTypedef), (void*)&byteswritten) == FR_OK)
{
audio_error = AUDIO_RECORDER_ERROR_NONE;
}if (f_write(&wav_file, pHeaderBuff, sizeof(WAV_InfoTypedef), (void*)&byteswritten) == FR_OK) { ... }
}if (f_lseek(&wav_file, 0) == FR_OK) { ... }
haudio.in.state = AUDIO_RECORDER_SUSPENDED;
f_close(&wav_file);
_cbNotifyStateChange();
if(AudioThreadId != 0)
{
osThreadSuspend(AudioThreadId);
}if (AudioThreadId != 0) { ... }
return audio_error;
}{ ... }
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StopPlayer(void)
{
BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW);
BSP_AUDIO_OUT_DeInit();
haudio.in.state = AUDIO_RECORDER_SUSPENDED;
f_close(&wav_file);
_cbNotifyStateChange();
if(AudioThreadId != 0)
{
osThreadSuspend(AudioThreadId);
}if (AudioThreadId != 0) { ... }
return AUDIO_RECORDER_ERROR_NONE;
}{ ... }
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_PauseResume(void)
{
if(haudio.in.state == AUDIO_RECORDER_PLAYING)
{
osThreadSuspend(AudioThreadId);
BSP_AUDIO_OUT_Pause();
haudio.in.state = AUDIO_RECORDER_PLAY_PAUSE;
}if (haudio.in.state == AUDIO_RECORDER_PLAYING) { ... }
else if(haudio.in.state == AUDIO_RECORDER_RECORDING)
{
osThreadSuspend(AudioThreadId);
BSP_AUDIO_IN_Pause();
haudio.in.state = AUDIO_RECORDER_RECORD_PAUSE;
}else if (haudio.in.state == AUDIO_RECORDER_RECORDING) { ... }
else if(haudio.in.state == AUDIO_RECORDER_PLAY_PAUSE)
{
osThreadResume(AudioThreadId);
BSP_AUDIO_OUT_Resume();
haudio.in.state = AUDIO_RECORDER_PLAYING;
}else if (haudio.in.state == AUDIO_RECORDER_PLAY_PAUSE) { ... }
else if(haudio.in.state == AUDIO_RECORDER_RECORD_PAUSE)
{
osThreadResume(AudioThreadId);
BSP_AUDIO_IN_Resume();
haudio.in.state = AUDIO_RECORDER_RECORDING;
}else if (haudio.in.state == AUDIO_RECORDER_RECORD_PAUSE) { ... }
return AUDIO_RECORDER_ERROR_NONE;
}{ ... }
/* ... */
AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_Resume(void)
{
if(haudio.in.state == AUDIO_RECORDER_PLAY_PAUSE)
{
osThreadResume(AudioThreadId);
BSP_AUDIO_OUT_Resume();
haudio.in.state = AUDIO_RECORDER_PLAYING;
}if (haudio.in.state == AUDIO_RECORDER_PLAY_PAUSE) { ... }
else if(haudio.in.state == AUDIO_RECORDER_RECORD_PAUSE)
{
osThreadResume(AudioThreadId);
BSP_AUDIO_IN_Resume();
haudio.in.state = AUDIO_RECORDER_RECORDING;
}else if (haudio.in.state == AUDIO_RECORDER_RECORD_PAUSE) { ... }
return AUDIO_RECORDER_ERROR_NONE;
}{ ... }
/* ... */
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&haudio.pdm[AUDIO_IN_PDM_BUFFER_SIZE/2],
(uint16_t*)&haudio.buff[haudio.ppcm]);
haudio.ppcm += AUDIO_IN_PDM_BUFFER_SIZE/4;
if (haudio.ppcm == AUDIO_IN_BUFFER_SIZE/2)
{
osMessagePut ( AudioEvent, REC_BUFFER_OFFSET_HALF, 0);
}if (haudio.ppcm == AUDIO_IN_BUFFER_SIZE/2) { ... }
else if (haudio.ppcm >= AUDIO_IN_BUFFER_SIZE)
{
osMessagePut ( AudioEvent, REC_BUFFER_OFFSET_FULL, 0);
haudio.ppcm = 0;
}else if (haudio.ppcm >= AUDIO_IN_BUFFER_SIZE) { ... }
}{ ... }
/* ... */
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&haudio.pdm[0],
(uint16_t*)&haudio.buff[haudio.ppcm]);
haudio.ppcm += AUDIO_IN_PDM_BUFFER_SIZE/4;
if (haudio.ppcm == AUDIO_IN_BUFFER_SIZE/2)
{
osMessagePut ( AudioEvent, REC_BUFFER_OFFSET_HALF, 0);
}if (haudio.ppcm == AUDIO_IN_BUFFER_SIZE/2) { ... }
else if (haudio.ppcm >= AUDIO_IN_BUFFER_SIZE)
{
osMessagePut ( AudioEvent, REC_BUFFER_OFFSET_FULL, 0);
haudio.ppcm = 0;
}else if (haudio.ppcm >= AUDIO_IN_BUFFER_SIZE) { ... }
}{ ... }
/* ... */
void BSP_AUDIO_IN_Error_CallBack(void)
{
haudio.in.state = AUDIO_RECORDER_ERROR;
}{ ... }
/* ... */
static void AUDIO_TransferComplete_CallBack(void)
{
if(haudio.in.state == AUDIO_RECORDER_PLAYING)
{
BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&haudio.buff[0], AUDIO_OUT_BUFFER_SIZE /2);
osMessagePut ( AudioEvent, PLAY_BUFFER_OFFSET_FULL, 0);
}if (haudio.in.state == AUDIO_RECORDER_PLAYING) { ... }
}{ ... }
/* ... */
static void AUDIO_HalfTransfer_CallBack(void)
{
if(haudio.in.state == AUDIO_RECORDER_PLAYING)
{
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.in.state == AUDIO_RECORDER_PLAYING) { ... }
}{ ... }
/* ... */
static void AUDIO_Error_CallBack(void)
{
haudio.in.state = AUDIO_RECORDER_ERROR;
}{ ... }
/* ... */
static void Audio_Thread(void const * argument)
{
uint32_t numOfReadBytes, numOfWrittenBytes;
osEvent event;
for(;;)
{
event = osMessageGet(AudioEvent, 100 );
if( event.status == osEventMessage )
{
if(haudio.in.state == AUDIO_RECORDER_PLAYING)
{
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)
{
AUDIO_RECORDER_StopPlayer();
}if (numOfReadBytes == 0) { ... }
}if (f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { ... }
else
{
AUDIO_RECORDER_StopPlayer();
}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)
{
AUDIO_RECORDER_StopPlayer();
}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
{
AUDIO_RECORDER_StopPlayer();
}else { ... }
break;
case PLAY_BUFFER_OFFSET_FULL:
default:
break;default
}switch (event.value.v) { ... }
}if (haudio.in.state == AUDIO_RECORDER_PLAYING) { ... }
if(haudio.in.state == AUDIO_RECORDER_RECORDING)
{
switch(event.value.v)
{
case REC_BUFFER_OFFSET_HALF:
if(f_write(&wav_file, (uint8_t*)(haudio.buff),
AUDIO_IN_BUFFER_SIZE/2,
(void*)&numOfWrittenBytes) == FR_OK)
{
if(numOfWrittenBytes == 0)
{
AUDIO_RECORDER_StopRec();
}if (numOfWrittenBytes == 0) { ... }
}if (f_write(&wav_file, (uint8_t*)(haudio.buff), AUDIO_IN_BUFFER_SIZE/2, (void*)&numOfWrittenBytes) == FR_OK) { ... }
else
{
AUDIO_RECORDER_StopRec();
}else { ... }
haudio.in.fptr += numOfWrittenBytes;
break;
case REC_BUFFER_OFFSET_HALF:
case REC_BUFFER_OFFSET_FULL:
if(f_write(&wav_file, (uint8_t*)(haudio.buff + AUDIO_IN_BUFFER_SIZE/2),
AUDIO_IN_BUFFER_SIZE/2,
(void*)&numOfWrittenBytes) == FR_OK)
{
if(numOfWrittenBytes == 0)
{
AUDIO_RECORDER_StopRec();
}if (numOfWrittenBytes == 0) { ... }
}if (f_write(&wav_file, (uint8_t*)(haudio.buff + AUDIO_IN_BUFFER_SIZE/2), AUDIO_IN_BUFFER_SIZE/2, (void*)&numOfWrittenBytes) == FR_OK) { ... }
else
{
AUDIO_RECORDER_StopRec();
}else { ... }
haudio.in.fptr += numOfWrittenBytes;
break;
case REC_BUFFER_OFFSET_FULL:
default:
break;default
}switch (event.value.v) { ... }
}if (haudio.in.state == AUDIO_RECORDER_RECORDING) { ... }
}if (event.status == osEventMessage) { ... }
}for (;;) { ... }
}{ ... }
/* ... */
uint32_t AUDIO_RECORDER_GetElapsedTime(void)
{
uint32_t duration;
duration = haudio.in.fptr / AudioInfo.ByteRate;
return duration;
}{ ... }
/* ... */
uint32_t AUDIO_RECORDER_GetPlayedTime(void)
{
uint32_t duration;
duration = (wav_file.fptr) / AudioInfo.ByteRate;
return duration;
}{ ... }
/* ... */
uint32_t AUDIO_RECORDER_GetTotalTime(void)
{
uint32_t duration;
duration = (f_size(&wav_file)) / AudioInfo.ByteRate;
return duration;
}{ ... }
/* ... */
/* ... */
static uint32_t WavProcess_EncInit(uint32_t Freq, uint8_t *pHeader)
{
AudioInfo.SampleRate = Freq;
AudioInfo.NbrChannels = 2;
AudioInfo.BitPerSample = 16;
AudioInfo.FileSize = 0x001D4C00;
AudioInfo.SubChunk1Size = 44;
AudioInfo.ByteRate = (AudioInfo.SampleRate * \
(AudioInfo.BitPerSample/8) * \
AudioInfo.NbrChannels);
AudioInfo.BlockAlign = AudioInfo.NbrChannels * \
(AudioInfo.BitPerSample/8);
if(WavProcess_HeaderInit(pHeader, &AudioInfo))
{
return 1;
}if (WavProcess_HeaderInit(pHeader, &AudioInfo)) { ... }
return 0;
}{ ... }
/* ... */
static uint32_t WavProcess_HeaderInit(uint8_t* pHeader, WAV_InfoTypedef* pAudioInfoStruct)
{
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] = pAudioInfoStruct->NbrChannels;
pHeader[23] = 0x00;
Write the number of channels, ie. 0x01 (Mono)
pHeader[24] = (uint8_t)((pAudioInfoStruct->SampleRate & 0xFF));
pHeader[25] = (uint8_t)((pAudioInfoStruct->SampleRate >> 8) & 0xFF);
pHeader[26] = (uint8_t)((pAudioInfoStruct->SampleRate >> 16) & 0xFF);
pHeader[27] = (uint8_t)((pAudioInfoStruct->SampleRate >> 24) & 0xFF);
Write the Sample Rate in Hz
pHeader[28] = (uint8_t)((pAudioInfoStruct->ByteRate & 0xFF));
pHeader[29] = (uint8_t)((pAudioInfoStruct->ByteRate >> 8) & 0xFF);
pHeader[30] = (uint8_t)((pAudioInfoStruct->ByteRate >> 16) & 0xFF);
pHeader[31] = (uint8_t)((pAudioInfoStruct->ByteRate >> 24) & 0xFF);
Write the Byte Rate
pHeader[32] = pAudioInfoStruct->BlockAlign;
pHeader[33] = 0x00;
Write the block alignment
pHeader[34] = pAudioInfoStruct->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, WAV_InfoTypedef* pAudioInfoStruct)
{
/* ... */
pHeader[4] = (uint8_t)(haudio.in.fptr);
pHeader[5] = (uint8_t)(haudio.in.fptr >> 8);
pHeader[6] = (uint8_t)(haudio.in.fptr >> 16);
pHeader[7] = (uint8_t)(haudio.in.fptr >> 24);Write the file length
haudio.in.fptr -=44;
pHeader[40] = (uint8_t)(haudio.in.fptr);
pHeader[41] = (uint8_t)(haudio.in.fptr >> 8);
pHeader[42] = (uint8_t)(haudio.in.fptr >> 16);
pHeader[43] = (uint8_t)(haudio.in.fptr >> 24);
return 0;
}{ ... }
/* ... */
/* ... */