arduino-audio-tools
CodecL8.h
1 #pragma once
2 
3 #include "AudioCodecs/AudioEncoded.h"
4 
5 namespace audio_tools {
6 
19 class DecoderL8 : public AudioDecoder {
20  public:
25  DecoderL8(bool isSigned = false) {
26  TRACED();
27  setSigned(isSigned);
28  }
29 
35  DecoderL8(Print &out_stream, bool active = true) {
36  TRACED();
37  p_print = &out_stream;
38  }
39 
47  DecoderL8(Print &out_stream, AudioInfoSupport &bi) {
48  TRACED();
49  setOutput(out_stream);
51  }
52 
55  void setSigned(bool isSigned) { is_signed = isSigned; }
56 
58  virtual void setAudioInfo(AudioInfo from) override {
59  TRACED();
60  if (from.bits_per_sample!=16){
61  LOGE("Bits per sample not supported: %d", from.bits_per_sample);
62  }
63  from.bits_per_sample = 16;
64  if (info != from) {
65  notifyAudioChange(from);
66  }
67  info = from;
68  }
69 
70  virtual size_t write(const void *in_ptr, size_t in_size) override {
71  if (p_print == nullptr) return 0;
72  buffer.resize(in_size);
73  memset(buffer.data(), 0, in_size * 2);
74  if (is_signed) {
75  int8_t *pt8 = (int8_t *)in_ptr;
76  for (size_t j = 0; j < in_size; j++) {
77  buffer[j] = convertSample(pt8[j]);
78  }
79  } else {
80  uint8_t *pt8 = (uint8_t *)in_ptr;
81  for (size_t j = 0; j < in_size; j++) {
82  buffer[j] = convertSample(pt8[j]);
83  }
84  }
85  int write_byte_count = in_size * sizeof(int16_t);
86  size_t result = p_print->write((uint8_t *)buffer.data(), write_byte_count);
87  LOGD("DecoderL8 %d -> %d -> %d", (int)in_size, write_byte_count, (int)result);
88  return result / sizeof(int16_t);
89  }
90 
91  int16_t convertSample(int16_t in) {
92  int32_t tmp = in;
93  if (!is_signed) {
94  tmp -= 129;
95  }
96  return NumberConverter::clip<int16_t>(tmp * 258);
97  }
98 
99  virtual operator bool() override { return p_print!=nullptr; }
100 
101 
102  protected:
103  bool is_signed = false;
104  Vector<int16_t> buffer;
105 };
106 
120 class EncoderL8 : public AudioEncoder {
121  public:
122  // Empty Constructor - the output stream must be provided with begin()
123  EncoderL8(bool isSigned = false) {
124  TRACED();
125  setSigned(isSigned);
126  }
127 
128  // Constructor providing the output stream
129  EncoderL8(Print &out) { p_print = &out; }
130 
132  void setSigned(bool isSigned) { is_signed = isSigned; }
133 
135  void setOutput(Print &out_stream) override { p_print = &out_stream; }
136 
138  const char *mime() override { return "audio/l8"; }
139 
141  bool begin() override { is_open = true; return true;}
142 
144  bool begin(Print &out) {
145  p_print = &out;
146  return begin();
147  }
148 
150  void end() override { is_open = false; }
151 
153  size_t write(const void *in_ptr, size_t in_size) override {
154  if (p_print == nullptr) return 0;
155  int16_t *pt16 = (int16_t *)in_ptr;
156  size_t samples = in_size / 2;
157  buffer.resize(samples);
158  memset(buffer.data(), 0, samples);
159  for (size_t j = 0; j < samples; j++) {
160  buffer[j] = convertSample(pt16[j]);
161  }
162 
163  size_t result = p_print->write((uint8_t *)buffer.data(), samples);
164  LOGD("EncoderL8 %d -> %d -> %d", (int)in_size,(int) samples, (int)result);
165  return result * sizeof(int16_t);
166  }
167 
168  operator bool() override { return is_open; }
169 
170  int16_t convertSample(int16_t sample) {
171  int16_t tmp = NumberConverter::clip<int8_t>(sample / 258);
172  if (!is_signed) {
173  tmp += 129;
174  // clip to range
175  if (tmp < 0) {
176  tmp = 0;
177  } else if (tmp > 255) {
178  tmp = 255;
179  }
180  }
181  return tmp;
182  }
183 
184  bool isOpen() { return is_open; }
185 
186  protected:
187  Print *p_print = nullptr;
188  bool is_open;
189  bool is_signed = false;
190  Vector<int8_t> buffer;
191 };
192 
193 } // namespace audio_tools
Docoding of encoded audio into PCM data.
Definition: AudioEncoded.h:18
virtual void setOutput(AudioStream &out_stream)
Defines where the decoded result is written to.
Definition: AudioEncoded.h:36
Encoding of PCM data.
Definition: AudioEncoded.h:88
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition: AudioTypes.h:158
Supports changes to the sampling rate, bits and channels.
Definition: AudioTypes.h:136
DecoderL8 - Converts an 8 Bit Stream into 16Bits Most microcontrollers can not output 8 bit data dire...
Definition: CodecL8.h:19
void setSigned(bool isSigned)
Definition: CodecL8.h:55
DecoderL8(Print &out_stream, AudioInfoSupport &bi)
Construct a new DecoderL8 object.
Definition: CodecL8.h:47
DecoderL8(Print &out_stream, bool active=true)
Construct a new DecoderL8 object.
Definition: CodecL8.h:35
virtual void setAudioInfo(AudioInfo from) override
for most decoders this is not needed
Definition: CodecL8.h:58
DecoderL8(bool isSigned=false)
Construct a new DecoderL8 object.
Definition: CodecL8.h:25
EncoderL8s - Condenses 16 bit PCM data stream to 8 bits data. Most microcontrollers can not process 8...
Definition: CodecL8.h:120
void setSigned(bool isSigned)
By default the encoded values are unsigned, but can change them to signed.
Definition: CodecL8.h:132
void setOutput(Print &out_stream) override
Defines the output Stream.
Definition: CodecL8.h:135
const char * mime() override
Provides "audio/pcm".
Definition: CodecL8.h:138
void end() override
stops the processing
Definition: CodecL8.h:150
bool begin(Print &out)
starts the processing
Definition: CodecL8.h:144
size_t write(const void *in_ptr, size_t in_size) override
Writes PCM data to be encoded as RAW.
Definition: CodecL8.h:153
bool begin() override
starts the processing using the actual RAWAudioInfo
Definition: CodecL8.h:141
Definition: NoArduino.h:58
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:50
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:57