-
#include <WiFi.h>
-
#include "driver/i2s.h"
-
-
#define I2S_DATA 25 //
-
#define I2S_BLCK 26 //
-
#define I2S_LRCK 27 //
-
#define I2S_MCLK 3 //
-
-
QueueHandle_t i2sQueueHandle
;
-
TaskHandle_t i2sOutputTaskHandle
=
NULL
;
-
-
i2s_config_t i2s_config
;
-
i2s_pin_config_t i2s_pin_config
;
-
-
// Just change that to test
-
const
unsigned
char
bitsPerSample
=
I2S_BITS_PER_SAMPLE_24BIT
;
-
const
unsigned
long
sampleRate
=
48000
;
-
-
// hardcoded only for this test, max stereo samples for single DMA write is:
-
// 32 bits audio is 128: 1024 total bytes
-
// 24 bits audio si 170: 1020 total bytes
-
// 16 bits audio is 256: 1024 total bytes
-
unsigned
long
samples
=
int
(
1024
/
(
(
bitsPerSample
/
8
)
*
2
)
)
;
-
-
unsigned
char
bytes
=
(
bitsPerSample
/
8
)
*
2
;
-
-
// Buffer like struct array is not dynamic for hold bitspersample data
-
// So used bytes array instead, this prevents headcache.
-
unsigned
char
buffer
[
2048
]
;
-
-
constexpr
char
hexmap
[
]
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
-
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
}
;
-
-
void
i2sOutputTask
(
void
*
pvParameters
)
{
-
size_t
bytesWritten
;
-
-
// Install driver
-
i2s_driver_install
(
I2S_NUM_0,
&
i2s_config,
4
,
&
i2sQueueHandle
)
;
-
i2s_set_pin
(
I2S_NUM_0,
&
i2s_pin_config
)
;
-
-
//if(ESP_OK != i2s_set_clk(I2S_NUM_0, sampleRate, I2S_BITS_PER_SAMPLE_24BIT, I2S_CHANNEL_STEREO)){}
-
-
//i2s_check_set_mclk(I2S_NUM_0, I2S_MCLK );
-
i2s_zero_dma_buffer
(
I2S_NUM_0
)
;
-
-
for
(
;;
)
{
-
// wait for some data to be requested
-
i2s_event_t evt
;
-
if
(
xQueueReceive
(
i2sQueueHandle,
&
evt, portMAX_DELAY
)
==
pdPASS
)
{
-
-
if
(
evt.
type
==
I2S_EVENT_TX_DONE
)
{
-
i2s_write
(
I2S_NUM_0,
(
uint8_t
*
)
buffer,
-
(
samples
*
bytes
)
,
&
bytesWritten, portMAX_DELAY
-
)
;
-
-
if
(
bytesWritten
!
=
(
samples
*
bytes
)
)
{
-
Serial.
println
(
"Not all bytes were written to I2S"
)
;
-
}
-
//i2s_write_expand( I2S_NUM_0, (uint8_t *)buffer, (samples*bytes), 24, 24, &bytesWritten, portMAX_DELAY );
-
}
-
}
-
}
-
}
-
-
void
setup
(
)
{
-
Serial.
begin
(
115200
)
;
-
-
// Set pins
-
i2s_pin_config.
bck_io_num
=
I2S_BLCK
;
-
i2s_pin_config.
ws_io_num
=
I2S_LRCK
;
-
i2s_pin_config.
data_out_num
=
I2S_DATA
;
-
i2s_pin_config.
data_in_num
=
I2S_PIN_NO_CHANGE
;
-
-
// set config
-
i2s_config.
mode
=
(
i2s_mode_t
)
(
I2S_MODE_MASTER
|
I2S_MODE_TX
)
;
-
i2s_config.
sample_rate
=
(
i2s_bits_per_sample_t
)
sampleRate
;
-
i2s_config.
bits_per_sample
=
(
i2s_bits_per_sample_t
)
bitsPerSample
;
-
i2s_config.
channel_format
=
I2S_CHANNEL_FMT_RIGHT_LEFT
;
-
i2s_config.
communication_format
=
(
i2s_comm_format_t
)
I2S_COMM_FORMAT_STAND_I2S
;
-
i2s_config.
intr_alloc_flags
=
0
;
-
i2s_config.
dma_buf_count
=
6
;
-
i2s_config.
dma_buf_len
=
int
(
1024
/
(
(
bitsPerSample
/
8
)
*
2
)
)
;
-
i2s_config.
use_apll
=
false
;
-
i2s_config.
fixed_mclk
=
12288
;
-
i2s_config.
tx_desc_auto_clear
=
false
;
-
-
// fill frames bytes with same byte value, for use with logic analizer only
-
// so dont expect audio, all bytes on right to 0x01 and bytes on left to 0x02
-
for
(
int
i
=
0
;
i
<
samples
;
i
++
)
{
-
// Left
-
switch
(
bitsPerSample
)
{
-
case
I2S_BITS_PER_SAMPLE_8BIT
:
-
// rigth
-
buffer
[
(
i
*
bytes
)
]
=
1
;
-
-
// left
-
buffer
[
(
i
*
bytes
)
+
1
]
=
2
;
-
break
;
-
-
case
I2S_BITS_PER_SAMPLE_16BIT
:
-
// rigth
-
buffer
[
(
i
*
bytes
)
]
=
4
;
-
buffer
[
(
i
*
bytes
)
+
1
]
=
3
;
-
-
// left
-
buffer
[
(
i
*
bytes
)
+
2
]
=
2
;
-
buffer
[
(
i
*
bytes
)
+
3
]
=
1
;
-
break
;
-
-
case
I2S_BITS_PER_SAMPLE_24BIT
:
-
// rigth
-
buffer
[
(
i
*
bytes
)
]
=
6
;
-
buffer
[
(
i
*
bytes
)
+
1
]
=
5
;
-
buffer
[
(
i
*
bytes
)
+
2
]
=
4
;
-
-
// left
-
buffer
[
(
i
*
bytes
)
+
3
]
=
3
;
-
buffer
[
(
i
*
bytes
)
+
4
]
=
2
;
-
buffer
[
(
i
*
bytes
)
+
5
]
=
1
;
-
break
;
-
-
case
I2S_BITS_PER_SAMPLE_32BIT
:
-
// right
-
buffer
[
(
i
*
bytes
)
]
=
8
;
-
buffer
[
(
i
*
bytes
)
+
1
]
=
7
;
-
buffer
[
(
i
*
bytes
)
+
2
]
=
6
;
-
buffer
[
(
i
*
bytes
)
+
3
]
=
5
;
-
-
// left
-
buffer
[
(
i
*
bytes
)
+
4
]
=
4
;
-
buffer
[
(
i
*
bytes
)
+
5
]
=
3
;
-
buffer
[
(
i
*
bytes
)
+
6
]
=
2
;
-
buffer
[
(
i
*
bytes
)
+
7
]
=
1
;
-
break
;
-
-
default
:
-
Serial.
printf
(
"Unknown bits per sample: %d
\n
"
, bitsPerSample
)
;
-
}
-
}
-
-
Serial.
println
(
""
)
;
-
Serial.
printf
(
"Bits per Sample: %d, Samples: %d, Bytes: %d, Total: %d
\n
"
,
-
bitsPerSample, samples, bytes,
(
samples
*
bytes
)
-
)
;
-
-
// will print only first 4 samples ( stereo )
-
for
(
int
i
=
0
;
i
<
(
4
*
(
bytes
)
)
;
++
i
)
{
-
Serial.
print
(
hexmap
[
(
buffer
[
i
]
&
0xF0
)
>>
4
]
)
;
-
Serial.
print
(
hexmap
[
buffer
[
i
]
&
0x0F
]
)
;
-
Serial.
print
(
" "
)
;
-
if
(
(
(
i
+
1
)
%
(
bytes
/
2
)
==
0
)
&&
(
i
+
1
!
=
(
4
*
(
bytes
)
)
)
)
{
Serial.
print
(
"- "
)
;
}
-
}
-
-
xTaskCreatePinnedToCore
(
-
i2sOutputTask,
//Function to implement the task
-
"i2sOutputTask"
,
//Name of the task
-
5000
,
//Stack size in words
-
NULL
,
//Task input parameter
-
0
,
//Priority of the task
-
&
i2sOutputTaskHandle,
//Task handle.
-
1
//Core where the task should run
-
)
;
-
-
}
-
-
void
loop
(
)
{
-
delay
(
5
)
;
-
}