Getting i2s example to work on Lyrat board

audioguy
Posts: 8
Joined: Fri Dec 07, 2018 10:22 am

Getting i2s example to work on Lyrat board

Postby audioguy » Thu Jan 31, 2019 9:56 pm

Hi guys,
Im trying to get the i2s Example form the idf library to work on my lyrat board .
https://www.espressif.com/sites/default ... ide_en.pdf
i have set the i2s ports acording to the ones i got to work in some esp-ADF example, but i dont get
sound on my headphonejack.
here is my code

Code: Select all

/* I2S Example

    This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver
    Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data

    This example code is in the Public Domain (or CC0 licensed, at your option.)

    Unless required by applicable law or agreed to in writing, this
    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "esp_system.h"
#include <math.h>



#define SAMPLE_RATE     (36000)
#define I2S_NUM         (0)
#define WAVE_FREQ_HZ    (100)
#define PI 3.14159265

#define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ)

static void setup_triangle_sine_waves(int bits)
{
    int *samples_data = malloc(((bits+8)/16)*SAMPLE_PER_CYCLE*4);
    unsigned int i, sample_val;
    double sin_float, triangle_float, triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE;
    size_t i2s_bytes_write = 0;

    printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits+8)/16)*SAMPLE_PER_CYCLE*4);

    triangle_float = -(pow(2, bits)/2 - 1);

    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 *= (pow(2, bits)/2 - 1);

        if (bits == 16) {
            sample_val = 0;
            sample_val += (short)triangle_float;
            sample_val = sample_val << 16;
            sample_val += (short) sin_float;
            samples_data[i] = sample_val;
        } else if (bits == 24) { //1-bytes unused
            samples_data[i*2] = ((int) triangle_float) << 8;
            samples_data[i*2 + 1] = ((int) sin_float) << 8;
        } else {
            samples_data[i*2] = ((int) triangle_float);
            samples_data[i*2 + 1] = ((int) sin_float);
        }

    }

    i2s_set_clk(I2S_NUM, SAMPLE_RATE, bits, 2);
    //Using push
    // for(i = 0; i < SAMPLE_PER_CYCLE; i++) {
    //     if (bits == 16)
    //         i2s_push_sample(0, &samples_data[i], 100);
    //     else
    //         i2s_push_sample(0, &samples_data[i*2], 100);
    // }
    // or write
    i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100);

    free(samples_data);
}
void app_main()
{
    //for 36Khz sample rates, we create 100Hz sine wave, every cycle need 36000/100 = 360 samples (4-bytes or 8-bytes each sample)
    //depend on bits_per_sample
    //using 6 buffers, we need 60-samples per buffer
    //if 2-channels, 16-bit each channel, total buffer is 360*4 = 1440 bytes
    //if 2-channels, 24/32-bit each channel, total buffer is 360*8 = 2880 bytes
    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_TX,                                  // Only TX
        .sample_rate = SAMPLE_RATE,
        .bits_per_sample = 16,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
        .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 6,
        .dma_buf_len = 60,
        .use_apll = false,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1                                //Interrupt level 1
    };
   i2s_pin_config_t pin_config = {
        .bck_io_num = 5,
        .ws_io_num = 25,
        .data_out_num = 26,
        .data_in_num = -1};
    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM, &pin_config);

    int test_bits = 16;
    while (1) {
        setup_triangle_sine_waves(test_bits);
        vTaskDelay(5000/portTICK_RATE_MS);
        test_bits += 8;
        if(test_bits > 32)
            test_bits = 16;

    }

}
This is the i2s pinconfig

Code: Select all

  i2s_pin_config_t pin_config = {
        .bck_io_num = 5,
        .ws_io_num = 25,
        .data_out_num = 26,
        .data_in_num = -1};
       
Do i need to do something different if i want to play it on headphones instead of the speaker output of the board?
Thanks in advance :)

User avatar
ESP_krzychb
Posts: 394
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: Getting i2s example to work on Lyrat board

Postby ESP_krzychb » Thu Jan 31, 2019 10:28 pm

audioguy wrote: Do i need to do something different if i want to play it on headphones instead of the speaker output of the board?
Thanks in advance :)
Hi audioguy,

Yes, you need to configure an audio codec chip on board of ESP32-LyraT. Both the headphones and the speaker are connected to this audio chip. Please try respective examples in esp-adf/examples/ that contain a driver for this codec.

audioguy
Posts: 8
Joined: Fri Dec 07, 2018 10:22 am

Re: Getting i2s example to work on Lyrat board

Postby audioguy » Fri Feb 01, 2019 8:19 pm

Thanks for that tip, but I don't really understand what is meant by "configure an audio codec chip" I use the same

Code: Select all

 i2s_config 
as the ESP-adf example which seems to work.
would that be something I need to do in the project setup (makefiles act.) or is there another "driver/i2s. h" I could include somehow?
I would use the ESP-adf pipeline, but I cant get it to play to my headphones and let me see what raw samples its writing to the i2s stream_writer.
I've tried the

Code: Select all

audio_element_set_write_cb(i2s_stream_reader, i2s_input_write_cb, NULL);
function, but I probably overwrite the part calling i2s_write with this callback and I don't know how to prevent it

User avatar
ESP_krzychb
Posts: 394
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: Getting i2s example to work on Lyrat board

Postby ESP_krzychb » Fri Feb 01, 2019 10:12 pm

Hi audioguy,

By "configure an audio codec chip" I meant running https://github.com/espressif/esp-adf/bl ... .c#L56-L57

Just checked play_mp3 example on ESP-LyraT V4.3 and it works properly with the headphones.

Who is online

Users browsing this forum: Google [Bot], sparks and 124 guests