arduino-audio-tools
I2SESP8266.h
1 #pragma once
2 
3 #ifdef ESP8266
4 #include <I2S.h>
5 
6 #include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
7 #include "AudioTools/CoreAudio/AudioLogger.h"
8 
9 #define IS_I2S_IMPLEMENTED
10 
11 namespace audio_tools {
12 
21  friend class I2SStream;
22 
23  public:
26  I2SConfigStd c(mode);
27  return c;
28  }
29 
31  bool setAudioInfo(AudioInfo) { return false; }
32 
34  bool begin(RxTxMode mode = TX_MODE) { return begin(defaultConfig(mode)); }
35 
37  bool begin(I2SConfigStd cfg) {
38  this->cfg = cfg;
39  i2s_set_rate(cfg.sample_rate);
40  cfg.bits_per_sample = 16;
41  if (!i2s_rxtx_begin(cfg.rx_tx_mode == RX_MODE, cfg.rx_tx_mode == TX_MODE)) {
42  LOGE("i2s_rxtx_begin failed");
43  return false;
44  }
45  return true;
46  }
47 
49  void end() { i2s_end(); }
50 
52  int available() { return I2S_BUFFER_COUNT * I2S_BUFFER_SIZE; }
53 
55  int availableForWrite() { return I2S_BUFFER_COUNT * I2S_BUFFER_SIZE; }
56 
58  I2SConfigStd config() { return cfg; }
59 
60  protected:
61  I2SConfigStd cfg;
62 
64  size_t writeBytes(const void *src, size_t size_bytes) {
65  size_t result = 0;
66  size_t frame_size = cfg.channels * (cfg.bits_per_sample / 8);
67  uint16_t frame_count = size_bytes / frame_size;
68  if (cfg.channels == 2 && cfg.bits_per_sample == 16) {
69  result = i2s_write_buffer((int16_t *)src, frame_count) * frame_size;
70  } else {
71  result = writeExt(src, size_bytes);
72  }
73  return result;
74  }
75 
77  size_t writeExt(const void *src, size_t size_bytes) {
78  size_t result = 0;
79  int j;
80 
81  switch (cfg.bits_per_sample) {
82  case 8:
83  for (j = 0; j < size_bytes; j += cfg.channels) {
84  int8_t *data = (int8_t *)src;
85  int16_t frame[2];
86  frame[0] = data[j] * 256;
87  if (cfg.channels == 1) {
88  frame[1] = data[j] * 256;
89  } else {
90  frame[1] = data[j + 1] * 256;
91  }
92  uint32_t *frame_ptr = (uint32_t *)frame;
93  if (i2s_write_sample(*frame_ptr)) {
94  result += 2;
95  }
96  }
97  break;
98 
99  case 16:
100  for (j = 0; j < size_bytes / 2; j += cfg.channels) {
101  int16_t *data = (int16_t *)src;
102  int16_t frame[2];
103  frame[0] = data[j];
104  if (cfg.channels == 1) {
105  frame[1] = data[j];
106  } else {
107  frame[1] = data[j + 1];
108  }
109  uint32_t *frame_ptr = (uint32_t *)frame;
110  if (i2s_write_sample(*frame_ptr)) {
111  result += 2;
112  }
113  }
114  break;
115 
116  case 24:
117  for (j = 0; j < size_bytes / 3; j += cfg.channels) {
118  int24_t *data = (int24_t *)src;
119  int24_t frame[2];
120  int32_t value = data[j];
121  frame[0] = value;
122  if (cfg.channels == 1) {
123  frame[1] = value;
124  } else {
125  value = data[j + 1];
126  frame[1] = value / 256;
127  }
128  uint32_t *frame_ptr = (uint32_t *)frame;
129  if (i2s_write_sample(*frame_ptr)) {
130  result += 2;
131  }
132  }
133  break;
134 
135  case 32:
136  for (j = 0; j < size_bytes / 4; j += cfg.channels) {
137  int32_t *data = (int32_t *)src;
138  int32_t frame[2];
139  frame[0] = data[j] / 65538;
140  if (cfg.channels == 1) {
141  frame[1] = data[j] / 65538;
142  } else {
143  frame[1] = data[j + 1] / 65538;
144  }
145  uint32_t *frame_ptr = (uint32_t *)frame;
146  if (i2s_write_sample(*frame_ptr)) {
147  result += 2;
148  }
149  }
150  break;
151  }
152  return result;
153  }
154 
156  size_t readBytes(void *dest, size_t size_bytes) {
157  size_t result_bytes = 0;
158  uint16_t frame_size = cfg.channels * (cfg.bits_per_sample / 8);
159  size_t frames = size_bytes / frame_size;
160  int16_t *ptr = (int16_t *)dest;
161 
162  for (int j = 0; j < frames; j++) {
163  int16_t *left = ptr;
164  int16_t *right = ptr + 1;
165  bool ok = i2s_read_sample(
166  left, right, false); // RX data returned in both 16-bit outputs.
167  if (!ok) {
168  break;
169  }
170  ptr += 2;
171  result_bytes += frame_size;
172  }
173  return result_bytes;
174  }
175 };
176 
177 using I2SDriver = I2SDriverESP8266;
178 
179 } // namespace audio_tools
180 
181 #endif
Configuration for i2s.
Definition: I2SConfigStd.h:17
RxTxMode rx_tx_mode
public settings
Definition: I2SConfigStd.h:48
Basic I2S API - for the ESP8266 Only 16 bits are supported !
Definition: I2SESP8266.h:20
bool setAudioInfo(AudioInfo)
Potentially updates the sample rate (if supported)
Definition: I2SESP8266.h:31
I2SConfigStd config()
provides the actual configuration
Definition: I2SESP8266.h:58
int available()
we assume the data is already available in the buffer
Definition: I2SESP8266.h:52
I2SConfigStd defaultConfig(RxTxMode mode)
Provides the default configuration.
Definition: I2SESP8266.h:25
int availableForWrite()
We limit the write size to the buffer size.
Definition: I2SESP8266.h:55
size_t writeExt(const void *src, size_t size_bytes)
writes the data by making shure that we send 2 channels 16 bit data
Definition: I2SESP8266.h:77
bool begin(I2SConfigStd cfg)
starts the DAC
Definition: I2SESP8266.h:37
void end()
stops the I2C and unistalls the driver
Definition: I2SESP8266.h:49
size_t writeBytes(const void *src, size_t size_bytes)
writes the data to the I2S interface
Definition: I2SESP8266.h:64
size_t readBytes(void *dest, size_t size_bytes)
reads the data from the I2S interface
Definition: I2SESP8266.h:156
bool begin(RxTxMode mode=TX_MODE)
starts the DAC with the default config
Definition: I2SESP8266.h:34
We support the Stream interface for the I2S access. In addition we allow a separate mute pin which mi...
Definition: I2SStream.h:33
24bit integer which is used for I2S sound processing. The values are represented as int32_t,...
Definition: Int24_4bytes_t.h:16
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:28
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:823
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52
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
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:59