Skip to content

Commit a29de9e

Browse files
authored
Merge pull request #19 from bcmi-labs/audio-playback
`examples/Audio_Playback`
2 parents 5046d4c + 0d1e455 commit a29de9e

File tree

6 files changed

+173
-0
lines changed

6 files changed

+173
-0
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.wav filter=lfs diff=lfs merge=lfs -text

.github/workflows/compile-examples.yml

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ jobs:
4949
libraries: |
5050
# Install the library from the local path.
5151
- source-path: ./
52+
- source-url: https://github.com/facchinm/USBHostMbed5.git
53+
version: test_hs_in_fs
5254
sketch-paths: |
5355
- examples
5456
enable-deltas-report: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:9c17298498cf2a99c95f8dcf246691be4852eaddf8da24268b62854e0056c796
3+
size 1426086
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* GIGA R1 - Audio Playback
3+
* Simple wav format audio playback via 12-Bit DAC output by reading from a USB drive.
4+
* In order for this sketch to work you need to rename 'USB_DRIVE' to the name of your USB stick drive.
5+
* Furthermore you need to store the provided audio file AUDIO_SAMPLE.wav on it.
6+
*/
7+
8+
#include <Arduino_AdvancedAnalog.h>
9+
#include <DigitalOut.h>
10+
#include <USBHostMbed5.h>
11+
#include <FATFileSystem.h>
12+
13+
AdvancedDAC dac1(A12);
14+
15+
USBHostMSD msd;
16+
mbed::FATFileSystem usb("USB_DRIVE");
17+
18+
FILE * file = nullptr;
19+
int sample_size = 0;
20+
int samples_count = 0;
21+
22+
23+
void setup()
24+
{
25+
Serial.begin(115200);
26+
while (!Serial);
27+
28+
/* Enable power for HOST USB connector. */
29+
pinMode(PA_15, OUTPUT);
30+
digitalWrite(PA_15, HIGH);
31+
32+
Serial.println("Please connect a USB stick to the GIGA's USB port ...");
33+
while (!msd.connect()) delay(100);
34+
35+
Serial.println("Mounting USB device ...");
36+
int const rc_mount = usb.mount(&msd);
37+
if (rc_mount)
38+
{
39+
Serial.print("Error mounting USB device ");
40+
Serial.println(rc_mount);
41+
return;
42+
}
43+
44+
Serial.println("Opening audio file ...");
45+
46+
/* 16-bit PCM Mono 16kHz realigned noise reduction */
47+
file = fopen("/USB_DRIVE/AUDIO_SAMPLE.wav", "rb");
48+
if (file == nullptr)
49+
{
50+
Serial.print("Error opening audio file: ");
51+
Serial.println(strerror(errno));
52+
return;
53+
}
54+
55+
Serial.println("Reading audio header ...");
56+
struct wav_header_t
57+
{
58+
char chunkID[4]; //"RIFF" = 0x46464952
59+
unsigned long chunkSize; //28 [+ sizeof(wExtraFormatBytes) + wExtraFormatBytes] + sum(sizeof(chunk.id) + sizeof(chunk.size) + chunk.size)
60+
char format[4]; //"WAVE" = 0x45564157
61+
char subchunk1ID[4]; //"fmt " = 0x20746D66
62+
unsigned long subchunk1Size; //16 [+ sizeof(wExtraFormatBytes) + wExtraFormatBytes]
63+
unsigned short audioFormat;
64+
unsigned short numChannels;
65+
unsigned long sampleRate;
66+
unsigned long byteRate;
67+
unsigned short blockAlign;
68+
unsigned short bitsPerSample;
69+
};
70+
71+
wav_header_t header;
72+
fread(&header, sizeof(header), 1, file);
73+
74+
Serial.println("WAV File Header read:");
75+
char msg[64] = {0};
76+
snprintf(msg, sizeof(msg), "File Type: %s", header.chunkID);
77+
Serial.println(msg);
78+
snprintf(msg, sizeof(msg), "File Size: %ld", header.chunkSize);
79+
Serial.println(msg);
80+
snprintf(msg, sizeof(msg), "WAV Marker: %s", header.format);
81+
Serial.println(msg);
82+
snprintf(msg, sizeof(msg), "Format Name: %s", header.subchunk1ID);
83+
Serial.println(msg);
84+
snprintf(msg, sizeof(msg), "Format Length: %ld", header.subchunk1Size);
85+
Serial.println(msg);
86+
snprintf(msg, sizeof(msg), "Format Type: %hd", header.audioFormat);
87+
Serial.println(msg);
88+
snprintf(msg, sizeof(msg), "Number of Channels: %hd", header.numChannels);
89+
Serial.println(msg);
90+
snprintf(msg, sizeof(msg), "Sample Rate: %ld", header.sampleRate);
91+
Serial.println(msg);
92+
snprintf(msg, sizeof(msg), "Sample Rate * Bits/Sample * Channels / 8: %ld", header.byteRate);
93+
Serial.println(msg);
94+
snprintf(msg, sizeof(msg), "Bits per Sample * Channels / 8: %hd", header.blockAlign);
95+
Serial.println(msg);
96+
snprintf(msg, sizeof(msg), "Bits per Sample: %hd", header.bitsPerSample);
97+
Serial.println(msg);
98+
99+
/* Find the data section of the WAV file. */
100+
struct chunk_t
101+
{
102+
char ID[4];
103+
unsigned long size;
104+
};
105+
106+
chunk_t chunk;
107+
snprintf(msg, sizeof(msg), "id\t" "size");
108+
Serial.println(msg);
109+
/* Find data chunk. */
110+
while (true)
111+
{
112+
fread(&chunk, sizeof(chunk), 1, file);
113+
snprintf(msg, sizeof(msg), "%c%c%c%c\t" "%li", chunk.ID[0], chunk.ID[1], chunk.ID[2], chunk.ID[3], chunk.size);
114+
Serial.println(msg);
115+
if (*(unsigned int *) &chunk.ID == 0x61746164)
116+
break;
117+
/* Skip chunk data bytes. */
118+
fseek(file, chunk.size, SEEK_CUR);
119+
}
120+
121+
/* Determine number of samples. */
122+
sample_size = header.bitsPerSample / 8;
123+
samples_count = chunk.size * 8 / header.bitsPerSample;
124+
snprintf(msg, sizeof(msg), "Sample size = %i", sample_size); Serial.println(msg);
125+
snprintf(msg, sizeof(msg), "Samples count = %i", samples_count); Serial.println(msg);
126+
127+
/* Configure the advanced DAC. */
128+
if (!dac1.begin(AN_RESOLUTION_12, header.sampleRate, 256, 16))
129+
{
130+
Serial.println("Failed to start DAC1 !");
131+
return;
132+
}
133+
}
134+
135+
void loop()
136+
{
137+
if (dac1.available() && !feof(file))
138+
{
139+
/* Read data from file. */
140+
uint16_t sample_data[256] = {0};
141+
fread(sample_data, sample_size, 256, file);
142+
143+
/* Get a free buffer for writing. */
144+
SampleBuffer buf = dac1.dequeue();
145+
146+
/* Write data to buffer. */
147+
for (size_t i = 0; i < buf.size(); i++)
148+
{
149+
/* Scale down to 12 bit. */
150+
uint16_t const dac_val = ((static_cast<unsigned int>(sample_data[i])+32768)>>4) & 0x0fff;
151+
buf[i] = dac_val;
152+
}
153+
154+
/* Write the buffer to DAC. */
155+
dac1.write(buf);
156+
}
157+
}

src/AdvancedADC.h

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include "DMABuffer.h"
2222
#include "AdvancedAnalog.h"
2323

24+
#ifndef ARDUINO_ADVANCED_ADC_H_
25+
#define ARDUINO_ADVANCED_ADC_H_
26+
2427
struct adc_descr_t;
2528

2629
class AdvancedADC {
@@ -45,3 +48,5 @@ class AdvancedADC {
4548
int begin(uint32_t resolution, uint32_t sample_rate, size_t n_samples, size_t n_buffers);
4649
int stop();
4750
};
51+
52+
#endif /* ARDUINO_ADVANCED_ADC_H_ */

src/AdvancedDAC.h

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include "DMABuffer.h"
2222
#include "AdvancedAnalog.h"
2323

24+
#ifndef ARDUINO_ADVANCED_DAC_H_
25+
#define ARDUINO_ADVANCED_DAC_H_
26+
2427
struct dac_descr_t;
2528

2629
class AdvancedDAC {
@@ -47,3 +50,5 @@ class AdvancedDAC {
4750
int begin(uint32_t resolution, uint32_t frequency, size_t n_samples=0, size_t n_buffers=0);
4851
int stop();
4952
};
53+
54+
#endif /* ARDUINO_ADVANCED_DAC_H_ */

0 commit comments

Comments
 (0)