1
6
7
17
18
27
28
29
34
35
40
41
42
43
44
45
46
47
48
52
53
54
55
56
60
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
104
110
111
112
118
119
120
121
122
123
/* ... */
#include <stdint.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_pdm.h"
#include "driver/gpio.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2s_pdm_example.h"
#include "i2s_example_pins.h"10 includes
#define EXAMPLE_PDM_TX_CLK_IO EXAMPLE_I2S_BCLK_IO1
#define EXAMPLE_PDM_TX_DOUT_IO EXAMPLE_I2S_DOUT_IO1
#define EXAMPLE_PDM_TX_FREQ_HZ 16000
#define EXAMPLE_WAVE_AMPLITUDE (1000.0)
#define CONST_PI (3.1416f)
#define EXAMPLE_SINE_WAVE_LEN(tone) (uint32_t)((EXAMPLE_PDM_TX_FREQ_HZ / (float)tone) + 0.5)
#define EXAMPLE_TONE_LAST_TIME_MS 500
#define EXAMPLE_BYTE_NUM_EVERY_TONE (EXAMPLE_TONE_LAST_TIME_MS * EXAMPLE_PDM_TX_FREQ_HZ / 1000)8 defines
static const uint32_t tone[3][7] = {
{262, 294, 330, 349, 392, 440, 494},
{523, 587, 659, 698, 784, 880, 988},
{1046, 1175, 1318, 1397, 1568, 1760, 1976},
}{...};
static const uint8_t song[28] = {1, 1, 5, 5, 6, 6, 5,
4, 4, 3, 3, 2, 2, 1,
5, 5, 4, 4, 3, 3, 2,
5, 5, 4, 4, 3, 3, 2
}{...};
static const uint8_t rhythm[7] = {1, 1, 1, 1, 1, 1, 2};
static const char *tone_name[3] = {"bass", "alto", "treble"};
static i2s_chan_handle_t i2s_example_init_pdm_tx(void)
{
i2s_chan_handle_t tx_chan;
/* ... */
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
tx_chan_cfg.auto_clear = true;
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
/* ... */
i2s_pdm_tx_config_t pdm_tx_cfg = {
#if CONFIG_EXAMPLE_PDM_TX_DAC
.clk_cfg = I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG(EXAMPLE_PDM_TX_FREQ_HZ),
.slot_cfg = I2S_PDM_TX_SLOT_DAC_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),/* ... */
#else
.clk_cfg = I2S_PDM_TX_CLK_DEFAULT_CONFIG(EXAMPLE_PDM_TX_FREQ_HZ),
.slot_cfg = I2S_PDM_TX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),/* ... */
#endif
.gpio_cfg = {
.clk = EXAMPLE_PDM_TX_CLK_IO,
.dout = EXAMPLE_PDM_TX_DOUT_IO,
.invert_flags = {
.clk_inv = false,
}{...},
}{...},
}{...};
ESP_ERROR_CHECK(i2s_channel_init_pdm_tx_mode(tx_chan, &pdm_tx_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));
return tx_chan;
}{ ... }
void i2s_example_pdm_tx_task(void *args)
{
int16_t *w_buf = (int16_t *)calloc(1, EXAMPLE_BUFF_SIZE);
assert(w_buf);
i2s_chan_handle_t tx_chan = i2s_example_init_pdm_tx();
size_t w_bytes = 0;
uint8_t cnt = 0;
uint8_t tone_select = 0;
printf("Playing %s `twinkle twinkle little star`\n", tone_name[tone_select]);
while (1) {
int tone_point = EXAMPLE_SINE_WAVE_LEN(tone[tone_select][song[cnt] - 1]);
for (int i = 0; i < tone_point; i++) {
w_buf[i] = (int16_t)((sin(2 * (float)i * CONST_PI / tone_point)) * EXAMPLE_WAVE_AMPLITUDE);
}{...}
for (int tot_bytes = 0; tot_bytes < EXAMPLE_BYTE_NUM_EVERY_TONE * rhythm[cnt % 7]; tot_bytes += w_bytes) {
if (i2s_channel_write(tx_chan, w_buf, tone_point * sizeof(int16_t), &w_bytes, 1000) != ESP_OK) {
printf("Write Task: i2s write failed\n");
}{...}
}{...}
cnt++;
if (cnt == sizeof(song)) {
cnt = 0;
tone_select++;
tone_select %= 3;
printf("Playing %s `twinkle twinkle little star`\n", tone_name[tone_select]);
}{...}
vTaskDelay(15);
}{...}
free(w_buf);
vTaskDelete(NULL);
}{ ... }