@@ -214,7 +214,53 @@ NoAudioCodecSimplex::NoAudioCodecSimplex(int input_sample_rate, int output_sampl
214214 ESP_LOGI (TAG, " Simplex channels created" );
215215}
216216
217- NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm (int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, i2s_std_slot_mask_t spk_slot_mask,gpio_num_t mic_sck, gpio_num_t mic_din) {
217+ int NoAudioCodec::Write (const int16_t * data, int samples) {
218+ std::lock_guard<std::mutex> lock (data_if_mutex_);
219+ std::vector<int32_t > buffer (samples);
220+
221+ // output_volume_: 0-100
222+ // volume_factor_: 0-65536
223+ int32_t volume_factor = pow (double (output_volume_) / 100.0 , 2 ) * 65536 ;
224+ for (int i = 0 ; i < samples; i++) {
225+ int64_t temp = int64_t (data[i]) * volume_factor; // 使用 int64_t 进行乘法运算
226+ if (temp > INT32_MAX) {
227+ buffer[i] = INT32_MAX;
228+ } else if (temp < INT32_MIN) {
229+ buffer[i] = INT32_MIN;
230+ } else {
231+ buffer[i] = static_cast <int32_t >(temp);
232+ }
233+ }
234+
235+ size_t bytes_written;
236+ ESP_ERROR_CHECK (i2s_channel_write (tx_handle_, buffer.data (), samples * sizeof (int32_t ), &bytes_written, portMAX_DELAY));
237+ return bytes_written / sizeof (int32_t );
238+ }
239+
240+ int NoAudioCodec::Read (int16_t * dest, int samples) {
241+ size_t bytes_read;
242+
243+ std::vector<int32_t > bit32_buffer (samples);
244+ if (i2s_channel_read (rx_handle_, bit32_buffer.data (), samples * sizeof (int32_t ), &bytes_read, portMAX_DELAY) != ESP_OK) {
245+ ESP_LOGE (TAG, " Read Failed!" );
246+ return 0 ;
247+ }
248+
249+ samples = bytes_read / sizeof (int32_t );
250+ for (int i = 0 ; i < samples; i++) {
251+ int32_t value = bit32_buffer[i] >> 12 ;
252+ dest[i] = (value > INT16_MAX) ? INT16_MAX : (value < -INT16_MAX) ? -INT16_MAX : (int16_t )value;
253+ }
254+ return samples;
255+ }
256+
257+ // Delegating constructor: calls the main constructor with default slot mask
258+ NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm (int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din)
259+ : NoAudioCodecSimplexPdm(input_sample_rate, output_sample_rate, spk_bclk, spk_ws, spk_dout, I2S_STD_SLOT_LEFT, mic_sck, mic_din) {
260+ // All initialization is handled by the delegated constructor
261+ }
262+
263+ NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm (int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, i2s_std_slot_mask_t spk_slot_mask, gpio_num_t mic_sck, gpio_num_t mic_din) {
218264 duplex_ = false ;
219265 input_sample_rate_ = input_sample_rate;
220266 output_sample_rate_ = output_sample_rate;
@@ -292,110 +338,6 @@ NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm(int input_sample_rate, int output
292338 ESP_LOGI (TAG, " Simplex channels created" );
293339}
294340
295- NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm (int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din) {
296- duplex_ = false ;
297- input_sample_rate_ = input_sample_rate;
298- output_sample_rate_ = output_sample_rate;
299-
300- // Create a new channel for speaker
301- i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG ((i2s_port_t )1 , I2S_ROLE_MASTER);
302- tx_chan_cfg.dma_desc_num = AUDIO_CODEC_DMA_DESC_NUM;
303- tx_chan_cfg.dma_frame_num = AUDIO_CODEC_DMA_FRAME_NUM;
304- tx_chan_cfg.auto_clear_after_cb = true ;
305- tx_chan_cfg.auto_clear_before_cb = false ;
306- tx_chan_cfg.intr_priority = 0 ;
307- ESP_ERROR_CHECK (i2s_new_channel (&tx_chan_cfg, &tx_handle_, NULL ));
308-
309-
310- i2s_std_config_t tx_std_cfg = {
311- .clk_cfg = {
312- .sample_rate_hz = (uint32_t )output_sample_rate_,
313- .clk_src = I2S_CLK_SRC_DEFAULT,
314- .mclk_multiple = I2S_MCLK_MULTIPLE_256,
315- #ifdef I2S_HW_VERSION_2
316- .ext_clk_freq_hz = 0 ,
317- #endif
318-
319- },
320- .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG (I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
321- .gpio_cfg = {
322- .mclk = I2S_GPIO_UNUSED,
323- .bclk = spk_bclk,
324- .ws = spk_ws,
325- .dout = spk_dout,
326- .din = I2S_GPIO_UNUSED,
327- .invert_flags = {
328- .mclk_inv = false ,
329- .bclk_inv = false ,
330- .ws_inv = false ,
331- },
332- },
333- };
334- ESP_ERROR_CHECK (i2s_channel_init_std_mode (tx_handle_, &tx_std_cfg));
335- #if SOC_I2S_SUPPORTS_PDM_RX
336- // Create a new channel for MIC in PDM mode
337- i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG ((i2s_port_t )0 , I2S_ROLE_MASTER);
338- ESP_ERROR_CHECK (i2s_new_channel (&rx_chan_cfg, NULL , &rx_handle_));
339- i2s_pdm_rx_config_t pdm_rx_cfg = {
340- .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG ((uint32_t )input_sample_rate_),
341- /* The data bit-width of PDM mode is fixed to 16 */
342- .slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG (I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
343- .gpio_cfg = {
344- .clk = mic_sck,
345- .din = mic_din,
346-
347- .invert_flags = {
348- .clk_inv = false ,
349- },
350- },
351- };
352- ESP_ERROR_CHECK (i2s_channel_init_pdm_rx_mode (rx_handle_, &pdm_rx_cfg));
353- #else
354- ESP_LOGE (TAG, " PDM is not supported" );
355- #endif
356- ESP_LOGI (TAG, " Simplex channels created" );
357- }
358-
359- int NoAudioCodec::Write (const int16_t * data, int samples) {
360- std::lock_guard<std::mutex> lock (data_if_mutex_);
361- std::vector<int32_t > buffer (samples);
362-
363- // output_volume_: 0-100
364- // volume_factor_: 0-65536
365- int32_t volume_factor = pow (double (output_volume_) / 100.0 , 2 ) * 65536 ;
366- for (int i = 0 ; i < samples; i++) {
367- int64_t temp = int64_t (data[i]) * volume_factor; // 使用 int64_t 进行乘法运算
368- if (temp > INT32_MAX) {
369- buffer[i] = INT32_MAX;
370- } else if (temp < INT32_MIN) {
371- buffer[i] = INT32_MIN;
372- } else {
373- buffer[i] = static_cast <int32_t >(temp);
374- }
375- }
376-
377- size_t bytes_written;
378- ESP_ERROR_CHECK (i2s_channel_write (tx_handle_, buffer.data (), samples * sizeof (int32_t ), &bytes_written, portMAX_DELAY));
379- return bytes_written / sizeof (int32_t );
380- }
381-
382- int NoAudioCodec::Read (int16_t * dest, int samples) {
383- size_t bytes_read;
384-
385- std::vector<int32_t > bit32_buffer (samples);
386- if (i2s_channel_read (rx_handle_, bit32_buffer.data (), samples * sizeof (int32_t ), &bytes_read, portMAX_DELAY) != ESP_OK) {
387- ESP_LOGE (TAG, " Read Failed!" );
388- return 0 ;
389- }
390-
391- samples = bytes_read / sizeof (int32_t );
392- for (int i = 0 ; i < samples; i++) {
393- int32_t value = bit32_buffer[i] >> 12 ;
394- dest[i] = (value > INT16_MAX) ? INT16_MAX : (value < -INT16_MAX) ? -INT16_MAX : (int16_t )value;
395- }
396- return samples;
397- }
398-
399341int NoAudioCodecSimplexPdm::Read (int16_t * dest, int samples) {
400342 size_t bytes_read;
401343
@@ -405,6 +347,13 @@ int NoAudioCodecSimplexPdm::Read(int16_t* dest, int samples) {
405347 return 0 ;
406348 }
407349
408- // 计算实际读取的样本数
409- return bytes_read / sizeof (int16_t );
350+ samples = bytes_read / sizeof (int16_t );
351+ if (input_gain_ > 0 ) {
352+ int gain_factor = (int )input_gain_;
353+ for (int i = 0 ; i < samples; i++) {
354+ int32_t amplified = dest[i] * gain_factor;
355+ dest[i] = (amplified > INT16_MAX) ? INT16_MAX : (amplified < -INT16_MAX) ? -INT16_MAX : (int16_t )amplified;
356+ }
357+ }
358+ return samples;
410359}
0 commit comments