5
5
#include " esp_a2dp_api.h"
6
6
#include " driver/i2s.h"
7
7
#include " freertos/queue.h"
8
+ #include " SoundTypes.h"
8
9
9
10
namespace audio_tools {
10
11
@@ -21,6 +22,12 @@ class I2SConfig {
21
22
i2s_port_t port_no = I2S_NUM_0;
22
23
i2s_config_t i2s;
23
24
i2s_pin_config_t pin;
25
+ int channels = 2 ;
26
+
27
+ I2SConfig () {
28
+ i2s = defaultConfig (TX_MODE);
29
+ pin = defaultPinConfig (TX_MODE);
30
+ }
24
31
25
32
// / Default Constructor
26
33
I2SConfig (I2SMode mode) {
@@ -39,7 +46,7 @@ class I2SConfig {
39
46
protected:
40
47
i2s_config_t defaultConfig (I2SMode mode) {
41
48
ESP_LOGD (I2S_TAG, " %s" , __func__);
42
- i2s_config_t i2s_config = {
49
+ i2s_config_t config = {
43
50
.mode = (i2s_mode_t ) ((mode == TX_MODE) ? (I2S_MODE_MASTER | I2S_MODE_TX) : (I2S_MODE_MASTER | I2S_MODE_RX)) ,
44
51
.sample_rate = 44100 ,
45
52
.bits_per_sample = (i2s_bits_per_sample_t ) (sizeof (T) * 8 ),
@@ -50,18 +57,18 @@ class I2SConfig {
50
57
.dma_buf_len = 1024 ,
51
58
.use_apll = false ,
52
59
};
53
- return i2s_config ;
60
+ return config ;
54
61
}
55
62
56
63
i2s_pin_config_t defaultPinConfig (I2SMode mode = TX_MODE) {
57
64
ESP_LOGD (I2S_TAG, " %s - mode: %s" , __func__, mode==TX_MODE ? " TX" : " RX" );
58
- i2s_pin_config_t pin_config_const = {
65
+ i2s_pin_config_t config = {
59
66
.bck_io_num = 14 ,
60
67
.ws_io_num = 15 ,
61
68
.data_out_num = mode == TX_MODE ? 22 : I2S_PIN_NO_CHANGE,
62
69
.data_in_num = mode == RX_MODE ? 32 : I2S_PIN_NO_CHANGE
63
70
};
64
- return pin_config_const ;
71
+ return config ;
65
72
}
66
73
};
67
74
@@ -72,8 +79,11 @@ class I2SConfig {
72
79
* @copyright GPLv3
73
80
*/
74
81
template <typename T>
75
- class I2S {
82
+ class I2S : public AudioBaseInfoDependent {
83
+ friend class I2SStream ;
84
+
76
85
public:
86
+
77
87
// / Default Constructor
78
88
I2S () {
79
89
}
@@ -86,43 +96,57 @@ class I2S {
86
96
// / Provides the default configuration
87
97
I2SConfig<T> defaultConfig (I2SMode mode) {
88
98
ESP_LOGD (I2S_TAG, " %s" , __func__);
89
- I2SConfig<T> config (mode);
90
- return config ;
99
+ I2SConfig<T> c (mode);
100
+ return c ;
91
101
}
92
102
93
103
// / starts the DAC
94
104
void begin (I2SConfig<T> cfg) {
95
105
ESP_LOGD (I2S_TAG, " %s" , __func__);
106
+ this ->cfg = cfg;
96
107
this ->i2s_num = cfg.port_no ;
97
- this ->i2s_config = cfg.i2s ;
98
- this ->pin_config = cfg.pin ;
99
108
100
- ESP_LOGD (I2S_TAG, " sample rate: %d" , i2s_config.sample_rate );
101
- ESP_LOGD (I2S_TAG, " bits per sample: %d" , i2s_config.bits_per_sample );
102
- ESP_LOGD (I2S_TAG, " pin bck_io_num: %d" , pin_config.bck_io_num );
103
- ESP_LOGD (I2S_TAG, " pin ws_io_num: %d" , pin_config.ws_io_num );
104
- ESP_LOGD (I2S_TAG, " pin data_out_num: %d" , pin_config.data_out_num );
105
- ESP_LOGD (I2S_TAG, " pin data_in_num: %d" , pin_config.data_in_num );
109
+ // We make sure that we can reconfigure
110
+ if (is_started) {
111
+ stop ();
112
+ ESP_LOGD (I2S_TAG, " %s" , " I2S restarting" );
113
+ }
114
+
115
+ ESP_LOGD (I2S_TAG, " sample rate: %d" , cfg.i2s .sample_rate );
116
+ ESP_LOGD (I2S_TAG, " bits per sample: %d" , cfg.i2s .bits_per_sample );
117
+ ESP_LOGD (I2S_TAG, " number of channels: %d" , cfg.channels );
106
118
107
119
// setup config
108
- if (i2s_driver_install (i2s_num, &i2s_config , 0 , NULL )!=ESP_OK){
120
+ if (i2s_driver_install (i2s_num, &cfg. i2s , 0 , NULL )!=ESP_OK){
109
121
ESP_LOGE (I2S_TAG, " %s - %s" , __func__, " i2s_driver_install" );
110
122
}
111
123
112
124
// setup pin config
113
- if (i2s_set_pin (i2s_num, &pin_config)!= ESP_OK){
114
- ESP_LOGE (I2S_TAG, " %s - %s" , __func__, " i2s_set_pin" );
125
+ if (this ->cfg .i2s .mode & I2S_MODE_DAC_BUILT_IN ) {
126
+ ESP_LOGD (I2S_TAG, " Using built in DAC" );
127
+ // for internal DAC, this will enable both of the internal channels
128
+ i2s_set_pin (i2s_num, NULL );
129
+ } else {
130
+ if (i2s_set_pin (i2s_num, &cfg.pin )!= ESP_OK){
131
+ ESP_LOGD (I2S_TAG, " pin bck_io_num: %d" , cfg.pin .bck_io_num );
132
+ ESP_LOGD (I2S_TAG, " pin ws_io_num: %d" , cfg.pin .ws_io_num );
133
+ ESP_LOGD (I2S_TAG, " pin data_out_num: %d" , cfg.pin .data_out_num );
134
+ ESP_LOGD (I2S_TAG, " pin data_in_num: %d" , cfg.pin .data_in_num );
135
+ ESP_LOGE (I2S_TAG, " %s - %s" , __func__, " i2s_set_pin" );
136
+ }
115
137
}
116
138
117
139
// clear initial buffer
118
140
i2s_zero_dma_buffer (i2s_num);
119
141
142
+ is_started = true ;
120
143
}
121
144
122
145
// / stops the I2C and unistalls the driver
123
146
void stop (){
124
147
ESP_LOGD (I2S_TAG, " %s" , __func__);
125
- i2s_driver_uninstall (i2s_num);
148
+ i2s_driver_uninstall (i2s_num);
149
+ is_started = false ;
126
150
}
127
151
128
152
// / writes the data to the I2S interface
@@ -139,12 +163,44 @@ class I2S {
139
163
return result;
140
164
}
141
165
166
+ // / provides the actual configuration
167
+ I2SConfig<T> config () {
168
+ return cfg;
169
+ }
170
+
171
+ // / updates the sample rate dynamically
172
+ virtual void setAudioBaseInfo (AudioBaseInfo info) {
173
+ bool is_update = false ;
174
+
175
+ if (cfg.i2s .sample_rate != info.sample_rate
176
+ || cfg.i2s .bits_per_sample != info.bits_per_sample ) {
177
+ cfg.i2s .sample_rate = info.sample_rate ;
178
+ cfg.i2s .bits_per_sample = static_cast <i2s_bits_per_sample_t >(info.bits_per_sample );
179
+ is_update = true ;
180
+ }
181
+
182
+ if (cfg.channels != info.channels ){
183
+ if (info.channels ==2 ){
184
+ cfg.i2s .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
185
+ } else if (info.channels ==1 ){
186
+ cfg.i2s .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT;
187
+ }
188
+ cfg.channels = info.channels ;
189
+ is_update = true ;
190
+ }
191
+
192
+ if (is_update){
193
+ // restart
194
+ begin (config ());
195
+ }
196
+
197
+ }
198
+
142
199
protected:
200
+ I2SConfig<T> cfg;
143
201
i2s_port_t i2s_num;
144
- i2s_pin_config_t pin_config;
145
- i2s_config_t i2s_config;
202
+ bool is_started = false ;
146
203
147
-
148
204
// / writes the data to the I2S interface
149
205
size_t writeBytes (const void *src, size_t size_bytes, TickType_t ticks_to_wait=portMAX_DELAY){
150
206
size_t result = 0 ;
@@ -154,17 +210,16 @@ class I2S {
154
210
return result;
155
211
}
156
212
157
-
158
213
size_t readBytes (void *dest, size_t size_bytes, TickType_t ticks_to_wait=portMAX_DELAY){
159
214
size_t result = 0 ;
160
215
if (i2s_read (i2s_num, dest, size_bytes, &result, ticks_to_wait)!=ESP_OK){
161
216
ESP_LOGE (I2S_TAG, " %s" , __func__);
162
217
}
163
218
return result;
164
219
}
165
-
166
220
};
167
221
222
+
168
223
}
169
224
170
225
#endif
0 commit comments