Nuvoton
/
NuMaker-mbed-AudioPlayback-example
NuMaker audio playback
main.cpp@5:492ea7d38e59, 2017-03-29 (annotated)
- 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?
User | Revision | Line number | New 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 | } |