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