arduino-audio-tools
Loading...
Searching...
No Matches
CodecOpusOgg.h
Go to the documentation of this file.
1#pragma once
2
5
6namespace audio_tools {
7
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;
17};
18
21 char signature[8] = {'O', 'p', 'u', 's', 'T', 'a', 'g', 's'};
23 char vendor[8] = "Arduino";
25};
26
39 public:
41 p_codec = &dec; // OpusAudioDecoder
43 };
44
46 OpusSettings &config() { return dec.config(); }
47
48 bool begin(OpusSettings settings) {
50 return dec.begin(settings);
51 }
52
53 bool begin() override {
54 TRACED();
56 return dec.begin();
57 }
58
59 void end() override {
60 TRACED();
62 dec.end();
63 }
64
65 protected:
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));
75 info.sample_rate = header.sampleRate;
76 info.channels = header.channelCount;
78 info.logInfo();
80 } else if (strncmp("OpusTags", (char *)op->packet, 8) == 0) {
81 // not processed
82 }
83 }
84};
85
87 protected:
95 bool hasPendingPacket = false;
96
97 bool writeHeader() override {
98 LOGI("writeHeader");
99 bool result = true;
100 totalGranulepos = 0;
102 hasPendingPacket = false;
103 header.sampleRate = cfg.sample_rate;
104 header.channelCount = cfg.channels;
105 // write header
106 oh.packet = (uint8_t *)&header;
107 oh.bytes = sizeof(header);
108 oh.granulepos = 0;
109 oh.packetno = packetno++;
110 oh.b_o_s = true;
111 oh.e_o_s = false;
112 if (!writePacket(oh)) {
113 result = false;
114 LOGE("writePacket-header");
115 }
116
117 // write comment header
118 oh1.packet = (uint8_t *)&comment;
119 oh1.bytes = sizeof(comment);
120 oh1.granulepos = 0;
121 oh1.packetno = packetno++;
122 oh1.b_o_s = false;
123 oh1.e_o_s = false;
125 result = false;
126 LOGE("writePacket-header1");
127 }
128 TRACED();
129 return result;
130 }
131
133 if (!hasPendingPacket) return true;
134
135 op.packet = pendingPacket.data();
136 op.bytes = pendingPacket.size();
137 op.granulepos = granulePosition;
138 op.b_o_s = false;
139 op.e_o_s = endOfStream;
140 op.packetno = packetno++;
141 is_audio = true;
143 return false;
144 }
145
146 while ((oggz_write(p_oggz, op.bytes)) > 0)
147 ;
148
149 hasPendingPacket = false;
151 return true;
152 }
153
154 public:
158
159 void setFrameDurationUs(uint32_t frameDurationUs) {
161 (ogg_int64_t)(((uint64_t)frameDurationUs * 48000ULL) / 1000000ULL);
163 }
164
166 finalPacketSamples = samples;
167 }
168
169 size_t write(const uint8_t *data, size_t len) override {
170 if (data == nullptr) return 0;
171 LOGD("OpusOggWriter::write: %d", (int)len);
172
173 if (hasPendingPacket) {
175 if (!emitBufferedPacket(totalGranulepos, false)) {
176 return 0;
177 }
178 }
179
181 memcpy(pendingPacket.data(), data, len);
182 hasPendingPacket = true;
183
184 return len;
185 }
186
187 void end() override {
188 TRACED();
189
190 if (hasPendingPacket) {
195 }
198 }
199
200 is_open = false;
202 p_oggz = nullptr;
203 }
204};
205
216 public:
221
223 const char *mime() override { return "audio/ogg;codecs=opus"; }
224
227
230 // Get frame duration from encoder settings
233 switch (frameDurationMs) {
235 frameDurationUs = 2500;
236 break;
238 frameDurationUs = 5000;
239 break;
241 frameDurationUs = 10000;
242 break;
244 frameDurationUs = 20000;
245 break;
247 frameDurationUs = 40000;
248 break;
250 frameDurationUs = 60000;
251 break;
253 frameDurationUs = 80000;
254 break;
256 frameDurationUs = 100000;
257 break;
259 frameDurationUs = 120000;
260 break;
261 }
262 return frameDurationUs;
263 }
264
265 bool begin(AudioInfo from) override {
266 setAudioInfo(from);
267 return begin();
268 }
269
270 bool begin() override {
271 if (p_codec == nullptr) return false;
272
275 if (!p_codec->begin(p_ogg->audioInfo())) {
276 return false;
277 }
278
279 int lookaheadSamples = enc.lookaheadSamples();
280 if (lookaheadSamples > 0) {
282 (uint32_t)(((uint64_t)lookaheadSamples * 48000U) /
285 }
286
287 if (!p_ogg->begin()) {
288 p_codec->end();
289 return false;
290 }
291
292 return true;
293 }
294
308
309 protected:
310 // use custom writer
312 // use opus encoder
314};
315
317
318} // namespace audio_tools
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
AudioInfo info
Definition AudioCodecsBase.h:76
void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition AudioCodecsBase.h:28
virtual void setOutput(Print &out_stream) override
Default output assignment (encoders may override to store Print reference)
Definition AudioCodecsBase.h:109
AudioInfo cfg
Definition AudioOutput.h:88
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition AudioOutput.h:62
virtual void end()=0
virtual bool begin()=0
void setDecoder(AudioDecoder *decoder)
Definition AudioEncoded.h:144
Decoder for Ogg Container. Decodes a packet from an Ogg container. The Ogg begin segment contains the...
Definition ContainerOgg.h:26
void end() override
Definition ContainerOgg.h:88
EncodedAudioOutput out
Definition ContainerOgg.h:124
AudioDecoder * p_codec
Definition ContainerOgg.h:126
bool begin() override
Definition ContainerOgg.h:62
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
AudioEncoder * p_codec
Definition ContainerOgg.h:411
void setEncoder(AudioEncoder *enc)
Definition ContainerOgg.h:415
void end() override
stops the processing
Definition ContainerOgg.h:387
void setOggOutput(OggContainerOutput *out)
Replace the ogg output class.
Definition ContainerOgg.h:418
virtual void setAudioInfo(AudioInfo info) override
We actually do nothing with this.
Definition ContainerOgg.h:366
OggContainerOutput * p_ogg
Definition ContainerOgg.h:413
Output class for the OggContainerEncoder. Each write is ending up as container entry.
Definition ContainerOgg.h:209
bool is_open
Definition ContainerOgg.h:280
bool is_audio
Definition ContainerOgg.h:287
ogg_packet op
Definition ContainerOgg.h:282
OGGZ * p_oggz
Definition ContainerOgg.h:281
virtual bool begin() override
starts the processing using the actual AudioInfo
Definition ContainerOgg.h:218
ogg_packet oh
Definition ContainerOgg.h:283
virtual bool writePacket(ogg_packet &op, int flag=0)
Definition ContainerOgg.h:289
size_t packetno
Definition ContainerOgg.h:285
Decoder for the Opus audio format. Each Opus frame must be provided with one write() call....
Definition CodecOpus.h:121
bool begin(OpusSettings settings)
Definition CodecOpus.h:147
void end() override
Definition CodecOpus.h:180
OpusSettings & config()
Provides access to the configuration.
Definition CodecOpus.h:144
Encode for Opus audio.
Definition CodecOpus.h:260
int frameSizeSamples()
Definition CodecOpus.h:350
int lookaheadSamples()
Definition CodecOpus.h:341
OpusEncoderSettings & config()
Provides access to the configuration.
Definition CodecOpus.h:301
int pendingSamples()
Definition CodecOpus.h:352
Opus Decoder which uses the Ogg Container. See https://datatracker.ietf.org/doc/html/rfc7845....
Definition CodecOpusOgg.h:38
OpusOggHeader header
Definition CodecOpusOgg.h:66
bool begin(OpusSettings settings)
Definition CodecOpusOgg.h:48
OpusOggDecoder()
Definition CodecOpusOgg.h:40
OpusAudioDecoder dec
Definition CodecOpusOgg.h:67
void end() override
Definition CodecOpusOgg.h:59
OpusSettings & config()
Provides access to the Opus configuration.
Definition CodecOpusOgg.h:46
bool begin() override
Definition CodecOpusOgg.h:53
virtual void beginOfSegment(ogg_packet *op) override
Definition CodecOpusOgg.h:69
Opus Encoder which uses the Ogg Container: see https://datatracker.ietf.org/doc/html/rfc7845 Dependen...
Definition CodecOpusOgg.h:215
OpusOggEncoder()
Definition CodecOpusOgg.h:217
void end() override
stops the processing
Definition CodecOpusOgg.h:295
OpusEncoderSettings & config()
Provides access to the Opus config.
Definition CodecOpusOgg.h:226
OpusAudioEncoder enc
Definition CodecOpusOgg.h:313
const char * mime() override
Provides "audio/opus".
Definition CodecOpusOgg.h:223
OpusOggWriter ogg_writer
Definition CodecOpusOgg.h:311
uint32_t frameDurationUs() override
provides the frame duration in us (e.g. for RTSP)
Definition CodecOpusOgg.h:229
bool begin() override
starts the processing using the actual AudioInfo
Definition CodecOpusOgg.h:270
bool begin(AudioInfo from) override
Definition CodecOpusOgg.h:265
Definition CodecOpusOgg.h:86
void setFrameDurationUs(uint32_t frameDurationUs)
Definition CodecOpusOgg.h:159
bool writeHeader() override
Definition CodecOpusOgg.h:97
OpusOggHeader header
Definition CodecOpusOgg.h:88
ogg_int64_t totalGranulepos
Definition CodecOpusOgg.h:92
bool hasPendingPacket
Definition CodecOpusOgg.h:95
void setFinalPacketSamples(ogg_int64_t samples)
Definition CodecOpusOgg.h:165
void end() override
stops the processing
Definition CodecOpusOgg.h:187
bool emitBufferedPacket(ogg_int64_t granulePosition, bool endOfStream)
Definition CodecOpusOgg.h:132
size_t write(const uint8_t *data, size_t len) override
Writes raw data to be encoded and packaged.
Definition CodecOpusOgg.h:169
ogg_int64_t finalPacketSamples
Definition CodecOpusOgg.h:94
void setPreSkipSamples(uint16_t preSkipSamples)
Definition CodecOpusOgg.h:155
Vector< uint8_t > pendingPacket
Definition CodecOpusOgg.h:91
ogg_packet oh1
Definition CodecOpusOgg.h:90
ogg_int64_t samplesPerPacket
Definition CodecOpusOgg.h:93
OpusOggCommentHeader comment
Definition CodecOpusOgg.h:89
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
virtual void logInfo(const char *source="")
Definition AudioTypes.h:121
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
enum VBanDataTypeList __attribute__