arduino-audio-tools
Loading...
Searching...
No Matches
RTSPFormat.h
1#pragma once
2#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
3#include "AudioTools/CoreAudio/AudioStreams.h"
4#include "AudioTools/CoreAudio/AudioTypes.h"
5#include "RTSPPlatform.h"
6#include "stdint.h"
7
8#define DEFAULT_PCM_FRAGMENT_SIZE 640
9
10namespace audio_tools {
11
42 public:
43 // Provides the format information: see see
44 // https://en.wikipedia.org/wiki/RTP_payload_formats
45 virtual const char *format(char *buffer, int len) = 0;
46
47 // Data convertsion e.g. to network format. len is in samples
48 virtual int convert(void *data, int sampleCount) { return sampleCount; }
49
50 // Initialize with AudioInfo like data
51 virtual void begin(AudioInfo info) { cfg = info; }
52 // Provide a default config (must be overridden by concrete subclass)
53 virtual AudioInfo defaultConfig() = 0;
54 // Access current AudioInfo
55 virtual AudioInfo audioInfo() { return cfg; }
56 // Name accessors
57 virtual const char *name() { return name_str; }
59 void setName(const char *name) { name_str = name; }
60
62 void setFragmentSize(int fragmentSize) { fragment_size = fragmentSize; }
63
65 virtual int fragmentSize() { return fragment_size; }
66
68 virtual int timestampIncrement() {
69 int sample_size_bytes = cfg.bits_per_sample / 8;
70 int samples_per_fragment =
71 fragmentSize() / (sample_size_bytes * cfg.channels);
72 return samples_per_fragment;
73 }
74
76 void setTimerPeriodUs(int period) { timer_period_us = period; }
77
79 virtual int timerPeriodUs() { return timer_period_us; }
80
82 virtual int rtpPayloadType() { return 96; }
83
85 virtual int readHeader(uint8_t *data) { return 0; }
86
88 virtual void setUseRfc2250Header(bool /*enable*/) {}
89 virtual bool useRfc2250Header() const { return false; }
90
91 protected:
92 const char *STD_URL_PRE_SUFFIX = "trackID";
93 // for sample rate 16000
94 int fragment_size = DEFAULT_PCM_FRAGMENT_SIZE;
95 int timer_period_us = 10000;
96 AudioInfo cfg{16000, 1, 16};
97 const char *name_str = "RTSPAudioTools";
98};
99
114class RTSPFormatPCM : public RTSPFormat {
115 public:
116 RTSPFormatPCM(AudioInfo info, int fragmentSize = DEFAULT_PCM_FRAGMENT_SIZE) {
117 cfg = info;
120 }
121
122 RTSPFormatPCM() {
123 AudioInfo tmp(16000, 1, 16); // Default: 16kHz mono 16-bit
124 cfg = tmp;
125 setFragmentSize(DEFAULT_PCM_FRAGMENT_SIZE);
126 setTimerPeriodUs(getTimerPeriod(DEFAULT_PCM_FRAGMENT_SIZE));
127 }
128
129 void begin(AudioInfo info) {
130 this->cfg = info;
131 setTimerPeriodUs(getTimerPeriod(this->fragment_size));
132 }
133
141 const char *format(char *buffer, int len) override {
142 snprintf(buffer, len,
143 "s=Microphone\r\n" // Stream Name
144 "c=IN IP4 0.0.0.0\r\n" // Connection Information
145 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
146 "m=audio 0 RTP/AVP %d\r\n" // UDP sessions with format 10 or 11
147 "a=rtpmap:%s\r\n"
148 "a=rate:%i\r\n", // provide sample rate
149 rtpPayloadType(), payloadFormat(), sampleRate());
150 LOGI("ftsp format: %s", buffer);
151 return (const char *)buffer;
152 }
153
160 int convert(void *data, int samples) {
161 // convert to network format (big endian)
162 int16_t *pt_16 = (int16_t *)data;
163 for (int j = 0; j < samples / 2; j++) {
164 pt_16[j] = htons(pt_16[j]);
165 }
166 return samples;
167 }
168
169 AudioInfo info() { return cfg; }
170
171 AudioInfo defaultConfig() override { return AudioInfo(16000, 1, 16); }
172
173 int rtpPayloadType() override {
174 int result = 0;
175 switch (channels()) {
176 case 1:
177 result = 11;
178 break;
179 case 2:
180 result = 10;
181 break;
182 default:
183 LOGE("unsupported audio type");
184 break;
185 }
186 return result;
187 }
188
189 protected:
190 char payload_fromat[30];
191
192 int sampleRate() { return cfg.sample_rate; }
193 int channels() { return cfg.channels; }
194 int bytesPerSample() { return cfg.bits_per_sample / 8; }
195
201 // Calculate how many samples are in the fragment
202 int samples_per_fragment = timestampIncrement();
203 // Calculate how long it takes to play these samples at the given sample
204 // rate
205 int timer_period =
206 (samples_per_fragment * 1000000) / cfg.sample_rate; // microseconds
207 return timer_period;
208 }
209
210
211 // see https://en.wikipedia.org/wiki/RTP_payload_formats
212 // 11 L16/%i/%i
213 const char *payloadFormat() {
214 switch (channels()) {
215 case 1:
216 snprintf(payload_fromat, 30, "%d L16/%i/%i", rtpPayloadType(),
217 sampleRate(), channels());
218 break;
219 case 2:
220 snprintf(payload_fromat, 30, "%d L16/%i/%i", rtpPayloadType(),
221 sampleRate(), channels());
222 break;
223 default:
224 LOGE("unsupported audio type");
225 break;
226 }
227 return payload_fromat;
228 }
229};
230
238 public:
240 setTimerPeriodUs(20000); // 20ms standard for Opus
241 }
242
245 p_encoder = &encoder;
246 setTimerPeriodUs(encoder.frameDurationUs()); // Convert ms to us
247 }
248
249 // Provides the Opus format information:
250 // m=audio 54312 RTP/AVP 101
251 // a=rtpmap:101 opus/48000/2
252 // a=fmtp:101 stereo=1; sprop-stereo=1
253 const char *format(char *buffer, int len) override {
254 TRACEI();
255 snprintf(buffer, len,
256 "s=%s\r\n" // Stream Name
257 "c=IN IP4 0.0.0.0\r\n" // Connection Information
258 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
259 "m=audio 0 RTP/AVP 101\r\n" // UDP sessions with format 101=opus
260 "a=rtpmap:101 opus/%d/2\r\n"
261 "a=fmtp:101 stereo=1; sprop-stereo=%d\r\n",
262 name(), cfg.sample_rate, cfg.channels == 2);
263 return (const char *)buffer;
264 }
265 AudioInfo defaultConfig() {
266 AudioInfo cfg(48000, 2, 16);
267 return cfg;
268 }
269
270 void begin(AudioInfo info) override {
271 RTSPFormat::begin(info);
272 // Update timer period based on encoder configuration if available
273 if (p_encoder != nullptr) {
274 // p_encoder->setAudioInfo(info);
275 setTimerPeriodUs(p_encoder->frameDurationUs()); // Convert ms to us
276 }
277 }
278
279 protected:
280 AudioEncoder *p_encoder = nullptr;
281};
282
290 public:
292 setTimerPeriodUs(20000); // Default 20ms, will be recalculated in begin()
293 }
294
295 // Provides the SBC format information:
296 // m=audio 5004 RTP/AVP 98
297 // a=rtpmap:98 aptx/44100/2
298 // a=fmtp:98 variant=standard; bitresolution=16;
299 const char *format(char *buffer, int len) override {
300 TRACEI();
301 snprintf(buffer, len,
302 "s=%s\r\n" // Stream Name
303 "c=IN IP4 0.0.0.0\r\n" // Connection Information
304 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
305 "m=audio 0 RTP/AVP 98\r\n" // UDP sessions with format 98=aptx
306 "a=rtpmap:98 aptx/%d/%d\r\n"
307 "a=fmtp:98 variant=standard; bitresolution=%d\r\n",
308 name(), cfg.sample_rate, cfg.channels, cfg.bits_per_sample);
309 return (const char *)buffer;
310 }
311 AudioInfo defaultConfig() {
312 AudioInfo cfg(44100, 2, 16);
313 return cfg;
314 }
315
316 void begin(AudioInfo info) override {
317 RTSPFormat::begin(info);
318 // Calculate fragment-based timing for AptX
319 if (fragmentSize() > 0 && cfg.sample_rate > 0 && cfg.channels > 0) {
320 int bytesPerSample = (cfg.bits_per_sample + 7) / 8;
321 int samplesPerFragment = fragmentSize() / (cfg.channels * bytesPerSample);
322 int period = (samplesPerFragment * 1000000) / cfg.sample_rate;
323 setTimerPeriodUs(period);
324 }
325 }
326};
327
334class RTSPFormatGSM : public RTSPFormat {
335 public:
336 RTSPFormatGSM() {
337 setTimerPeriodUs(20000); // 20ms standard for GSM (160 samples at 8kHz)
338 }
339
341 const char *format(char *buffer, int len) override {
342 TRACEI();
343 assert(cfg.sample_rate == 8000);
344 assert(cfg.channels == 1);
345
346 snprintf(buffer, len,
347 "s=%s\r\n" // Stream Name
348 "c=IN IP4 0.0.0.0\r\n" // Connection Information
349 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
350 "m=audio 0 RTP/AVP 3\r\n" // UDP sessions with format 3=GSM
351 ,
352 name());
353 return (const char *)buffer;
354 }
355
356 AudioInfo defaultConfig() {
357 AudioInfo cfg(8000, 1, 16);
358 return cfg;
359 }
360};
361
370 public:
371 RTSPFormatG711(bool isUlaw) {
372 setTimerPeriodUs(20000); // 20ms standard for G.711 (160 samples at 8kHz)
373 setIsULaw(isUlaw);
374 }
375
377 const char *format(char *buffer, int len) override {
378 TRACEI();
379 assert(cfg.sample_rate == 8000);
380 assert(cfg.channels == 1);
381
382 snprintf(
383 buffer, len,
384 "s=%s\r\n" // Stream Name
385 "c=IN IP4 0.0.0.0\r\n" // Connection Information
386 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
387 "m=audio 0 RTP/AVP %d\r\n" // UDP sessions with format 0=G711 μ-Law
388 ,
389 name(), getFormat());
390 return (const char *)buffer;
391 }
392
394 void setIsULaw(bool flag) { is_ulaw = flag; }
395
396 AudioInfo defaultConfig() {
397 AudioInfo cfg(8000, 1, 16);
398 return cfg;
399 }
400
401 protected:
402 bool is_ulaw = true;
403 uint8_t getFormat() { return is_ulaw ? 0 : 8; }
404};
405
413 public:
415 setTimerPeriodUs(20000); // Default 20ms, will be recalculated in begin()
416 }
417
418 const char *format(char *buffer, int len) override {
419 TRACEI();
420 snprintf(buffer, len,
421 "s=%s\r\n" // Stream Name
422 "c=IN IP4 0.0.0.0\r\n" // Connection Information
423 "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session
424 "m=audio 0 RTP/AVP 96\r\n" // UDP sessions with format 96=dynamic
425 "a=rtpmap:96 l8/%d/%d\r\n",
426 name(), cfg.sample_rate, cfg.channels);
427 return (const char *)buffer;
428 }
429 AudioInfo defaultConfig() {
430 AudioInfo cfg(16000, 2, 8);
431 return cfg;
432 }
433
434 void begin(AudioInfo info) override {
435 RTSPFormat::begin(info);
436 // Calculate fragment-based timing for L8 (8-bit PCM)
437 if (fragmentSize() > 0 && cfg.sample_rate > 0 && cfg.channels > 0) {
438 int bytesPerSample = 1; // 8-bit = 1 byte per sample
439 int samplesPerFragment = fragmentSize() / cfg.channels;
440 int period = (samplesPerFragment * 1000000) / cfg.sample_rate;
441 setTimerPeriodUs(period);
442 }
443 }
444};
445
466template <class AudioEncoder>
468 public:
470 setTimerPeriodUs(20000); // Default 20ms, will be recalculated in begin()
471 }
472
473 RTSPFormatADPCM(AudioEncoder &encoder) {
474 p_encoder = &encoder;
475 encoder.begin();
476 setTimerPeriodUs(encoder.frameDurationUs()); // Convert ms to us
477 setFragmentSize(encoder.blockSize());
478 }
479
481 if (p_encoder != nullptr) return p_encoder->frameDurationUs();
483 }
484
485 // Provides the IMA ADPCM format information
486 // See RFC 3551 for details
487 const char *format(char *buffer, int len) override {
488 TRACEI();
489 // Only certain sample rates are valid for DVI4 (IMA ADPCM)
490 int sr = cfg.sample_rate;
491 int payload_type = 5; // default to 8000 Hz
492 switch (sr) {
493 case 8000:
494 payload_type = 5;
495 break;
496 case 16000:
497 payload_type = 6;
498 break;
499 case 11025:
500 payload_type = 16;
501 break;
502 case 22050:
503 payload_type = 17;
504 break;
505 default:
506 LOGE("Unsupported sample rate for IMA ADPCM: %d", sr);
507 sr = 8000;
508 payload_type = 5;
509 break;
510 }
511 snprintf(buffer, len,
512 "s=%s\r\n"
513 "c=IN IP4 0.0.0.0\r\n"
514 "t=0 0\r\n"
515 "m=audio 0 RTP/AVP %d\r\n"
516 "a=rtpmap:%d DVI4/%d\r\n",
517 name(), payload_type, payload_type, sr);
518 return (const char *)buffer;
519 }
520 AudioInfo defaultConfig() {
521 AudioInfo cfg(22050, 1, 16); // 4 bits per sample for IMA ADPCM
522 return cfg;
523 }
524
525 void begin(AudioInfo info) override {
526 RTSPFormat::begin(info);
527 if (p_encoder != nullptr) {
528 ((AudioInfoSupport *)p_encoder)->setAudioInfo(info);
529 setTimerPeriodUs(p_encoder->frameDurationUs()); // Convert ms to us
530 } else {
531 // Calculate timing for ADPCM (4 bits per sample = 0.5 bytes per sample)
532 if (fragmentSize() > 0 && cfg.sample_rate > 0) {
533 int samplesPerFragment =
534 fragmentSize() * 2; // 2 samples per byte for 4-bit ADPCM
535 int period = (samplesPerFragment * 1000000) / cfg.sample_rate;
536 setTimerPeriodUs(period);
537 }
538 }
539 }
540
541 AudioInfo audioInfo() override {
542 if (p_encoder != nullptr)
543 return ((AudioInfoSupport *)p_encoder)->audioInfo();
544 return RTSPFormat::audioInfo();
545 }
546
547 protected:
548 AudioEncoder *p_encoder = nullptr;
549};
550
557class RTSPFormatMP3 : public RTSPFormat {
558 public:
559 RTSPFormatMP3() {
560 setTimerPeriodUs(26122); // ~26ms for MP3 frames (1152 samples at 44.1kHz)
561 setFragmentSize(2884); // Trigger read that is big enough
562 }
563
566 setEncoder(encoder);
567 setFragmentSize(2884); // Trigger read that is big enough
568 setTimerPeriodUs(encoder.frameDurationUs()); // Convert ms to us
569 }
570
571 void setEncoder(AudioEncoder &encoder) { p_encoder = &encoder; }
572
574 if (p_encoder != nullptr) return p_encoder->frameDurationUs();
576 }
577
578 virtual int timestampIncrement() {
579 if (p_encoder != nullptr) return p_encoder->samplesPerFrame();
580 // MP3 frame size is typically 1152 samples
581 return 1152;
582 }
583
586 if (p_encoder != nullptr)
587 return ((AudioInfoSupport *)p_encoder)->audioInfo();
588 return RTSPFormat::audioInfo();
589 }
590
591 // Provides the MP3 format information:
592 // m=audio 0 RTP/AVP 14
593 // a=rtpmap:14 MPA/90000[/ch]
594 // See RFC 3551 for details: MP3 RTP clock is always 90kHz
595 const char *format(char *buffer, int len) override {
596 TRACEI();
597 int payload_type = rtpPayloadType(); // RTP/AVP 14 = MPEG audio (MP3)
598 int ch = cfg.channels;
599 if (ch <= 0) ch = 1;
600 // Include channels when not mono for clarity
601 int ptime_ms =
602 (cfg.sample_rate > 0) ? (int)((1152 * 1000) / cfg.sample_rate) : 26;
603 if (ptime_ms < 10) ptime_ms = 10; // clamp to a reasonable minimum
604 if (ch == 1) {
605 snprintf(buffer, len,
606 "m=audio 0 RTP/AVP %d\r\n"
607 "a=rtpmap:%d MPA/90000\r\n"
608 "a=fmtp:%d layer=3\r\n"
609 "a=ptime:%d\r\n",
610 payload_type, payload_type, payload_type, ptime_ms);
611 } else {
612 snprintf(buffer, len,
613 "m=audio 0 RTP/AVP %d\r\n"
614 "a=rtpmap:%d MPA/90000/%d\r\n"
615 "a=fmtp:%d layer=3\r\n"
616 "a=ptime:%d\r\n",
617 payload_type, payload_type, ch, payload_type, ptime_ms);
618 }
619 return (const char *)buffer;
620 }
621
622 int rtpPayloadType() override { return 14; }
623
624 AudioInfo defaultConfig() {
625 AudioInfo cfg(44100, 2, 16); // Typical MP3 config
626 return cfg;
627 }
628
629 void begin(AudioInfo info) override {
630 RTSPFormat::begin(info);
631 // MP3 frame size is typically 1152 samples
632 int samplesPerFrame = 1152;
633 if (cfg.sample_rate > 0) {
634 int period = (samplesPerFrame * 1000000) / cfg.sample_rate;
635 setTimerPeriodUs(period);
636 }
637 }
638
640 int readHeader(unsigned char *buffer) override {
641 // Some clients (e.g., FFmpeg/ffplay) expect the optional RFC2250 4-byte
642 // MPEG audio header for payload type 14, while others (e.g., VLC) expect
643 // raw frames. Make this behavior configurable.
644 if (use_rfc2250_header_) {
645 memset(buffer, 0, 4);
646 return 4;
647 }
648 (void)buffer;
649 return 0;
650 }
651
652 protected:
653 AudioEncoder *p_encoder = nullptr;
654 bool use_rfc2250_header_ = false;
655
656 public:
657 // Enable/disable RFC2250 4-byte MPEG audio header in RTP payload
658 void setUseRfc2250Header(bool enable) { use_rfc2250_header_ = enable; }
659 bool useRfc2250Header() const override { return use_rfc2250_header_; }
660};
661
669class RTSPFormatAAC : public RTSPFormat {
670 public:
671 RTSPFormatAAC() {
672 setTimerPeriodUs(23219); // ~23ms for AAC frames (1024 samples at 44.1kHz)
673 }
674
675 // Provides the AAC format information:
676 // m=audio 0 RTP/AVP 96
677 // a=rtpmap:96 MPEG4-GENERIC/44100/2
678 // a=fmtp:96 streamtype=5; profile-level-id=1; mode=AAC-hbr; ...
679 // For simplicity, only basic SDP lines are provided here
680 const char *format(char *buffer, int len) override {
681 TRACEI();
682 int payload_type = 96; // Dynamic payload type for AAC
683 int sr = cfg.sample_rate;
684 int ch = cfg.channels;
685 snprintf(buffer, len,
686 "s=%s\r\n"
687 "c=IN IP4 0.0.0.0\r\n"
688 "t=0 0\r\n"
689 "m=audio 0 RTP/AVP %d\r\n"
690 "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
691 "a=fmtp:%d streamtype=5; profile-level-id=1; mode=AAC-hbr;\r\n",
692 name(), payload_type, payload_type, sr, ch, payload_type);
693 return (const char *)buffer;
694 }
695 AudioInfo defaultConfig() {
696 AudioInfo cfg(44100, 2, 16); // Typical AAC config
697 return cfg;
698 }
699
700 void begin(AudioInfo info) override {
701 RTSPFormat::begin(info);
702 // AAC frame size is typically 1024 samples
703 int samplesPerFrame = 1024;
704 if (cfg.sample_rate > 0) {
705 int period = (samplesPerFrame * 1000000) / cfg.sample_rate;
706 setTimerPeriodUs(period);
707 }
708 }
709};
710
711} // namespace audio_tools
Encoding of PCM data.
Definition AudioCodecsBase.h:97
virtual uint16_t samplesPerFrame()
Optioinal rtsp function: provide samples per the frame.
Definition AudioCodecsBase.h:113
virtual uint32_t frameDurationUs()
Optioinal rtsp function: provide the frame duration in microseconds.
Definition AudioCodecsBase.h:111
Supports changes to the sampling rate, bits and channels.
Definition AudioTypes.h:133
AAC format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats See RFC 3640 for details.
Definition RTSPFormat.h:669
RTSP/RTP formatter for mono IMA ADPCM (DVI4)
Definition RTSPFormat.h:467
int timerPeriodUs()
Timer period in microseconds.
Definition RTSPFormat.h:480
abtX format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats
Definition RTSPFormat.h:289
G711 μ-Law format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats Packet intervall: 20,...
Definition RTSPFormat.h:369
void setIsULaw(bool flag)
Defines if we use ulow ar alow; by default we use ulaw!
Definition RTSPFormat.h:394
const char * format(char *buffer, int len) override
Provides the G711 format information.
Definition RTSPFormat.h:377
GSM format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:334
const char * format(char *buffer, int len) override
Provides the GSM format information.
Definition RTSPFormat.h:341
Audio Format Definition - Base class for RTSP audio formats.
Definition RTSPFormat.h:41
virtual int timerPeriodUs()
Timer period in microseconds.
Definition RTSPFormat.h:79
virtual int readHeader(uint8_t *data)
Optional header: e.g. rfc2250.
Definition RTSPFormat.h:85
void setTimerPeriodUs(int period)
Defines the timer period in microseconds.
Definition RTSPFormat.h:76
virtual int timestampIncrement()
Fragment size in samples.
Definition RTSPFormat.h:68
void setFragmentSize(int fragmentSize)
Defines the fragment size in bytes.
Definition RTSPFormat.h:62
virtual int fragmentSize()
Fragment (=write) size in bytes.
Definition RTSPFormat.h:65
virtual int rtpPayloadType()
default dynamic
Definition RTSPFormat.h:82
void setName(const char *name)
Defines the name of the stream.
Definition RTSPFormat.h:59
virtual void setUseRfc2250Header(bool)
Optional: Configure RFC2250 header usage (default: no-op)
Definition RTSPFormat.h:88
MP3 format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:557
int timerPeriodUs()
Timer period in microseconds.
Definition RTSPFormat.h:573
virtual int timestampIncrement()
Fragment size in samples.
Definition RTSPFormat.h:578
AudioInfo audioInfo()
Provides the AudioInfo.
Definition RTSPFormat.h:585
RTSPFormatMP3(AudioEncoder &encoder)
Provide dynamic frame duration if encoder is available.
Definition RTSPFormat.h:565
int readHeader(unsigned char *buffer) override
rfc2250 header before the playload
Definition RTSPFormat.h:640
void setUseRfc2250Header(bool enable)
Optional: Configure RFC2250 header usage (default: no-op)
Definition RTSPFormat.h:658
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:622
Opus format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:237
RTSPFormatOpus(AudioEncoder &encoder)
Determine timer duration from opus configuration.
Definition RTSPFormat.h:244
L8 format for RTSP https://en.wikipedia.org/wiki/RTP_payload_formats.
Definition RTSPFormat.h:412
Linear PCM Format for RTSP Streaming.
Definition RTSPFormat.h:114
int convert(void *data, int samples)
Convert to network format.
Definition RTSPFormat.h:160
const char * format(char *buffer, int len) override
Provide format 10 or 11.
Definition RTSPFormat.h:141
int getTimerPeriod(int fragmentSize)
Get the timer period for streaming.
Definition RTSPFormat.h:200
int rtpPayloadType() override
default dynamic
Definition RTSPFormat.h:173
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:53
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