How to play a sine wave sound

dg9ngf
Posts: 40
Joined: Mon Sep 16, 2019 6:49 pm

How to play a sine wave sound

Postby dg9ngf » Fri Sep 20, 2019 7:00 pm

I'm having massive trouble playing a simple sine wave sound through I2S and the DAC. I've attached an audio amplifier and a loudspeaker to pin 25. I try to make it work with Arduino. The problems I have are around understanding the code. The samples I could find just do something but it's not what I need and I can't bring it there. The ESP documentation is very minimal and there are no examples available.

* Why can't bits_per_sample be 8 bits? It shows me an error message for the invalid value.
* What are the specifics of communication_format? What is MSB? Do I need I2S? How are the bits and bytes aligned in the buffer?
* What is dma_buf_count for?
* What length can dma_buf_len be? Can I align it with my sine wave frequency period?

The output I get is either the wrong frequency (I'm at double the programmed frequency now) or total random garbage. This all doesn't make any sense. Also I get all harmonics in the output signal, so it's not a sine wave that's playing. The sound sounds like a square wave but the osciloscope shows a stepped sine wave.

Here's parts of my code. It has grown by trying so it's not in a good shape now. I need a solution to play and stop the sound at any time, starting and stopping at output level 0 (in the range from 0 to 2, instead of -1 to 1, because I don't have negative voltage).

Code: Select all

#include "driver/i2s.h"

int maxPhase = 55;   // Should make 800 Hz, gives 1600 Hz and all of the harmonics as well
// I2S configuration 
int i2s_num = 0;   // I2S port number
i2s_config_t i2s_config =
{
  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
  .sample_rate = 44100,
  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
  .communication_format = I2S_COMM_FORMAT_I2S_MSB,
  .intr_alloc_flags = 0,   // Default interrupt priority
  .dma_buf_count = 8,
  .dma_buf_len = maxPhase * 4,
  .use_apll = false
};
float pi2 = 6.283185;
uint8_t buffer[i2s_config.dma_buf_len];

void setup()
{
  // Initialize I2S with configurations above
  i2s_driver_install((i2s_port_t)i2s_num, &i2s_config, 0, NULL);
  i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);   // Pin 25
  int phase = maxPhase * 0.75;
  while (true)
  {
    int i;
    for (i = 0; i < maxPhase;)
    {
      float rad = (float)phase / maxPhase * pi2;
      uint8_t sample = (sin(rad) + 1) * 30;   // Full amplitude: 127
      buffer[i++] = 0;   // unused right channel
      buffer[i++] = 0;   // unused right channel
      buffer[i++] = sample;   // high byte?
      buffer[i++] = 0;   // low byte (unused)
      phase++;
      if (phase >= maxPhase) phase = 0;
    }

    size_t bytesWritten;
    i2s_write((i2s_port_t)i2s_num, buffer, i2s_config.dma_buf_len * sizeof(uint8_t), &bytesWritten, 0);
  }
}

void loop()
{
}

Who is online

Users browsing this forum: No registered users and 52 guests