5
5
using namespace audio_tools ;
6
6
7
7
// / Calback which writes the sound data to the stream
8
- typedef void (*AudioWAVServerDataCallback )(Stream &out);
8
+ typedef void (*AudioServerDataCallback )(Stream &out);
9
9
10
10
/* *
11
- * @brief A simple Arduino Webserver which streams the result as WAV file.
11
+ * @brief A simple Arduino Webserver which streams the result
12
12
* This class is based on the WiFiServer class. All you need to do is to provide the data
13
- * with a callback method or from a Stream.
13
+ * with a callback method or from an Arduino Stream.
14
14
*/
15
- class AudioWAVServer {
15
+ class AudioServer {
16
16
17
17
public:
18
18
/* *
19
19
* @brief Construct a new Audio W A V Server object
20
20
* We assume that the WiFi is already connected
21
21
*/
22
- AudioWAVServer () = default ;
22
+ AudioServer () = default ;
23
23
24
24
/* *
25
25
* @brief Construct a new Audio W A V Server object
26
26
*
27
27
* @param network
28
28
* @param password
29
29
*/
30
- AudioWAVServer (const char * network, const char *password) {
30
+ AudioServer (const char * network, const char *password) {
31
31
this ->network = (char *)network;
32
32
this ->password = (char *)password;
33
33
}
@@ -36,14 +36,11 @@ class AudioWAVServer {
36
36
* @brief Start the server. You need to be connected to WiFI before calling this method
37
37
*
38
38
* @param in
39
- * @param sample_rate
40
- * @param channels
39
+ * @param contentType Mime Type of result
41
40
*/
42
- void begin (Stream &in, int sample_rate, int channels, int bits_per_sample= 16 ) {
41
+ void begin (Stream &in, const char * contentType ) {
43
42
this ->in = ∈
44
- this ->sample_rate = sample_rate;
45
- this ->channels = channels;
46
- this ->bits_per_sample = bits_per_sample;
43
+ this ->content_type = contentType;
47
44
48
45
connectWiFi ();
49
46
@@ -55,15 +52,12 @@ class AudioWAVServer {
55
52
* @brief Start the server. The data must be provided by a callback method
56
53
*
57
54
* @param cb
58
- * @param sample_rate
59
- * @param channels
55
+ * @param contentType Mime Type of result
60
56
*/
61
- void begin (AudioWAVServerDataCallback cb, int sample_rate, int channels, int bits_per_sample= 16 ) {
57
+ void begin (AudioServerDataCallback cb, const char * contentType ) {
62
58
this ->in =nullptr ;
63
59
this ->callback = cb;
64
- this ->sample_rate = sample_rate;
65
- this ->channels = channels;
66
- this ->bits_per_sample = bits_per_sample;
60
+ this ->content_type = contentType;
67
61
68
62
connectWiFi ();
69
63
@@ -94,12 +88,12 @@ class AudioWAVServer {
94
88
processClient ();
95
89
} else {
96
90
// We are connected: copy input from source to wav output
97
- if (encoder ){
91
+ if (client ){
98
92
if (callback==nullptr ) {
99
93
LOGI (" copy data..." );
100
94
copier.copy ();
101
95
// if we limit the size of the WAV the encoder gets automatically closed when all has been sent
102
- if (!encoder ) {
96
+ if (!client ) {
103
97
LOGI (" stop client..." );
104
98
client.stop ();
105
99
active = false ;
@@ -120,16 +114,11 @@ class AudioWAVServer {
120
114
char *password = nullptr ;
121
115
char *network = nullptr ;
122
116
123
- // Sound Generation
124
- int sample_rate;
125
- int channels;
126
- int bits_per_sample;
127
-
128
- AudioWAVServerDataCallback callback = nullptr ;
117
+ // Content
118
+ const char *content_type;
119
+ AudioServerDataCallback callback = nullptr ;
129
120
Stream *in = nullptr ;
130
- StreamCopy copier;
131
- WAVEncoder encoder;
132
- AudioOutputStream wav_stream = AudioOutputStream(encoder); // WAV output stream
121
+ StreamCopy copier;
133
122
134
123
void connectWiFi () {
135
124
LOGD (" connectWiFi" );
@@ -146,32 +135,24 @@ class AudioWAVServer {
146
135
Serial.println (WiFi.localIP ());
147
136
}
148
137
149
- void sendReply (){
138
+ virtual void sendReply (){
150
139
LOGD (" sendReply" );
151
140
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
152
141
// and a content-type so the client knows what's coming, then a blank line:
153
142
client.println (" HTTP/1.1 200 OK" );
154
- client.println (" Content-type:audio/wav" );
143
+ client.print (" Content-type:" );
144
+ client.println (content_type);
155
145
client.println ();
156
146
157
- // set up wav encoder
158
- auto config = encoder.defaultConfig ();
159
- config.channels = channels;
160
- config.sample_rate = sample_rate;
161
- // config.data_length = data_length;
162
- config.bits_per_sample = bits_per_sample;
163
- config.is_streamed = true ;
164
- encoder.begin (client, config);
165
-
166
147
if (callback!=nullptr ){
167
148
// provide data via Callback
168
149
LOGI (" sendReply - calling callback" );
169
- callback (wav_stream );
150
+ callback (client );
170
151
client.stop ();
171
152
} else {
172
153
// provide data for stream
173
154
LOGI (" sendReply - Returning WAV stream..." );
174
- copier.begin (wav_stream , *in);
155
+ copier.begin (client , *in);
175
156
}
176
157
}
177
158
@@ -206,3 +187,108 @@ class AudioWAVServer {
206
187
}
207
188
208
189
};
190
+
191
+
192
+ /* *
193
+ * @brief A simple Arduino Webserver which streams the audio PCM data result as WAV file.
194
+ * This class is based on the WiFiServer class. All you need to do is to provide the data
195
+ * with a callback method or from a Stream.
196
+ */
197
+ class AudioWAVServer : public AudioServer {
198
+
199
+ public:
200
+ /* *
201
+ * @brief Construct a new Audio W A V Server object
202
+ * We assume that the WiFi is already connected
203
+ */
204
+ AudioWAVServer () = default ;
205
+
206
+ /* *
207
+ * @brief Construct a new Audio W A V Server object
208
+ *
209
+ * @param network
210
+ * @param password
211
+ */
212
+ AudioWAVServer (const char * network, const char *password) : AudioServer(network, password) {
213
+ }
214
+
215
+ /* *
216
+ * @brief Start the server. You need to be connected to WiFI before calling this method
217
+ *
218
+ * @param in
219
+ * @param sample_rate
220
+ * @param channels
221
+ */
222
+ void begin (Stream &in, int sample_rate, int channels, int bits_per_sample=16 ) {
223
+ this ->in = ∈
224
+ this ->sample_rate = sample_rate;
225
+ this ->channels = channels;
226
+ this ->bits_per_sample = bits_per_sample;
227
+
228
+ connectWiFi ();
229
+
230
+ // start server
231
+ server.begin ();
232
+ }
233
+
234
+ /* *
235
+ * @brief Start the server. The data must be provided by a callback method
236
+ *
237
+ * @param cb
238
+ * @param sample_rate
239
+ * @param channels
240
+ */
241
+ void begin (AudioServerDataCallback cb, int sample_rate, int channels, int bits_per_sample=16 ) {
242
+ this ->in =nullptr ;
243
+ this ->callback = cb;
244
+ this ->sample_rate = sample_rate;
245
+ this ->channels = channels;
246
+ this ->bits_per_sample = bits_per_sample;
247
+
248
+ connectWiFi ();
249
+
250
+ // start server
251
+ server.begin ();
252
+ }
253
+
254
+ protected:
255
+
256
+ // Sound Generation
257
+ int sample_rate;
258
+ int channels;
259
+ int bits_per_sample;
260
+
261
+ // WAV support
262
+ WAVEncoder encoder;
263
+ AudioOutputStream wav_stream = AudioOutputStream(encoder); // WAV output stream
264
+
265
+ void sendReply (){
266
+ LOGD (" sendReply" );
267
+ // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
268
+ // and a content-type so the client knows what's coming, then a blank line:
269
+ client.println (" HTTP/1.1 200 OK" );
270
+ client.println (" Content-type:audio/wav" );
271
+ client.println ();
272
+
273
+ // set up wav encoder
274
+ auto config = encoder.defaultConfig ();
275
+ config.channels = channels;
276
+ config.sample_rate = sample_rate;
277
+ // config.data_length = data_length;
278
+ config.bits_per_sample = bits_per_sample;
279
+ config.is_streamed = true ;
280
+ encoder.begin (client, config);
281
+
282
+ if (callback!=nullptr ){
283
+ // provide data via Callback
284
+ LOGI (" sendReply - calling callback" );
285
+ callback (wav_stream);
286
+ client.stop ();
287
+ } else {
288
+ // provide data for stream
289
+ LOGI (" sendReply - Returning WAV stream..." );
290
+ copier.begin (wav_stream, *in);
291
+ }
292
+ }
293
+
294
+ };
0 commit comments