NuMaker audio playback

Committer:
csyang2
Date:
Wed Mar 29 05:49:41 2017 +0000
Revision:
5:492ea7d38e59
Parent:
4:0b5c342628ff
Child:
6:66ba9ac474ac
2017.03.29; main.cpp; 1. Use format() to set sampling rate, channel count and sample bit length. (default is 8000Hz mono 16-bit); 2. Add record feature.; ; README.md; 1. Rename Audio Codec as NAU8822L.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ccli8 1:c3f10403b3db 1 #include "mbed.h"
ccli8 1:c3f10403b3db 2
ccli8 1:c3f10403b3db 3 #include "NAU8822L.h"
ccli8 1:c3f10403b3db 4
ccli8 1:c3f10403b3db 5 #if defined(TARGET_NUMAKER_PFM_NUC472)
ccli8 1:c3f10403b3db 6 #include "NuSDFileSystem.h"
ccli8 1:c3f10403b3db 7
ccli8 1:c3f10403b3db 8 NAU8822L audio(PC_9, PA_15, 0x1A, PG_7, PG_8, PG_9, PI_11, PI_12); // NAU8822L object
ccli8 1:c3f10403b3db 9 DigitalOut hp_enable(PH_2);
ccli8 1:c3f10403b3db 10 NuSDFileSystem Nu_SD(PF_6, PF_7, PF_8, PF_5 ,PF_4, PF_3, PF_2, "sd");
csyang2 5:492ea7d38e59 11
ccli8 1:c3f10403b3db 12 #elif defined(TARGET_NUMAKER_PFM_M453)
ccli8 1:c3f10403b3db 13 NAU8822L audio(PD_4, PD_5, 0x1A, PA_5, PA_6, PA_7, PD_0, PA_4); // NAU8822L object
ccli8 1:c3f10403b3db 14 DigitalOut hp_enable(PE_1);
csyang2 5:492ea7d38e59 15
ccli8 1:c3f10403b3db 16 #endif
Chuck Young 4:0b5c342628ff 17
ccli8 1:c3f10403b3db 18 InterruptIn button(SW2); // button SW2
ccli8 1:c3f10403b3db 19 DigitalOut led(LED1); // flashing LED1(rgbled1)
ccli8 1:c3f10403b3db 20
csyang2 5:492ea7d38e59 21 int audioBuf[4096];
csyang2 5:492ea7d38e59 22
ccli8 1:c3f10403b3db 23 int readPtr = 0;
csyang2 5:492ea7d38e59 24 int writePtr = 0;
csyang2 5:492ea7d38e59 25
csyang2 5:492ea7d38e59 26 int samplingRate = 8000;
csyang2 5:492ea7d38e59 27 char channelCount = 1;
csyang2 5:492ea7d38e59 28 char sampleBitLength = 16;
ccli8 1:c3f10403b3db 29
ccli8 1:c3f10403b3db 30 #if defined(TARGET_NUMAKER_PFM_NUC472)
ccli8 1:c3f10403b3db 31 FILE *fp;
ccli8 1:c3f10403b3db 32
csyang2 5:492ea7d38e59 33 int theta = 0;
ccli8 1:c3f10403b3db 34
ccli8 1:c3f10403b3db 35 #elif defined(TARGET_NUMAKER_PFM_M453)
csyang2 5:492ea7d38e59 36 // 1k sine wave@sampling rate 8kHz mono 16-bit
csyang2 5:492ea7d38e59 37 const char sine1k[16] = {
csyang2 5:492ea7d38e59 38 0x00, 0x00, 0x50, 0x0B, 0xFF, 0x0F, 0x50, 0x0B, 0x00, 0x00, 0xB0, 0xF4, 0x01, 0xF0, 0xB0, 0xF4
ccli8 1:c3f10403b3db 39 };
csyang2 5:492ea7d38e59 40
csyang2 5:492ea7d38e59 41 int flag = 0;
csyang2 5:492ea7d38e59 42
ccli8 1:c3f10403b3db 43 #endif
ccli8 1:c3f10403b3db 44
ccli8 1:c3f10403b3db 45 void flip(void) {
ccli8 1:c3f10403b3db 46 led = !led;
ccli8 1:c3f10403b3db 47 }
ccli8 1:c3f10403b3db 48
csyang2 5:492ea7d38e59 49 void play(void) {
ccli8 1:c3f10403b3db 50 #if defined(TARGET_NUMAKER_PFM_NUC472)
ccli8 1:c3f10403b3db 51 audio.write(audioBuf, readPtr, 4);
ccli8 1:c3f10403b3db 52 readPtr += 4;
ccli8 1:c3f10403b3db 53 readPtr &= 0xFFF;
ccli8 1:c3f10403b3db 54 theta -= 4;
ccli8 1:c3f10403b3db 55 #elif defined(TARGET_NUMAKER_PFM_M453)
csyang2 5:492ea7d38e59 56 if (flag == 0) {
csyang2 5:492ea7d38e59 57 audio.write((int *)sine1k, readPtr, 2);
csyang2 5:492ea7d38e59 58 readPtr += 2;
csyang2 5:492ea7d38e59 59 readPtr &= 0x3;
csyang2 5:492ea7d38e59 60 } else {
csyang2 5:492ea7d38e59 61 audio.write(audioBuf, readPtr, 2);
csyang2 5:492ea7d38e59 62 readPtr += 2;
csyang2 5:492ea7d38e59 63 readPtr &= 0xFFF;
csyang2 5:492ea7d38e59 64 }
ccli8 1:c3f10403b3db 65 #endif
ccli8 1:c3f10403b3db 66 }
ccli8 1:c3f10403b3db 67
csyang2 5:492ea7d38e59 68 void record(void) {
csyang2 5:492ea7d38e59 69 audio.read();
csyang2 5:492ea7d38e59 70
csyang2 5:492ea7d38e59 71 #if defined(TARGET_NUMAKER_PFM_NUC472)
csyang2 5:492ea7d38e59 72 audioBuf[writePtr] = audio.rxBuffer[0];
csyang2 5:492ea7d38e59 73 audioBuf[++writePtr] = audio.rxBuffer[1];
csyang2 5:492ea7d38e59 74 audioBuf[++writePtr] = audio.rxBuffer[2];
csyang2 5:492ea7d38e59 75 audioBuf[++writePtr] = audio.rxBuffer[3];
csyang2 5:492ea7d38e59 76 ++writePtr;
csyang2 5:492ea7d38e59 77 theta += 4;
csyang2 5:492ea7d38e59 78 if (writePtr > 4094) {
csyang2 5:492ea7d38e59 79 writePtr = 0;
csyang2 5:492ea7d38e59 80 }
csyang2 5:492ea7d38e59 81 #elif defined(TARGET_NUMAKER_PFM_M453)
csyang2 5:492ea7d38e59 82 audioBuf[writePtr] = audio.rxBuffer[0];
csyang2 5:492ea7d38e59 83 audioBuf[++writePtr] = audio.rxBuffer[1];
csyang2 5:492ea7d38e59 84 ++writePtr;
csyang2 5:492ea7d38e59 85 if (writePtr > 4094) {
csyang2 5:492ea7d38e59 86 writePtr = 0;
csyang2 5:492ea7d38e59 87 flag = 1;
csyang2 5:492ea7d38e59 88 }
csyang2 5:492ea7d38e59 89 #endif
csyang2 5:492ea7d38e59 90 }
csyang2 5:492ea7d38e59 91
ccli8 1:c3f10403b3db 92 void fillAudioBuf(void) {
ccli8 1:c3f10403b3db 93 #if defined(TARGET_NUMAKER_PFM_NUC472)
ccli8 1:c3f10403b3db 94 while (!feof(fp)) {
ccli8 1:c3f10403b3db 95 if (theta < 4096) {
ccli8 1:c3f10403b3db 96 // read 2 integers
ccli8 1:c3f10403b3db 97 fread(&audioBuf[writePtr], 4, 2, fp);
ccli8 1:c3f10403b3db 98 NVIC_DisableIRQ(I2S1_IRQn); // FIXME
ccli8 1:c3f10403b3db 99 theta += 2;
ccli8 1:c3f10403b3db 100 NVIC_EnableIRQ(I2S1_IRQn); // FIXME
ccli8 1:c3f10403b3db 101 writePtr += 2;
ccli8 1:c3f10403b3db 102 writePtr &= 0xFFF;
ccli8 1:c3f10403b3db 103 }
ccli8 1:c3f10403b3db 104 }
ccli8 1:c3f10403b3db 105 #elif defined(TARGET_NUMAKER_PFM_M453)
csyang2 5:492ea7d38e59 106 while (1) {
csyang2 5:492ea7d38e59 107 Thread::wait(500);
csyang2 5:492ea7d38e59 108 }
csyang2 5:492ea7d38e59 109 #endif
csyang2 5:492ea7d38e59 110 }
csyang2 5:492ea7d38e59 111
csyang2 5:492ea7d38e59 112 void drainAudioBuf(void) {
csyang2 5:492ea7d38e59 113 #if defined(TARGET_NUMAKER_PFM_NUC472)
csyang2 5:492ea7d38e59 114 int i = 0;
csyang2 5:492ea7d38e59 115 while (1) {
csyang2 5:492ea7d38e59 116 if (theta > 512 ) {
csyang2 5:492ea7d38e59 117 fwrite(&audioBuf[readPtr], 4, 128, fp);
csyang2 5:492ea7d38e59 118 NVIC_DisableIRQ(I2S1_IRQn); // FIXME
csyang2 5:492ea7d38e59 119 theta -= 128;
csyang2 5:492ea7d38e59 120 NVIC_EnableIRQ(I2S1_IRQn); // FIXME
csyang2 5:492ea7d38e59 121 readPtr += 128;
csyang2 5:492ea7d38e59 122 if (readPtr > 4094)
csyang2 5:492ea7d38e59 123 readPtr = 0;
csyang2 5:492ea7d38e59 124
csyang2 5:492ea7d38e59 125 i += 512;
csyang2 5:492ea7d38e59 126 }
csyang2 5:492ea7d38e59 127
csyang2 5:492ea7d38e59 128 /* record about 10 seconds PCM */
csyang2 5:492ea7d38e59 129 if (i >= samplingRate*channelCount*sampleBitLength/8*10)
csyang2 5:492ea7d38e59 130 break;
csyang2 5:492ea7d38e59 131 }
csyang2 5:492ea7d38e59 132 #elif defined(TARGET_NUMAKER_PFM_M453)
csyang2 5:492ea7d38e59 133 while (flag == 0) {
csyang2 5:492ea7d38e59 134 Thread::wait(500);
csyang2 5:492ea7d38e59 135 }
csyang2 5:492ea7d38e59 136 #endif
csyang2 5:492ea7d38e59 137 }
csyang2 5:492ea7d38e59 138
csyang2 5:492ea7d38e59 139 void demo_record(void) {
csyang2 5:492ea7d38e59 140 for (int i = 0; i < 4096; i++) {
csyang2 5:492ea7d38e59 141 audioBuf[i] = 0;
csyang2 5:492ea7d38e59 142 }
csyang2 5:492ea7d38e59 143
csyang2 5:492ea7d38e59 144 #if defined(TARGET_NUMAKER_PFM_NUC472)
csyang2 5:492ea7d38e59 145 fp = fopen("/sd/test.pcm", "w");
csyang2 5:492ea7d38e59 146 if (fp == NULL) {
csyang2 5:492ea7d38e59 147 perror("\r\nError opening file!\r\n");
csyang2 5:492ea7d38e59 148 exit(1);
csyang2 5:492ea7d38e59 149 }
ccli8 1:c3f10403b3db 150 #endif
csyang2 5:492ea7d38e59 151
csyang2 5:492ea7d38e59 152 audio.attach(&record);
csyang2 5:492ea7d38e59 153 audio.format(samplingRate, channelCount, sampleBitLength);
csyang2 5:492ea7d38e59 154
csyang2 5:492ea7d38e59 155 printf("Start recording...\r\n");
csyang2 5:492ea7d38e59 156 audio.record();
csyang2 5:492ea7d38e59 157
csyang2 5:492ea7d38e59 158 drainAudioBuf();
csyang2 5:492ea7d38e59 159
csyang2 5:492ea7d38e59 160 #if defined(TARGET_NUMAKER_PFM_NUC472)
csyang2 5:492ea7d38e59 161 fclose(fp);
csyang2 5:492ea7d38e59 162 #endif
csyang2 5:492ea7d38e59 163
csyang2 5:492ea7d38e59 164 printf("Stop recording.\r\n");
csyang2 5:492ea7d38e59 165 audio.stop();
csyang2 5:492ea7d38e59 166 }
csyang2 5:492ea7d38e59 167
csyang2 5:492ea7d38e59 168 void demo_play(void) {
csyang2 5:492ea7d38e59 169 #if defined(TARGET_NUMAKER_PFM_NUC472)
csyang2 5:492ea7d38e59 170 fp = fopen("/sd/test.pcm", "r");
csyang2 5:492ea7d38e59 171 if (fp == NULL) {
csyang2 5:492ea7d38e59 172 perror("\r\nError opening file!\r\n");
csyang2 5:492ea7d38e59 173 exit(1);
csyang2 5:492ea7d38e59 174 }
csyang2 5:492ea7d38e59 175
csyang2 5:492ea7d38e59 176 // fseek(fp, 44, SEEK_SET);
csyang2 5:492ea7d38e59 177
csyang2 5:492ea7d38e59 178 for (int i = 0; i < 4096; i++) {
csyang2 5:492ea7d38e59 179 audioBuf[i] = 0;
csyang2 5:492ea7d38e59 180 }
csyang2 5:492ea7d38e59 181 #endif
csyang2 5:492ea7d38e59 182
csyang2 5:492ea7d38e59 183 // disable headphone
csyang2 5:492ea7d38e59 184 hp_enable = 1;
csyang2 5:492ea7d38e59 185
csyang2 5:492ea7d38e59 186 audio.attach(&play);
csyang2 5:492ea7d38e59 187 audio.format(samplingRate, channelCount, sampleBitLength);
csyang2 5:492ea7d38e59 188
csyang2 5:492ea7d38e59 189 // enable headphone
csyang2 5:492ea7d38e59 190 hp_enable = 0;
csyang2 5:492ea7d38e59 191
csyang2 5:492ea7d38e59 192 printf("Start playing...\r\n");
csyang2 5:492ea7d38e59 193 audio.start();
csyang2 5:492ea7d38e59 194
csyang2 5:492ea7d38e59 195 fillAudioBuf();
csyang2 5:492ea7d38e59 196
csyang2 5:492ea7d38e59 197 printf("Stop playing.\r\n");
csyang2 5:492ea7d38e59 198 audio.stop();
csyang2 5:492ea7d38e59 199
csyang2 5:492ea7d38e59 200 // disable headphone
csyang2 5:492ea7d38e59 201 hp_enable = 1;
ccli8 1:c3f10403b3db 202 }
ccli8 1:c3f10403b3db 203
ccli8 1:c3f10403b3db 204 int main(void) {
ccli8 1:c3f10403b3db 205 led = 1;
ccli8 1:c3f10403b3db 206
ccli8 1:c3f10403b3db 207 button.rise(&flip);
ccli8 1:c3f10403b3db 208
csyang2 5:492ea7d38e59 209 demo_record();
ccli8 1:c3f10403b3db 210
csyang2 5:492ea7d38e59 211 demo_play();
ccli8 1:c3f10403b3db 212
ccli8 1:c3f10403b3db 213 led = 0;
ccli8 1:c3f10403b3db 214 }