diff --git a/src/main.cpp b/src/main.cpp index 5770874..c3986eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,12 +9,14 @@ #include "keyboard.h" #include "sdcard.h" +#include "sound.h" #define VERSION "0.0" #define LED_PIN 21 Keyboard keyboard; SDCard sdcard; +Sound sound; void setup() { @@ -29,6 +31,7 @@ void setup() keyboard.init(); sdcard.mount(); + sound.init(); } void loop() @@ -43,9 +46,11 @@ void loop() if (touched == true) { // turn the LED on (HIGH is the voltage level) digitalWrite(LED_PIN, HIGH); + sound.play(); } else { // turn the LED off by making the voltage LOW digitalWrite(LED_PIN, LOW); + sound.stop(); } diff --git a/src/sound.cpp b/src/sound.cpp new file mode 100644 index 0000000..ef5ecd9 --- /dev/null +++ b/src/sound.cpp @@ -0,0 +1,86 @@ +/* + * i2s + * + * http://esp-idf.readthedocs.io/en/latest/api/peripherals/i2s.html + * https://github.com/espressif/esp-idf/blob/375b28650bd1c90d6ac706f63cde9a64d9a7e3e5/examples/peripherals/i2s/main/i2s_example_main.c + */ + +#include "sound.h" + +#include "Arduino.h" +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/i2s.h" +//#include +#include + + +#define SAMPLE_RATE (36000) +#define WAVE_FREQ_HZ (100) +//#define PI 3.14159265 + +#define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ) + + +using namespace std; + +Sound::Sound() { +} + +void Sound::init() { + unsigned int i, sample_val; + float sin_float, triangle_float, triangle_step = 65536.0 / SAMPLE_PER_CYCLE; + //for 36Khz sample rates, we create 100Hz sine wave, every cycle need 36000/100 = 360 samples (4-bytes each sample) + //using 6 buffers, we need 60-samples per buffer + //2-channels, 16-bit each channel, total buffer is 360*4 = 1440 bytes + i2s_config_t i2s_config; + i2s_config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX); // Only TX + i2s_config.sample_rate = SAMPLE_RATE; + i2s_config.bits_per_sample = (i2s_bits_per_sample_t)16; //16-bit per channel + i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; //2-channels + i2s_config.communication_format = (i2s_comm_format_t) (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB); + i2s_config.dma_buf_count = 6; + i2s_config.dma_buf_len = 60; // + i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1 + + i2s_pin_config_t pin_config = { + .bck_io_num = 26, + .ws_io_num = 25, + .data_out_num = 22, + .data_in_num = -1 //Not used + }; + + i2s_driver_install(i2s_num, &i2s_config, 0, NULL); + i2s_set_pin(i2s_num, &pin_config); + + triangle_float = -32767; + + for(i = 0; i < SAMPLE_PER_CYCLE; i++) { + sin_float = sin(i * PI / 180.0); + if(sin_float >= 0) + triangle_float += triangle_step; + else + triangle_float -= triangle_step; + sin_float *= 32767; + + sample_val = 0; + sample_val += (short)triangle_float; + sample_val = sample_val << 16; + sample_val += (short) sin_float; + + i2s_push_sample(i2s_num, (char *)&sample_val, portMAX_DELAY); + } +} + +void Sound::play() { + i2s_start(i2s_num); +} + +void Sound::stop() { + i2s_stop(i2s_num); +} + +void Sound::end() { + i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver +} diff --git a/src/sound.h b/src/sound.h new file mode 100644 index 0000000..d41763d --- /dev/null +++ b/src/sound.h @@ -0,0 +1,33 @@ +#ifndef _SOUND_H +#define _SOUND_H + +#include "Arduino.h" + +#include "driver/i2s.h" + +#define I2S_NUM 0 + + +typedef struct { + int16_t buf[512]; + int len; + int index; + int playing; +} i2sbuffer_t; + +class Sound { + public: + Sound(); + void init(); + void end(); + void loop(); +// void close(); + void play(); +// void pause(); + void stop(); + private: + i2sbuffer_t buffer; + const i2s_port_t i2s_num = (i2s_port_t)I2S_NUM; +}; + +#endif /* _SOUND_H */