arduino-audio-tools
CodecOpusOgg.h
1 #pragma once
2 
3 #include "AudioTools/AudioCodecs/CodecOpus.h"
4 #include "AudioTools/AudioCodecs/ContainerOgg.h"
5 
6 namespace audio_tools {
7 
9 struct __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 
20 struct __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:
40  OpusOggDecoder() {
41  p_codec = &dec; // OpusAudioDecoder
42  out.setDecoder(p_codec);
43  };
44 
45 
47  OpusSettings &config() { return dec.config(); }
48 
49  bool begin(OpusSettings settings) {
50  OggContainerDecoder::begin();
51  return dec.begin(settings);
52  }
53 
54  bool begin() override {
55  TRACED();
56  OggContainerDecoder::begin();
57  return dec.begin();
58  }
59 
60  void end() override {
61  TRACED();
62  OggContainerDecoder::end();
63  dec.end();
64  }
65 
66  protected:
67  OpusOggHeader header;
68  OpusAudioDecoder dec;
69 
70  virtual void beginOfSegment(ogg_packet *op) override {
71  LOGD("bos");
72  if (op->packet == nullptr) return;
73  if (strncmp("OpusHead", (char *)op->packet, 8) == 0) {
74  memmove(&header, (char *)op->packet, sizeof(header));
75  AudioInfo info = audioInfo();
76  info.sample_rate = header.sampleRate;
77  info.channels = header.channelCount;
78  info.bits_per_sample = 16;
79  info.logInfo();
80  setAudioInfo(info);
81  } else if (strncmp("OpusTags", (char *)op->packet, 8) == 0) {
82  // not processed
83  }
84  }
85 };
86 
88 
89  protected:
90  OpusOggHeader header;
91  OpusOggCommentHeader comment;
92  ogg_packet oh1;
93 
94  bool writeHeader() override {
95  LOGI("writeHeader");
96  bool result = true;
97  header.sampleRate = cfg.sample_rate;
98  header.channelCount = cfg.channels;
99  // write header
100  oh.packet = (uint8_t *)&header;
101  oh.bytes = sizeof(header);
102  oh.granulepos = 0;
103  oh.packetno = packetno++;
104  oh.b_o_s = true;
105  oh.e_o_s = false;
106  if (!writePacket(oh)) {
107  result = false;
108  LOGE("writePacket-header");
109  }
110 
111  // write comment header
112  oh1.packet = (uint8_t *)&comment;
113  oh1.bytes = sizeof(comment);
114  oh1.granulepos = 0;
115  oh1.packetno = packetno++;
116  oh1.b_o_s = true;
117  oh1.e_o_s = false;
118  if (!writePacket(oh1, OGGZ_FLUSH_AFTER)) {
119  result = false;
120  LOGE("writePacket-header1");
121  }
122  TRACED();
123  return result;
124  }
125 };
126 
137  public:
138  OpusOggEncoder() {
139  setOggOutput(&ogg_writer);
140  setEncoder(&enc);
141  }
142 
143 
145  const char *mime() override { return "audio/ogg;codecs=opus"; }
146 
148  OpusEncoderSettings &config() { return enc.config(); }
149 
150  protected:
151  // use custom writer
152  OpusOggWriter ogg_writer;
153  // use opus encoder
154  OpusAudioEncoder enc;
155 };
156 
157 } // namespace audio_tools
virtual void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition: AudioCodecsBase.h:26
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:138
OpusAudioEncoder: Dependens on https://github.com/pschatzmann/arduino-libopus.git.
Definition: CodecOpus.h:249
OpusEncoderSettings & config()
Provides access to the configuration.
Definition: CodecOpus.h:288
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:47
Opus Encoder which uses the Ogg Container: see https://datatracker.ietf.org/doc/html/rfc7845 Dependen...
Definition: CodecOpusOgg.h:136
OpusEncoderSettings & config()
Provides access to the Opus config.
Definition: CodecOpusOgg.h:148
const char * mime() override
Provides "audio/opus".
Definition: CodecOpusOgg.h:145
Definition: CodecOpusOgg.h:87
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:823
struct __attribute__((packed)) OpusOggHeader
Opus header.
Definition: CodecOpusOgg.h:9
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
Setting for Opus Decoder.
Definition: CodecOpus.h:23