Browse Source
http://esp-idf.readthedocs.io/en/latest/api/peripherals/i2s.html
375b28650b/examples/peripherals/i2s/main/i2s_example_main.c
main
Hendrik Langer
8 years ago
3 changed files with 124 additions and 0 deletions
@ -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 <stdio.h> |
||||
|
#include "freertos/FreeRTOS.h" |
||||
|
#include "freertos/task.h" |
||||
|
#include "driver/i2s.h" |
||||
|
//#include <soc/i2s_reg.h>
|
||||
|
#include <math.h> |
||||
|
|
||||
|
|
||||
|
#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
|
||||
|
} |
@ -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 */ |
Loading…
Reference in new issue