3#include "AudioTools/AudioCodecs/CodecOpus.h"
4#include "AudioTools/AudioCodecs/ContainerOgg.h"
9struct __attribute__((packed)) OpusOggHeader {
10 char signature[8] = {
'O',
'p',
'u',
's',
'H',
'e',
'a',
'd'};
12 uint8_t channelCount = 0;
13 uint16_t preSkip = 3840;
14 uint32_t sampleRate = 0;
15 int16_t outputGain = 0;
16 uint8_t channelMappingFamily = 0;
20struct __attribute__((packed)) OpusOggCommentHeader {
21 char signature[8] = {
'O',
'p',
'u',
's',
'T',
'a',
'g',
's'};
22 uint32_t vendorStringLength = 8;
23 char vendor[8] =
"Arduino";
24 uint32_t userCommentListLength = 0;
42 out.setDecoder(p_codec);
49 OggContainerDecoder::begin();
50 return dec.begin(settings);
53 bool begin()
override {
55 OggContainerDecoder::begin();
61 OggContainerDecoder::end();
69 virtual void beginOfSegment(ogg_packet *op)
override {
71 if (op->packet ==
nullptr)
return;
72 if (strncmp(
"OpusHead", (
char *)op->packet, 8) == 0) {
73 memmove(&header, (
char *)op->packet,
sizeof(header));
75 info.sample_rate = header.sampleRate;
76 info.channels = header.channelCount;
77 info.bits_per_sample = 16;
80 }
else if (strncmp(
"OpusTags", (
char *)op->packet, 8) == 0) {
89 OpusOggCommentHeader comment;
92 bool writeHeader()
override {
98 oh.packet = (uint8_t *)&header;
99 oh.bytes =
sizeof(header);
101 oh.packetno = packetno++;
104 if (!writePacket(oh)) {
106 LOGE(
"writePacket-header");
110 oh1.packet = (uint8_t *)&comment;
111 oh1.bytes =
sizeof(comment);
113 oh1.packetno = packetno++;
116 if (!writePacket(oh1, OGGZ_FLUSH_AFTER)) {
118 LOGE(
"writePacket-header1");
142 const char *
mime()
override {
return "audio/ogg;codecs=opus"; }
152 switch (frameDurationMs) {
153 case OPUS_FRAMESIZE_2_5_MS:
156 case OPUS_FRAMESIZE_5_MS:
159 case OPUS_FRAMESIZE_10_MS:
162 case OPUS_FRAMESIZE_20_MS:
176#include "AudioTools/Communication/RTSP/RTSPFormat.h"