Skip to content

Commit 00ac581

Browse files
committed
Provide generic AudioServer with AudioWAVServer as subclass
1 parent f8ab547 commit 00ac581

File tree

6 files changed

+133
-47
lines changed

6 files changed

+133
-47
lines changed

examples/streams-flite-webserver_wav/streams-flite-webserver_wav.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
#include "flite_arduino.h"
10-
#include "AudioWAVServer.h"
10+
#include "AudioServer.h"
1111

1212
using namespace audio_tools;
1313

examples/streams-generator-webserver_wav/streams-generator-server_wav.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "AudioTools.h"
2-
#include "AudioWAVServer.h"
2+
#include "AudioServer.h"
33

44
using namespace audio_tools;
55

examples/streams-sam-webserver_wav/streams-sam-webserver_wav.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*/
88
#include "sam_arduino.h"
9-
#include "AudioWAVServer.h"
9+
#include "AudioServer.h"
1010

1111
using namespace audio_tools;
1212

examples/streams-tts-webserver_wav/streams-tts-webserver_wav.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*/
88
#include "TTS.h"
9-
#include "AudioWAVServer.h"
9+
#include "AudioServer.h"
1010

1111
using namespace audio_tools;
1212

sandbox/streams-mozzi-webserver/streams-mozzi-webserver.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*/
1010
#include "AudioTools.h"
11-
#include "AudioWAVServer.h"
11+
#include "AudioServer.h"
1212
#include "AudioMozzi.h"
1313
#include <Oscil.h>
1414
#include <tables/cos2048_int8.h> // table for Oscils to play

src/AudioWAVServer.h renamed to src/AudioServer.h

Lines changed: 128 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,29 @@
55
using namespace audio_tools;
66

77
/// Calback which writes the sound data to the stream
8-
typedef void (*AudioWAVServerDataCallback)(Stream &out);
8+
typedef void (*AudioServerDataCallback)(Stream &out);
99

1010
/**
11-
* @brief A simple Arduino Webserver which streams the result as WAV file.
11+
* @brief A simple Arduino Webserver which streams the result
1212
* 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.
1414
*/
15-
class AudioWAVServer {
15+
class AudioServer {
1616

1717
public:
1818
/**
1919
* @brief Construct a new Audio W A V Server object
2020
* We assume that the WiFi is already connected
2121
*/
22-
AudioWAVServer() = default;
22+
AudioServer() = default;
2323

2424
/**
2525
* @brief Construct a new Audio W A V Server object
2626
*
2727
* @param network
2828
* @param password
2929
*/
30-
AudioWAVServer(const char* network, const char *password) {
30+
AudioServer(const char* network, const char *password) {
3131
this->network = (char*)network;
3232
this->password = (char*)password;
3333
}
@@ -36,14 +36,11 @@ class AudioWAVServer {
3636
* @brief Start the server. You need to be connected to WiFI before calling this method
3737
*
3838
* @param in
39-
* @param sample_rate
40-
* @param channels
39+
* @param contentType Mime Type of result
4140
*/
42-
void begin(Stream &in, int sample_rate, int channels, int bits_per_sample=16) {
41+
void begin(Stream &in, const char* contentType) {
4342
this->in = &in;
44-
this->sample_rate = sample_rate;
45-
this->channels = channels;
46-
this->bits_per_sample = bits_per_sample;
43+
this->content_type = contentType;
4744

4845
connectWiFi();
4946

@@ -55,15 +52,12 @@ class AudioWAVServer {
5552
* @brief Start the server. The data must be provided by a callback method
5653
*
5754
* @param cb
58-
* @param sample_rate
59-
* @param channels
55+
* @param contentType Mime Type of result
6056
*/
61-
void begin(AudioWAVServerDataCallback cb, int sample_rate, int channels, int bits_per_sample=16) {
57+
void begin(AudioServerDataCallback cb, const char* contentType) {
6258
this->in =nullptr;
6359
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;
6761

6862
connectWiFi();
6963

@@ -94,12 +88,12 @@ class AudioWAVServer {
9488
processClient();
9589
} else {
9690
// We are connected: copy input from source to wav output
97-
if (encoder){
91+
if (client){
9892
if (callback==nullptr) {
9993
LOGI("copy data...");
10094
copier.copy();
10195
// if we limit the size of the WAV the encoder gets automatically closed when all has been sent
102-
if (!encoder) {
96+
if (!client) {
10397
LOGI("stop client...");
10498
client.stop();
10599
active = false;
@@ -120,16 +114,11 @@ class AudioWAVServer {
120114
char *password = nullptr;
121115
char *network = nullptr;
122116

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;
129120
Stream *in = nullptr;
130-
StreamCopy copier;
131-
WAVEncoder encoder;
132-
AudioOutputStream wav_stream = AudioOutputStream(encoder); // WAV output stream
121+
StreamCopy copier;
133122

134123
void connectWiFi() {
135124
LOGD("connectWiFi");
@@ -146,32 +135,24 @@ class AudioWAVServer {
146135
Serial.println(WiFi.localIP());
147136
}
148137

149-
void sendReply(){
138+
virtual void sendReply(){
150139
LOGD("sendReply");
151140
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
152141
// and a content-type so the client knows what's coming, then a blank line:
153142
client.println("HTTP/1.1 200 OK");
154-
client.println("Content-type:audio/wav");
143+
client.print("Content-type:");
144+
client.println(content_type);
155145
client.println();
156146

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-
166147
if (callback!=nullptr){
167148
// provide data via Callback
168149
LOGI("sendReply - calling callback");
169-
callback(wav_stream);
150+
callback(client);
170151
client.stop();
171152
} else {
172153
// provide data for stream
173154
LOGI("sendReply - Returning WAV stream...");
174-
copier.begin(wav_stream, *in);
155+
copier.begin(client, *in);
175156
}
176157
}
177158

@@ -206,3 +187,108 @@ class AudioWAVServer {
206187
}
207188

208189
};
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 = &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

Comments
 (0)