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