arduino-audio-tools
Loading...
Searching...
No Matches
CodecOpusOgg.h
1#pragma once
2
3#include "AudioTools/AudioCodecs/CodecOpus.h"
4#include "AudioTools/AudioCodecs/ContainerOgg.h"
5
6namespace audio_tools {
7
9struct __attribute__((packed)) OpusOggHeader {
10 char signature[8] = {'O', 'p', 'u', 's', 'H', 'e', 'a', 'd'};
11 uint8_t version = 1;
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;
17};
18
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;
25};
26
39 public:
41 p_codec = &dec; // OpusAudioDecoder
42 out.setDecoder(p_codec);
43 };
44
46 OpusSettings &config() { return dec.config(); }
47
48 bool begin(OpusSettings settings) {
49 OggContainerDecoder::begin();
50 return dec.begin(settings);
51 }
52
53 bool begin() override {
54 TRACED();
55 OggContainerDecoder::begin();
56 return dec.begin();
57 }
58
59 void end() override {
60 TRACED();
61 OggContainerDecoder::end();
62 dec.end();
63 }
64
65 protected:
66 OpusOggHeader header;
67 OpusAudioDecoder dec;
68
69 virtual void beginOfSegment(ogg_packet *op) override {
70 LOGD("bos");
71 if (op->packet == nullptr) return;
72 if (strncmp("OpusHead", (char *)op->packet, 8) == 0) {
73 memmove(&header, (char *)op->packet, sizeof(header));
74 AudioInfo info = audioInfo();
75 info.sample_rate = header.sampleRate;
76 info.channels = header.channelCount;
77 info.bits_per_sample = 16;
78 info.logInfo();
79 setAudioInfo(info);
80 } else if (strncmp("OpusTags", (char *)op->packet, 8) == 0) {
81 // not processed
82 }
83 }
84};
85
87 protected:
88 OpusOggHeader header;
89 OpusOggCommentHeader comment;
90 ogg_packet oh1;
91
92 bool writeHeader() override {
93 LOGI("writeHeader");
94 bool result = true;
95 header.sampleRate = cfg.sample_rate;
96 header.channelCount = cfg.channels;
97 // write header
98 oh.packet = (uint8_t *)&header;
99 oh.bytes = sizeof(header);
100 oh.granulepos = 0;
101 oh.packetno = packetno++;
102 oh.b_o_s = true;
103 oh.e_o_s = false;
104 if (!writePacket(oh)) {
105 result = false;
106 LOGE("writePacket-header");
107 }
108
109 // write comment header
110 oh1.packet = (uint8_t *)&comment;
111 oh1.bytes = sizeof(comment);
112 oh1.granulepos = 0;
113 oh1.packetno = packetno++;
114 oh1.b_o_s = true;
115 oh1.e_o_s = false;
116 if (!writePacket(oh1, OGGZ_FLUSH_AFTER)) {
117 result = false;
118 LOGE("writePacket-header1");
119 }
120 TRACED();
121 return result;
122 }
123};
124
135 public:
137 setOggOutput(&ogg_writer);
138 setEncoder(&enc);
139 }
140
142 const char *mime() override { return "audio/ogg;codecs=opus"; }
143
145 OpusEncoderSettings &config() { return enc.config(); }
146
148 uint32_t frameDurationUs() override {
149 // Get frame duration from encoder settings
150 int frameDurationMs = config().frame_sizes_ms_x2;
151 uint32_t frameDurationUs = 20000;
152 switch (frameDurationMs) {
153 case OPUS_FRAMESIZE_2_5_MS:
154 frameDurationUs = 2500;
155 break;
156 case OPUS_FRAMESIZE_5_MS:
157 frameDurationUs = 5000;
158 break;
159 case OPUS_FRAMESIZE_10_MS:
160 frameDurationUs = 10000;
161 break;
162 case OPUS_FRAMESIZE_20_MS:
163 frameDurationUs = 20000;
164 break;
165 }
166 return frameDurationUs;
167 }
168
169 protected:
170 // use custom writer
171 OpusOggWriter ogg_writer;
172 // use opus encoder
174};
175
176#include "AudioTools/Communication/RTSP/RTSPFormat.h"
177
178} // namespace audio_tools
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:28
Decoder for Ogg Container. Decodes a packet from an Ogg container. The Ogg begin segment contains the...
Definition ContainerOgg.h:26
AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition ContainerOgg.h:54
Encoder for Ogg Container. Encodes a packet for an Ogg container. The Ogg begin segment contains the ...
Definition ContainerOgg.h:350
void setOggOutput(OggContainerOutput *out)
Replace the ogg output class.
Definition ContainerOgg.h:418
Output class for the OggContainerEncoder. Each write is ending up as container entry.
Definition ContainerOgg.h:209
OpusSettings & config()
Provides access to the configuration.
Definition CodecOpus.h:144
Encode for Opus audio.
Definition CodecOpus.h:260
OpusEncoderSettings & config()
Provides access to the configuration.
Definition CodecOpus.h:300
Opus Decoder which uses the Ogg Container. See https://datatracker.ietf.org/doc/html/rfc7845....
Definition CodecOpusOgg.h:38
OpusSettings & config()
Provides access to the Opus configuration.
Definition CodecOpusOgg.h:46
Opus Encoder which uses the Ogg Container: see https://datatracker.ietf.org/doc/html/rfc7845 Dependen...
Definition CodecOpusOgg.h:134
OpusEncoderSettings & config()
Provides access to the Opus config.
Definition CodecOpusOgg.h:145
const char * mime() override
Provides "audio/opus".
Definition CodecOpusOgg.h:142
uint32_t frameDurationUs() override
provides the frame duration in us (e.g. for RTSP)
Definition CodecOpusOgg.h:148
Definition CodecOpusOgg.h:86
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
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
Setting for Opus Encoder where the following values are valid: -1 indicates that the default value sh...
Definition CodecOpus.h:68
int frame_sizes_ms_x2
OPUS_FRAMESIZE_2_5_MS,OPUS_FRAMESIZE_5_MS,OPUS_FRAMESIZE_10_MS,OPUS_FRAMESIZE_20_MS,...
Definition CodecOpus.h:105
Setting for Opus Decoder.
Definition CodecOpus.h:22