arduino-audio-tools
Loading...
Searching...
No Matches
RTSP.h
1#pragma once
2
3#include "AudioStreamer.h"
4#include "AudioTools/CoreAudio/AudioPlayer.h"
5#include "AudioTools/CoreAudio/AudioStreams.h"
6#include "IAudioSource.h"
7#include "RTSPServer.h"
8
17namespace audio_tools {
18
27class RTSPOutputPCMInfo : public PCMInfo {
28public:
29 RTSPOutputPCMInfo() = default;
30 virtual void begin(AudioStream &stream) { p_stream = &stream; }
31 int getSampleRate() override { return p_stream->audioInfo().sample_rate; }
32 int getChannels() override { return p_stream->audioInfo().channels; }
33 int getSampleSizeBytes() override {
34 return p_stream->audioInfo().bits_per_sample / 8;
35 };
36 virtual void setAudioInfo(AudioInfo ai) { p_stream->setAudioInfo(ai); }
37
38protected:
39 AudioStream *p_stream = nullptr;
40};
41
50class RTSPPCMAudioInfo : public PCMInfo {
51public:
52 RTSPPCMAudioInfo() = default;
53 virtual void begin(AudioInfo info) { this->info = info; }
54 int getSampleRate() override { return info.sample_rate; }
55 int getChannels() override { return info.channels; }
56 int getSampleSizeBytes() override { return info.bits_per_sample / 8; };
57 virtual void setAudioInfo(AudioInfo ai) { info = ai; }
58
59protected:
60 AudioInfo info;
61};
62
72class RTSPSourceFromAudioStream : public IAudioSource {
73public:
74 RTSPSourceFromAudioStream() = default;
81 setInput(stream);
82 setFormat(new RTSPFormatPCM(pcmInfo));
83 }
84
85 RTSPSourceFromAudioStream(AudioStream &stream, RTSPFormat &format) {
86 setInput(stream);
87 setFormat(&format);
88 }
89
90 void setInput(AudioStream &stream) {
91 p_audiostream = &stream;
92 pcmInfo.begin(stream);
93 }
94
102 virtual void setAudioInfo(AudioInfo info) {
103 TRACEI();
104 p_audiostream->setAudioInfo(info);
105 }
106
113 virtual int readBytes(void *dest, int byteCount) override {
114 time_of_last_read = millis();
115 int result = 0;
116 LOGD("readDataTo: %d", byteCount);
117 if (started) {
118 result = p_audiostream->readBytes((uint8_t *)dest, byteCount);
119 }
120 return result;
121 }
122 // Provides the Audio Information
123 virtual RTSPFormat *getFormat() override { return &format; }
124
128 virtual void start() override {
129 TRACEI();
130 IAudioSource::start();
131 p_audiostream->begin();
132 started = true;
133 };
137 virtual void stop() override {
138 TRACEI();
139 IAudioSource::stop();
140 started = false;
141 p_audiostream->end();
142 };
143
144 void setFragmentSize(int fragmentSize) {
145 format.setFragmentSize(fragmentSize);
146 }
147
148 void setTimerPeriod(int period) { format.setTimerPeriod(period); }
149
152 bool isActive() { return millis() - time_of_last_read < 100; }
153
155 bool isStarted() { return started; }
156
157protected:
158 AudioStream *p_audiostream = nullptr;
159 uint32_t time_of_last_read = 0;
160 bool started = true;
161 RTSPOutputPCMInfo pcmInfo;
162 RTSPFormatPCM format{pcmInfo};
163};
164
174class RTSPSourceStream : public IAudioSource {
175public:
183 p_stream = &stream;
184 rtp_info.begin(info);
185 setFormat(new RTSPFormatPCM(rtp_info));
186 }
187
194 RTSPSourceStream(Stream &stream, RTSPFormat &format) {
195 p_stream = &stream;
196 setFormat(&format);
197 }
198
206 virtual void setAudioInfo(AudioInfo info) {
207 TRACEI();
208 rtp_info.setAudioInfo(info);
209 }
210
211 // Provides the Audio Information
212 virtual RTSPFormat *getFormat() override { return &format; }
213
218 virtual int readBytes(void *dest, int byteCount) override {
219 int result = 0;
220 LOGD("readDataTo: %d", byteCount);
221 if (active) {
222 result = p_stream->readBytes((uint8_t *)dest, byteCount);
223 }
224 return result;
225 }
229 virtual void start() override {
230 TRACEI();
231 active = true;
232 };
236 virtual void stop() override {
237 TRACEI();
238 active = false;
239 };
240
241 void setFragmentSize(int fragmentSize) {
242 format.setFragmentSize(fragmentSize);
243 }
244
245 void setTimerPeriod(int period) { format.setTimerPeriod(period); }
246
247protected:
248 Stream *p_stream = nullptr;
249 bool active = true;
250 RTSPPCMAudioInfo rtp_info;
251 RTSPFormatPCM format{rtp_info};
252};
253
259class RTSPFormatAudioTools : public RTSPFormat {
260public:
261 virtual void begin(AudioInfo info) { cfg = info; }
263 virtual const char *format(char *buffer, int len) = 0;
267 const char* name() {
268 return name_str;
269 }
271 void setName(const char* name){
272 name_str = name;
273 }
274
275 void setFragmentSize(int fragmentSize) { RTSPFormat::setFragmentSize(fragmentSize);}
276 int fragmentSize() { return RTSPFormat::fragmentSize(); }
277
278 void setTimerPeriod(int period) { RTSPFormat::setTimerPeriod(period); }
279 int timerPeriod() { return RTSPFormat::timerPeriod(); }
280
281protected:
282 AudioInfo cfg;
283 const char* name_str="RTSP-Demo";;
284};
285
293public:
294 // Provides the Opus format information:
295 // m=audio 54312 RTP/AVP 101
296 // a=rtpmap:101 opus/48000/2
297 // a=fmtp:101 stereo=1; sprop-stereo=1
298 const char *format(char *buffer, int len) override {
299 TRACEI();
300 snprintf(buffer, len,
301 "s=%s\r\n" // Stream Name
302 "c=IN IP4 0.0.0.0\r\n" // Connection Information
303 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
304 "m=audio 0 RTP/AVP 101\r\n" // UDP sessions with format 101=opus
305 "a=rtpmap:101 opus/%d/2\r\n"
306 "a=fmtp:101 stereo=1; sprop-stereo=%d\r\n",
307 name(), cfg.sample_rate, cfg.channels == 2);
308 return (const char *)buffer;
309 }
311 AudioInfo cfg(44100, 2, 16);
312 return cfg;
313 }
314};
315
323public:
324 // Provides the SBC format information:
325 // m=audio 5004 RTP/AVP 98
326 // a=rtpmap:98 aptx/44100/2
327 // a=fmtp:98 variant=standard; bitresolution=16;
328 const char *format(char *buffer, int len) override {
329 TRACEI();
330 snprintf(buffer, len,
331 "s=%s\r\n" // Stream Name
332 "c=IN IP4 0.0.0.0\r\n" // Connection Information
333 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
334 "m=audio 0 RTP/AVP 98\r\n" // UDP sessions with format 98=aptx
335 "a=rtpmap:98 aptx/%d/%d\r\n"
336 "a=fmtp:98 variant=standard; bitresolution=%d\r\n",
337 name(), cfg.sample_rate, cfg.channels, cfg.bits_per_sample);
338 return (const char *)buffer;
339 }
341 AudioInfo cfg(44100, 2, 16);
342 return cfg;
343 }
344};
345
353public:
355 const char *format(char *buffer, int len) override {
356 TRACEI();
357 assert(cfg.sample_rate == 8000);
358 assert(cfg.channels == 1);
359
360 snprintf(buffer, len,
361 "s=%s\r\n" // Stream Name
362 "c=IN IP4 0.0.0.0\r\n" // Connection Information
363 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
364 "m=audio 0 RTP/AVP 3\r\n" // UDP sessions with format 3=GSM
365 , name());
366 return (const char *)buffer;
367 }
368
370 AudioInfo cfg(8000, 1, 16);
371 return cfg;
372 }
373};
374
383public:
385 const char *format(char *buffer, int len) override {
386 TRACEI();
387 assert(cfg.sample_rate == 8000);
388 assert(cfg.channels == 1);
389
390 snprintf(buffer, len,
391 "s=%s\r\n" // Stream Name
392 "c=IN IP4 0.0.0.0\r\n" // Connection Information
393 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
394 "m=audio 0 RTP/AVP %d\r\n" // UDP sessions with format 0=G711 μ-Law
395 , name(), getFormat());
396 return (const char *)buffer;
397 }
398
400 void setIsULaw(bool flag) { is_ulaw = flag; }
401
403 AudioInfo cfg(8000, 1, 16);
404 return cfg;
405 }
406
407protected:
408 bool is_ulaw = true;
409 uint8_t getFormat() { return is_ulaw ? 0 : 8; }
410};
411
419public:
421 const char *format(char *buffer, int len) override {
422 TRACEI();
423 snprintf(buffer, len,
424 "s=%s\r\n" // Stream Name
425 "c=IN IP4 0.0.0.0\r\n" // Connection Information
426 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
427 "m=audio 0 RTP/AVP %d\r\n" // UDP sessions with format 10 or 11
428 "a=rtpmap:%s\r\n"
429 "a=rate:%i\r\n", // provide sample rate
430 name(), format(cfg.channels), payloadFormat(cfg.sample_rate, cfg.channels),
431 cfg.sample_rate);
432 return (const char *)buffer;
433 }
434
436 AudioInfo cfg(16000, 2, 16);
437 return cfg;
438 }
439
440protected:
441 char payload_fromat[30];
442
443 // format for mono is 11 and stereo 11
444 int format(int channels) {
445 int result = 0;
446 switch (channels) {
447 case 1:
448 result = 11;
449 break;
450 case 2:
451 result = 10;
452 break;
453 default:
454 LOGE("unsupported audio type");
455 break;
456 }
457 return result;
458 }
459
460 const char *payloadFormat(int sampleRate, int channels) {
461 // see https://en.wikipedia.org/wiki/RTP_payload_formats
462 // 11 L16/%i/%i
463
464 switch (channels) {
465 case 1:
466 snprintf(payload_fromat, 30, "%d L16/%i/%i", format(channels), sampleRate,
467 channels);
468 break;
469 case 2:
470 snprintf(payload_fromat, 30, "%d L16/%i/%i", format(channels), sampleRate,
471 channels);
472 break;
473 default:
474 LOGE("unsupported audio type");
475 break;
476 }
477 return payload_fromat;
478 }
479};
480
488public:
489 const char *format(char *buffer, int len) override {
490 TRACEI();
491 snprintf(buffer, len,
492 "s=%s\r\n" // Stream Name
493 "c=IN IP4 0.0.0.0\r\n" // Connection Information
494 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
495 "m=audio 0 RTP/AVP 96\r\n" // UDP sessions with format 96=dynamic
496 "a=rtpmap:96 l8/%d/%d\r\n",
497 name(), cfg.sample_rate, cfg.channels);
498 return (const char *)buffer;
499 }
501 AudioInfo cfg(16000, 2, 8);
502 return cfg;
503 }
504};
505
516class RTSPOutput : public AudioOutput {
517public:
520 int buffer_size = 1024 * 2) {
521 buffer.resize(buffer_size);
522 p_format = &format;
523 p_encoder = &encoder;
524 p_encoder->setOutput(buffer);
525 }
526
528 RTSPOutput(int buffer_size = 1024) {
529 buffer.resize(buffer_size);
530 p_encoder->setOutput(buffer);
531 }
532
533 AudioStreamer *streamer() { return &rtsp_streamer; }
534
535 bool begin(AudioInfo info) {
536 cfg = info;
537 return begin();
538 }
539
540 bool begin() {
541 TRACEI();
542 if (p_input == nullptr) {
543 LOGE("input is null");
544 return false;
545 }
546 if (p_encoder == nullptr) {
547 LOGE("encoder is null");
548 return false;
549 }
550 if (p_format == nullptr) {
551 LOGE("format is null");
552 return false;
553 }
554 p_encoder->setAudioInfo(cfg);
555 p_encoder->begin();
556 p_format->begin(cfg);
557 // setup the AudioStreamer
558 rtsp_streamer.setAudioSource(&rtps_source);
559 // setup the RTSPSourceFromAudioStream
560 rtps_source.setInput(*p_input);
561 rtps_source.setFormat(p_format);
562 rtps_source.setAudioInfo(cfg);
563 rtps_source.start();
564 return true;
565 }
566
567 void end() { rtps_source.stop(); }
568
574 return rtps_source.isStarted() ? buffer.available() : 0;
575 }
576
581 size_t write(const uint8_t *data, size_t len) override {
582 TRACED();
583 size_t result = p_encoder->write(data, len);
584 return result;
585 }
586
588 operator bool() { return rtps_source.isActive(); }
589
590protected:
591 RTSPFormatPCM pcm;
592 CopyEncoder copy_encoder;
593 RTSPSourceFromAudioStream rtps_source;
594 RingBufferStream buffer{0};
595 AudioStream *p_input = &buffer;
596 AudioEncoder *p_encoder = &copy_encoder;
597 RTSPFormatAudioTools *p_format = &pcm;
598 AudioStreamer rtsp_streamer;
599};
600
601// legacy name
602#if USE_OBSOLETE
603using RTSPStream = RTSPOutput;
604#endif
605
606} // namespace audio_tools
Encoding of PCM data.
Definition AudioCodecsBase.h:84
void setAudioInfo(AudioInfo from) override
Defines the sample rate, number of channels and bits per sample.
Definition AudioCodecsBase.h:93
Abstract Audio Ouptut class.
Definition AudioOutput.h:22
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:113
virtual void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition BaseStream.h:121
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition BaseStream.h:144
Dummy Encoder which just copies the provided data to the output.
Definition CodecCopy.h:62
abtX format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats
Definition RTSP.h:322
AudioInfo defaultConfig()
Provide a default format that will just work.
Definition RTSP.h:340
const char * format(char *buffer, int len) override
Provides the format string.
Definition RTSP.h:328
RTSPFormat which supports the AudioInfo class.
Definition RTSP.h:259
virtual const char * format(char *buffer, int len)=0
Provides the format string.
const char * name()
Proides the name.
Definition RTSP.h:267
void setName(const char *name)
Defines the name.
Definition RTSP.h:271
virtual AudioInfo defaultConfig()=0
Provide a default format that will just work.
G711 μ-Law format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats Packet intervall: 20,...
Definition RTSP.h:382
void setIsULaw(bool flag)
Defines if we use ulow ar alow; by default we use ulaw!
Definition RTSP.h:400
AudioInfo defaultConfig()
Provide a default format that will just work.
Definition RTSP.h:402
const char * format(char *buffer, int len) override
Provides the G711 format information.
Definition RTSP.h:385
GSM format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSP.h:352
AudioInfo defaultConfig()
Provide a default format that will just work.
Definition RTSP.h:369
const char * format(char *buffer, int len) override
Provides the GSM format information.
Definition RTSP.h:355
Opus format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSP.h:292
AudioInfo defaultConfig()
Provide a default format that will just work.
Definition RTSP.h:310
const char * format(char *buffer, int len) override
Provides the format string.
Definition RTSP.h:298
L8 format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSP.h:487
AudioInfo defaultConfig()
Provide a default format that will just work.
Definition RTSP.h:500
const char * format(char *buffer, int len) override
Provides the format string.
Definition RTSP.h:489
PCM format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSP.h:418
AudioInfo defaultConfig()
Provide a default format that will just work.
Definition RTSP.h:435
const char * format(char *buffer, int len) override
Provides the GSM format information.
Definition RTSP.h:421
We can write PCM data to the RTSPOutput. This is encoded by the indicated encoder (e....
Definition RTSP.h:516
RTSPOutput(int buffer_size=1024)
Construcor using RTSPFormatPCM and no encoder.
Definition RTSP.h:528
size_t write(const uint8_t *data, size_t len) override
Definition RTSP.h:581
int availableForWrite()
Definition RTSP.h:573
RTSPOutput(RTSPFormatAudioTools &format, AudioEncoder &encoder, int buffer_size=1024 *2)
Default constructor.
Definition RTSP.h:519
PCMInfo subclass which provides the audio information from the related AudioStream Depends on the htt...
Definition RTSP.h:27
PCMInfo subclass which provides the audio information from the AudioInfo parameter.
Definition RTSP.h:50
Simple Facade which can turn AudioStream into a IAudioSource. This way we can e.g....
Definition RTSP.h:72
virtual void stop() override
Definition RTSP.h:137
virtual void start() override
Definition RTSP.h:128
bool isStarted()
Returns true after start() has been called.
Definition RTSP.h:155
RTSPSourceFromAudioStream(AudioStream &stream)
Construct a new RTSPOutputSource object from an AudioStream.
Definition RTSP.h:80
virtual void setAudioInfo(AudioInfo info)
Set the Audio Info. This needs to be called if we just pass a Stream. The AudioStream is usually able...
Definition RTSP.h:102
bool isActive()
Definition RTSP.h:152
virtual int readBytes(void *dest, int byteCount) override
Definition RTSP.h:113
Simple Facade which can turn any Stream into a IAudioSource. This way we can e.g. use an I2SStream as...
Definition RTSP.h:174
virtual void stop() override
Definition RTSP.h:236
virtual void start() override
Definition RTSP.h:229
virtual void setAudioInfo(AudioInfo info)
Set the Audio Info. This needs to be called if we just pass a Stream. The AudioStream is usually able...
Definition RTSP.h:206
RTSPSourceStream(Stream &stream, AudioInfo info)
Construct a new RTSPOutputSource object from an Arduino Stream You need to provide the audio informat...
Definition RTSP.h:182
RTSPSourceStream(Stream &stream, RTSPFormat &format)
Construct a new RTSPOutputSource object from an Arduino Stream You need to provide the audio informat...
Definition RTSP.h:194
virtual int readBytes(void *dest, int byteCount) override
Definition RTSP.h:218
An AudioStream backed by a Ringbuffer. We can write to the end and read from the beginning of the str...
Definition AudioStreams.h:342
Definition NoArduino.h:125
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioConfig.h:877
uint32_t millis()
Returns the milliseconds since the start.
Definition Time.h:12
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:52
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59