96kHz-16bit USB Audio Output interface with UDA1345 and 24.576MHz Xtal.
Dependencies: I2S USBDevice mbed
Fork of USBAudioPlayback by
main.cpp@5:ca2316551f3d, 2014-02-05 (annotated)
- Committer:
- edy555
- Date:
- Wed Feb 05 14:31:03 2014 +0000
- Revision:
- 5:ca2316551f3d
- Parent:
- 4:a3aee5fc768a
- Child:
- 6:dc7b32ce4277
increase # of chunks, keep in-out interval on ring buffer
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
samux | 0:eb53799c0b97 | 1 | // Playback example with the USBAUDIO library |
samux | 0:eb53799c0b97 | 2 | |
samux | 0:eb53799c0b97 | 3 | #include "mbed.h" |
samux | 0:eb53799c0b97 | 4 | #include "USBAudio.h" |
edy555 | 3:44343b9dd8b6 | 5 | #include "I2S.h" |
samux | 0:eb53799c0b97 | 6 | |
samux | 0:eb53799c0b97 | 7 | // frequency: 48 kHz |
edy555 | 3:44343b9dd8b6 | 8 | #define FREQ_SPK 96000 |
edy555 | 3:44343b9dd8b6 | 9 | #define FREQ_MIC 8000 |
samux | 0:eb53799c0b97 | 10 | |
samux | 0:eb53799c0b97 | 11 | // 2channels: stereo |
samux | 0:eb53799c0b97 | 12 | #define NB_CHA_SPK 2 |
edy555 | 4:a3aee5fc768a | 13 | #define NB_CHA_MIC 0 |
samux | 0:eb53799c0b97 | 14 | |
samux | 0:eb53799c0b97 | 15 | // length computed: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there are two channels, the length will be 48 * 2 * 2 |
samux | 0:eb53799c0b97 | 16 | #define LENGTH_AUDIO_PACKET_SPK (FREQ_SPK / 500) * NB_CHA_SPK |
samux | 0:eb53799c0b97 | 17 | #define LENGTH_AUDIO_PACKET_MIC (FREQ_MIC / 500) * NB_CHA_MIC |
samux | 0:eb53799c0b97 | 18 | |
samux | 0:eb53799c0b97 | 19 | // USBAudio object |
samux | 0:eb53799c0b97 | 20 | USBAudio audio(FREQ_SPK, NB_CHA_SPK, FREQ_MIC, NB_CHA_MIC, 0xab45, 0x0378); |
samux | 0:eb53799c0b97 | 21 | |
edy555 | 3:44343b9dd8b6 | 22 | DigitalOut myled(LED1); |
edy555 | 3:44343b9dd8b6 | 23 | |
edy555 | 3:44343b9dd8b6 | 24 | I2S i2s(I2S_TRANSMIT, p5, p6, p7); |
edy555 | 3:44343b9dd8b6 | 25 | I2S i2srx(I2S_RECEIVE, p8, p29, p15); |
edy555 | 3:44343b9dd8b6 | 26 | |
edy555 | 5:ca2316551f3d | 27 | #define CHUNKS 8 |
edy555 | 3:44343b9dd8b6 | 28 | |
edy555 | 3:44343b9dd8b6 | 29 | int buf_out[LENGTH_AUDIO_PACKET_MIC/sizeof(int)]; |
edy555 | 3:44343b9dd8b6 | 30 | int16_t buf_in[CHUNKS][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)]; |
edy555 | 3:44343b9dd8b6 | 31 | int16_t * stream_in = NULL; |
edy555 | 3:44343b9dd8b6 | 32 | int16_t * stream_in_tail = NULL; |
edy555 | 3:44343b9dd8b6 | 33 | int read_pos = 0; |
edy555 | 3:44343b9dd8b6 | 34 | int write_pos = 0; |
edy555 | 3:44343b9dd8b6 | 35 | |
edy555 | 3:44343b9dd8b6 | 36 | void genwave() |
edy555 | 3:44343b9dd8b6 | 37 | { |
edy555 | 3:44343b9dd8b6 | 38 | int buf[8]; |
edy555 | 3:44343b9dd8b6 | 39 | if (stream_in == NULL) { |
edy555 | 3:44343b9dd8b6 | 40 | buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = buf[7] = 0; |
edy555 | 3:44343b9dd8b6 | 41 | i2s.write(buf, 6); |
edy555 | 3:44343b9dd8b6 | 42 | return; |
edy555 | 3:44343b9dd8b6 | 43 | } |
edy555 | 3:44343b9dd8b6 | 44 | |
edy555 | 3:44343b9dd8b6 | 45 | myled = 1; |
edy555 | 3:44343b9dd8b6 | 46 | buf[0] = stream_in[0]; |
edy555 | 3:44343b9dd8b6 | 47 | buf[1] = stream_in[1]; |
edy555 | 3:44343b9dd8b6 | 48 | buf[2] = stream_in[2]; |
edy555 | 3:44343b9dd8b6 | 49 | buf[3] = stream_in[3]; |
edy555 | 3:44343b9dd8b6 | 50 | buf[4] = stream_in[4]; |
edy555 | 3:44343b9dd8b6 | 51 | buf[5] = stream_in[5]; |
edy555 | 3:44343b9dd8b6 | 52 | buf[6] = stream_in[6]; |
edy555 | 3:44343b9dd8b6 | 53 | buf[7] = stream_in[7]; |
edy555 | 3:44343b9dd8b6 | 54 | i2s.write(buf, 8); |
edy555 | 3:44343b9dd8b6 | 55 | stream_in += 8; |
edy555 | 3:44343b9dd8b6 | 56 | if (stream_in >= stream_in_tail) { |
edy555 | 5:ca2316551f3d | 57 | int d = read_pos - write_pos; |
edy555 | 5:ca2316551f3d | 58 | if (d < 0) |
edy555 | 5:ca2316551f3d | 59 | d += CHUNKS; |
edy555 | 5:ca2316551f3d | 60 | if (d > CHUNKS/4) { |
edy555 | 5:ca2316551f3d | 61 | write_pos++; |
edy555 | 5:ca2316551f3d | 62 | write_pos %= CHUNKS; |
edy555 | 5:ca2316551f3d | 63 | } |
edy555 | 3:44343b9dd8b6 | 64 | stream_in = buf_in[write_pos]; |
edy555 | 3:44343b9dd8b6 | 65 | stream_in_tail = &buf_in[write_pos][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)]; |
edy555 | 3:44343b9dd8b6 | 66 | } |
edy555 | 3:44343b9dd8b6 | 67 | myled = 0; |
edy555 | 3:44343b9dd8b6 | 68 | } |
edy555 | 3:44343b9dd8b6 | 69 | |
samux | 0:eb53799c0b97 | 70 | int main() { |
edy555 | 3:44343b9dd8b6 | 71 | i2srx.masterslave(I2S_SLAVE); |
edy555 | 3:44343b9dd8b6 | 72 | i2srx.frequency(96000); |
edy555 | 3:44343b9dd8b6 | 73 | i2srx.start(); |
edy555 | 3:44343b9dd8b6 | 74 | i2s.attach(genwave); |
edy555 | 3:44343b9dd8b6 | 75 | i2s.masterslave(I2S_MASTER); |
edy555 | 3:44343b9dd8b6 | 76 | i2s.wordsize(16); |
edy555 | 3:44343b9dd8b6 | 77 | i2s.frequency(96000); |
edy555 | 3:44343b9dd8b6 | 78 | i2s.set_interrupt_fifo_level(0); |
edy555 | 3:44343b9dd8b6 | 79 | i2s.start(); |
samux | 0:eb53799c0b97 | 80 | |
samux | 0:eb53799c0b97 | 81 | while (1) { |
edy555 | 4:a3aee5fc768a | 82 | audio.read((uint8_t *)buf_in[read_pos++]); |
edy555 | 3:44343b9dd8b6 | 83 | read_pos %= CHUNKS; |
edy555 | 3:44343b9dd8b6 | 84 | if (stream_in == NULL && read_pos > CHUNKS / 2) { |
edy555 | 3:44343b9dd8b6 | 85 | stream_in = buf_in[write_pos]; |
edy555 | 3:44343b9dd8b6 | 86 | stream_in_tail = &buf_in[write_pos][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)]; |
edy555 | 3:44343b9dd8b6 | 87 | } |
samux | 0:eb53799c0b97 | 88 | } |
samux | 0:eb53799c0b97 | 89 | } |