Skip to content

Commit c936c50

Browse files
committed
Initial
0 parents  commit c936c50

File tree

203 files changed

+54247
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

203 files changed

+54247
-0
lines changed

LICENSE

+674
Large diffs are not rendered by default.

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# ESP32 Codec2 Arduino Library
2+
This is latest version of Codec2 library packaged for ESP32 Arduino usage.
3+
4+
For more information about Codec2 visit https://github.com/drowe67/codec2
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#include <DebugLog.h>
2+
#include <driver/i2s.h>
3+
#include <opus.h>
4+
5+
// serial
6+
#define SERIAL_BAUD_RATE 115200
7+
8+
// audio speaker
9+
#define AUDIO_SPEAKER_BCLK 26
10+
#define AUDIO_SPEAKER_LRC 13
11+
#define AUDIO_SPEAKER_DIN 25
12+
13+
// audio microphone
14+
#define AUDIO_MIC_SD 2
15+
#define AUDIO_MIC_WS 15
16+
#define AUDIO_MIC_SCK 4
17+
18+
#define AUDIO_SAMPLE_RATE 8000 // 44100
19+
#define AUDIO_OPUS_FRAME_MS 40 // one of 2.5, 5, 10, 20, 40, 60, 80, 100, 120
20+
#define AUDIO_OPUS_BITRATE 3200 // bit rate from 2400 to 512000
21+
#define AUDIO_OPUS_COMPLEXITY 0 // from 0 to 10
22+
23+
OpusEncoder *opus_encoder_;
24+
OpusDecoder *opus_decoder_;
25+
26+
TaskHandle_t audio_task_;
27+
28+
int16_t *opus_samples_;
29+
int opus_samples_size_;
30+
31+
int16_t *opus_samples_out_;
32+
int opus_samples_out_size_;
33+
34+
uint8_t *opus_bits_;
35+
int opus_bits_size_ = 1024;
36+
37+
void setup() {
38+
LOG_SET_LEVEL(DebugLogLevel::LVL_INFO);
39+
LOG_SET_OPTION(false, false, true); // disable file, line, enable func
40+
41+
Serial.begin(SERIAL_BAUD_RATE);
42+
while (!Serial);
43+
LOG_INFO("Board setup started");
44+
45+
// create i2s speaker
46+
i2s_config_t i2s_speaker_config = {
47+
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
48+
.sample_rate = AUDIO_SAMPLE_RATE,
49+
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
50+
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
51+
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
52+
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
53+
.dma_buf_count = 8,
54+
.dma_buf_len = 1024,
55+
.use_apll=0,
56+
.tx_desc_auto_clear= true,
57+
.fixed_mclk=-1
58+
};
59+
i2s_pin_config_t i2s_speaker_pin_config = {
60+
.bck_io_num = AUDIO_SPEAKER_BCLK,
61+
.ws_io_num = AUDIO_SPEAKER_LRC,
62+
.data_out_num = AUDIO_SPEAKER_DIN,
63+
.data_in_num = I2S_PIN_NO_CHANGE
64+
};
65+
if (i2s_driver_install(I2S_NUM_0, &i2s_speaker_config, 0, NULL) != ESP_OK) {
66+
LOG_ERROR("Failed to install i2s speaker driver");
67+
}
68+
if (i2s_set_pin(I2S_NUM_0, &i2s_speaker_pin_config) != ESP_OK) {
69+
LOG_ERROR("Failed to set i2s speaker pins");
70+
}
71+
72+
// create i2s microphone
73+
i2s_config_t i2s_mic_config = {
74+
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
75+
.sample_rate = AUDIO_SAMPLE_RATE,
76+
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
77+
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
78+
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
79+
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
80+
.dma_buf_count = 8,
81+
.dma_buf_len = 1024,
82+
.use_apll=0,
83+
.tx_desc_auto_clear= true,
84+
.fixed_mclk=-1
85+
};
86+
i2s_pin_config_t i2s_mic_pin_config = {
87+
.bck_io_num = AUDIO_MIC_SCK,
88+
.ws_io_num = AUDIO_MIC_WS,
89+
.data_out_num = I2S_PIN_NO_CHANGE,
90+
.data_in_num = AUDIO_MIC_SD
91+
};
92+
if (i2s_driver_install(I2S_NUM_1, &i2s_mic_config, 0, NULL) != ESP_OK) {
93+
LOG_ERROR("Failed to install i2s mic driver");
94+
}
95+
if (i2s_set_pin(I2S_NUM_1, &i2s_mic_pin_config) != ESP_OK) {
96+
LOG_ERROR("Failed to set i2s mic pins");
97+
}
98+
99+
// run codec2 audio loopback on a separate task
100+
xTaskCreate(&audio_task, "audio_task", 32000, NULL, 5, &audio_task_);
101+
102+
LOG_INFO("Board setup completed");
103+
}
104+
105+
void audio_task(void *param) {
106+
// configure encoder
107+
int encoder_error;
108+
opus_encoder_ = opus_encoder_create(AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &encoder_error);
109+
if (encoder_error != OPUS_OK) {
110+
LOG_ERROR("Failed to create OPUS encoder, error", encoder_error);
111+
return;
112+
}
113+
encoder_error = opus_encoder_init(opus_encoder_, AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP);
114+
if (encoder_error != OPUS_OK) {
115+
LOG_ERROR("Failed to initialize OPUS encoder, error", encoder_error);
116+
return;
117+
}
118+
opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(AUDIO_OPUS_BITRATE));
119+
opus_encoder_ctl(opus_encoder_, OPUS_SET_COMPLEXITY(AUDIO_OPUS_COMPLEXITY));
120+
opus_encoder_ctl(opus_encoder_, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
121+
122+
// configure decoder
123+
int decoder_error;
124+
opus_decoder_ = opus_decoder_create(AUDIO_SAMPLE_RATE, 1, &decoder_error);
125+
if (decoder_error != OPUS_OK) {
126+
LOG_ERROR("Failed to create OPUS decoder, error", decoder_error);
127+
return;
128+
}
129+
130+
opus_samples_size_ = (int)(AUDIO_SAMPLE_RATE / 1000 * AUDIO_OPUS_FRAME_MS);
131+
opus_samples_ = (int16_t*)malloc(sizeof(int16_t) * opus_samples_size_);
132+
opus_samples_out_size_ = 10 * opus_samples_size_;
133+
opus_samples_out_ = (int16_t*)malloc(sizeof(int16_t) * opus_samples_out_size_);
134+
135+
opus_bits_ = (uint8_t*)malloc(sizeof(uint8_t) * opus_bits_size_);
136+
137+
// run loopback record-encode-decode-playback loop
138+
size_t bytes_read, bytes_written;
139+
LOG_INFO("Audio task started");
140+
while(true) {
141+
i2s_read(I2S_NUM_1, opus_samples_, sizeof(uint16_t) * opus_samples_size_, &bytes_read, portMAX_DELAY);
142+
int encoded_size = opus_encode(opus_encoder_, opus_samples_, opus_samples_size_, opus_bits_, opus_bits_size_);
143+
vTaskDelay(1);
144+
int decoded_size = opus_decode(opus_decoder_, opus_bits_, encoded_size, opus_samples_out_, opus_samples_out_size_, 0);
145+
i2s_write(I2S_NUM_0, opus_samples_, sizeof(uint16_t) * decoded_size, &bytes_written, portMAX_DELAY);
146+
vTaskDelay(1);
147+
}
148+
}
149+
150+
void loop() {
151+
// do nothing
152+
delay(100);
153+
}

keywords.txt

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#######################################
2+
# Syntax Coloring Map For codec2
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
CODEC2 KEYWORD1
10+
11+
#######################################
12+
# Methods and Functions (KEYWORD2)
13+
#######################################
14+
15+
codec2_create KEYWORD2
16+
codec2_destroy KEYWORD2
17+
codec2_encode KEYWORD2
18+
codec2_decode KEYWORD2
19+
codec2_samples_per_frame KEYWORD2
20+
codec2_bits_per_frame KEYWORD2
21+
22+
#######################################
23+
# Instances (KEYWORD2)
24+
#######################################
25+
26+
#######################################
27+
# Constants (LITERAL1)
28+
#######################################
29+
30+
CODEC2_MODE_3200 LITERAL1
31+
CODEC2_MODE_2400 LITERAL1
32+
CODEC2_MODE_1600 LITERAL1
33+
CODEC2_MODE_1400 LITERAL1
34+
CODEC2_MODE_1300 LITERAL1
35+
CODEC2_MODE_1200 LITERAL1
36+
CODEC2_MODE_700C LITERAL1

library.properties

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=esp32_opus
2+
version=1.0.1
3+
author=sh123
4+
maintainer=sh123
5+
sentence=OPUS Arduino library for ESP32.
6+
paragraph=Use this library with ESP32 board to encode and decode OPUS speech frames.
7+
category=Communication
8+
url=https://github.com/sh123/esp32_opus_arduino
9+
architectures=esp32
10+
includes=opus_custom.h,opus_defines.h,opus.h,opus_multistream.h,opus_projection.h,opus_types.h

0 commit comments

Comments
 (0)