arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
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
11namespace 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
177using 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 AudioCodecsBase.h:10
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:53
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