|
8 | 8 | namespace audio_tools {
|
9 | 9 |
|
10 | 10 | /**
|
11 |
| - * @brief Basic I2S API - for the ESP32 |
| 11 | + * @brief Basic I2S API - for the ESP32. If we receive 1 channel, we expand the result to 2 channels. |
12 | 12 | *
|
13 | 13 | */
|
14 | 14 | class I2SBase {
|
@@ -101,23 +101,91 @@ class I2SBase {
|
101 | 101 |
|
102 | 102 | // update the cfg.i2s.channel_format based on the number of channels
|
103 | 103 | void setChannels(int channels){
|
104 |
| - if (channels==2){ |
105 |
| - i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; |
106 |
| - } else if (channels==1){ |
107 |
| - i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT; |
108 |
| - } |
109 | 104 | cfg.channels = channels;
|
110 | 105 | }
|
111 | 106 |
|
112 | 107 | /// writes the data to the I2S interface
|
113 | 108 | size_t writeBytes(const void *src, size_t size_bytes){
|
114 |
| - size_t result = 0; |
115 |
| - if (i2s_write(i2s_num, src, size_bytes, &result, portMAX_DELAY)!=ESP_OK){ |
116 |
| - LOGE("%s", __func__); |
117 |
| - } |
| 109 | + size_t result = 0; |
| 110 | + if (cfg.channels==2){ |
| 111 | + if (i2s_write(i2s_num, src, size_bytes, &result, portMAX_DELAY)!=ESP_OK){ |
| 112 | + LOGE("%s", __func__); |
| 113 | + } |
| 114 | + } else { |
| 115 | + result = writeExpandChannel(src, size_bytes); |
| 116 | + } |
118 | 117 | return result;
|
119 | 118 | }
|
120 | 119 |
|
| 120 | + /// writes the data by making shure that we send 2 channels |
| 121 | + size_t writeExpandChannel(const void *src, size_t size_bytes){ |
| 122 | + size_t result = 0; |
| 123 | + int j; |
| 124 | + switch(cfg.bits_per_sample){ |
| 125 | + |
| 126 | + case 8: |
| 127 | + for (j=0;j<size_bytes;j++){ |
| 128 | + int8_t frame[2]; |
| 129 | + int8_t *data = (int8_t *)src; |
| 130 | + frame[0]=data[j]; |
| 131 | + frame[1]=data[j]; |
| 132 | + size_t result_call = 0; |
| 133 | + if (i2s_write(i2s_num, frame, sizeof(int8_t)*2, &result_call, portMAX_DELAY)!=ESP_OK){ |
| 134 | + LOGE("%s", __func__); |
| 135 | + } else { |
| 136 | + result += result_call; |
| 137 | + } |
| 138 | + } |
| 139 | + break; |
| 140 | + |
| 141 | + case 16: |
| 142 | + for (j=0;j<size_bytes/2;j++){ |
| 143 | + int16_t frame[2]; |
| 144 | + int16_t *data = (int16_t*)src; |
| 145 | + frame[0]=data[j]; |
| 146 | + frame[1]=data[j]; |
| 147 | + size_t result_call = 0; |
| 148 | + if (i2s_write(i2s_num, frame, sizeof(int16_t)*2, &result_call, portMAX_DELAY)!=ESP_OK){ |
| 149 | + LOGE("%s", __func__); |
| 150 | + } else { |
| 151 | + result += result_call; |
| 152 | + } |
| 153 | + } |
| 154 | + break; |
| 155 | + |
| 156 | + case 24: |
| 157 | + for (j=0;j<size_bytes/4;j++){ |
| 158 | + int24_t frame[2]; |
| 159 | + int24_t *data = (int24_t*) src; |
| 160 | + frame[0]=data[j]; |
| 161 | + frame[1]=data[j]; |
| 162 | + size_t result_call = 0; |
| 163 | + if (i2s_write(i2s_num, frame, sizeof(int24_t)*2, &result_call, portMAX_DELAY)!=ESP_OK){ |
| 164 | + LOGE("%s", __func__); |
| 165 | + } else { |
| 166 | + result += result_call; |
| 167 | + } |
| 168 | + } |
| 169 | + break; |
| 170 | + |
| 171 | + case 32: |
| 172 | + for (j=0;j<size_bytes/4;j++){ |
| 173 | + int32_t frame[2]; |
| 174 | + int32_t *data = (int32_t*) src; |
| 175 | + frame[0]=data[j]; |
| 176 | + frame[1]=data[j]; |
| 177 | + size_t result_call = 0; |
| 178 | + if (i2s_write(i2s_num, frame, sizeof(int32_t)*2, &result_call, portMAX_DELAY)!=ESP_OK){ |
| 179 | + LOGE("%s", __func__); |
| 180 | + } else { |
| 181 | + result += result_call; |
| 182 | + } |
| 183 | + } |
| 184 | + break; |
| 185 | + } |
| 186 | + return result; |
| 187 | + } |
| 188 | + |
121 | 189 | size_t readBytes(void *dest, size_t size_bytes){
|
122 | 190 | size_t result = 0;
|
123 | 191 | if (i2s_read(i2s_num, dest, size_bytes, &result, portMAX_DELAY)!=ESP_OK){
|
|
0 commit comments