GithubHelp home page GithubHelp logo

Comments (22)

patfelst avatar patfelst commented on May 26, 2024 1

I think you mean "cycle" when you say "amplitude", but yes I understand now, thanks again.

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024 1

Yes, you are right. I chose the wrong words.

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024 1

The develop branch has been updated.

  • Changed default tone to pseudo-sine wave.
  • Changed the default output sampling rate to 64kHz.
  • Changed to use linear interpolation when generating waveforms.

Please give it a try.

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024 1

Perhaps there are others if you look for them.

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

@patfelst
Thanks for your report .
Audio support is currently not available. (There are plans to implement it.)
I apologize for the wait, but it is a feature I am eagerly awaiting.

We plan to make it compatible with multiple devices.
Therefore, it is not sufficient to simply copy the Core2 implementation.

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

ok thanks for that, I look forward to it being implemented. I will try a full I2S example.

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

@patfelst
Thank you for your patience.
Today's release of M5Unified v0.0.5 adds the M5.Speaker .
You can now use the tone function as well.
Please try it out !

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

Excellent thank you I will try it out soon!

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

I just tried the tone function and it works great. The examples are well commented - thanks. The virtual channels is a nice addition too. I may try wav file later.

I couldn't work out what this option for tone was:

// tone data (8bit unsigned wav)
  const uint8_t wavdata[64] = { 132,138,143,154,151,139,138,140,144,147,147,147,151,159,184,194,203,222,228,227,210,202,197,181,172,169,177,178,172,151,141,131,107,96,87,77,73,66,42,28,17,10,15,25,55,68,76,82,80,74,61,66,79,107,109,103,81,73,86,94,99,112,121,129 };

  /// Using a single wave of data, you can change the tone.
  M5.Speaker.tone(261.626, 1000, 1, true, wavdata, sizeof(wavdata));
  delay(200);
  M5.Speaker.tone(329.628, 1000, 2, true, wavdata, sizeof(wavdata));
  delay(200);
  M5.Speaker.tone(391.995, 1000, 3, true, wavdata, sizeof(wavdata));
  delay(200);

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

The default behavior of the tone function is to output a square wave, but you can also specify any waveform data to play a sound.
The 64-byte array in that example is a small wav data for a single amplitude created by a software synthesizer.

  M5.Speaker.tone( 261.626     // tone frequency (Hz)
                 , 1000        // tone duration (msec)
                 , 1           // virtual channel number. (0~7), (default = automatically selected)
                 , true        // true=start a new output without waiting for the current one to finish.
                 , wav         // Single amplitude audio data. 8bit unsigned wav.
                 , sizeof(wav) // size of wav_data.
                 , false       // true=data is stereo / false=data is mono.
                 );

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

This is great, so I could define a sine or sawtooth or other waveform! I might have to study your source code to see if I fully understand, but what is the assumed sampling rate, or period of the waveform data? Or is the waveform data applied evenly over the tone duration?

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

The sampling rate and repeat count is calculated based on the length of the wav data.

https://github.com/m5stack/M5Unified/blob/0.0.5/src/utility/Speaker_Class.cpp#L409-L412

ex 1:
args:
  data length = 2 Bytes
  tone freq = 440 Hz
  duration = 500 msec

result:
  sampling_rate = 2 Bytes * 440 Hz = 880 Hz.
  repeat_count = 500 msec * 440 Hz / 1000 = 220 time
ex 2:
args:
  data length = 1000 Bytes
  tone freq = 440 Hz
  duration = 2000 msec

result:
  sampling_rate = 1000 Bytes * 440 Hz = 440000 Hz.
  repeat_count = 2000 msec * 440 Hz / 1000 = 880 time

In other words, whether the length of the data is 2 or 1000, it will be considered as one amplitude and the tone will be played back.

It is important to note that if the waveform data contains multiple amplitudes, it will be played back at a higher pitch than expected, so be sure to specify data for a single amplitude.
If you want to specify data for 10 amplitudes, you need to set the playback frequency to one tenth.

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

Hi there again, I hope this is my mistake, but there seems to be a problem with the tone frequency, it alsmost sounds like two channels are playing, as I hear one frequency increasing as expected, but another channel rises, and then goes lower at about 4,000Hz. Please listen to the video.

This is the code in setup() some code after M5.begin(cfg):

  M5.Speaker.begin();
  M5.Speaker.setVolume(64);

  for (int i = 500; i < 8000; i += 500) {
    M5.Speaker.tone(i, 1000, 0, true);
    Serial.printf("Freq = %d Hz\n", i);
    while (M5.Speaker.isPlaying()) { delay(1); }  // Wait for the output to finish.
    delay(100);
  }
  /// stop output sound.
  M5.Speaker.stop();
M5Unified.tone.frequency.mov

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

@patfelst
I don't think it's another channel being played. I think it is due to the relationship between the harmonic components of the square wave and the output frequency.
The overtones beyond the Nyquist frequency fold back into the audible range and are heard as swells.

By changing the waveform to a sin wave or increasing the output sampling rate, this sound can be suppressed, but it is difficult to eliminate it completely.

Would it be better to change the default tone to sin wave ?

#include <M5Unified.h>

const uint8_t sin_wav[] = { 128, 152, 176, 198, 218, 234, 245, 253, 255, 253, 245, 234, 218, 198, 176, 152, 128, 103, 79, 57, 37, 21, 10, 2, 0, 2, 10, 21, 37, 57, 79, 103 };

void setup(void)
{
  M5.begin();
  M5.Display.setFont(&fonts::DejaVu18);

  { /// By changing the sampling rate, the fold noise changes.
    auto spk_cfg = M5.Speaker.config();
//  spk_cfg.sample_rate =  50000;
    spk_cfg.sample_rate =  96000;
//  spk_cfg.sample_rate = 100000;
//  spk_cfg.sample_rate = 144000;
//  spk_cfg.sample_rate = 192000;
//  spk_cfg.sample_rate = 200000;
    M5.Speaker.config(spk_cfg);
  }
  M5.Speaker.begin();
  M5.Speaker.setVolume(64);
}

void loop(void)
{
  delay(500);
  for (int i = 500; i < 8000; i += 1) {
//  M5.Speaker.tone(i, 1000, 0, true);
    M5.Speaker.tone(i, 1000, 0, true, sin_wav, sizeof(sin_wav));
    M5.Display.setCursor(0, M5.Display.height() / 2);
    M5.Display.printf("Freq = %d Hz        ", i);
    delay(1);
  }

  delay(500);
  for (int i = 500; i < 8000; i += 500) {
//  M5.Speaker.tone(i, 500, 0, true);
    M5.Speaker.tone(i, 500, 0, true, sin_wav, sizeof(sin_wav));
    M5.Display.setCursor(0, M5.Display.height() / 2);
    M5.Display.printf("Freq = %d Hz        ", i);
    while (M5.Speaker.isPlaying()) { delay(1); }
  }
}

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

wow @lovyan03 this is really interesting - square wave harmonics, I would not have thought of that!

Is it a processor overhead to use those higher output frequencies (sampling rate)? I'm assuming not. It is much better with the sine wave, and at 100,000 output sampling rate, it is great for my purpose. So I agree, make sine wave the default tone.

I do still hear some harmonics at a few higher frequences (>6kHz) but for my purposes of creating warning tones, it is much better now. Perhaps I should just use proper sampled sound effects. Is there a web site for converting a wav file to c++ array?

Thanks for your help, much appreciated!

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

Something strange just happened, I was experimenting with the master volume, and my 10x RGB LEDs driven with Fastled library changed to an unexpected colour (I set purple, it went light blue). I found that if I do not set the master volume, this does not happen (LED is correct colour). Also if I put in a delay as low as 1ms just after setting the LED colour, the problem also does not happen.

If I use M5.Speaker.setAllChannelVolume() the LED problem also does not occur.

If I don't put in a delay, and see the wrong colour, after making a tone, some time later in the main loop, when I set a new colour, the LEDs return to the correct colour again.

Any idea what is going on here? I'd rather not leave an enexplained delay in my code!

Setup() code is:

#define LED_COUNT 10
#define LED_PIN   25

void setup(void) {
  // setup M5Unified LCD, and create a bunch of sprites

  // Setup 10x RGB LED string
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_COUNT);
  set_rgb_led(led_brightness_percent, CRGB::Fuchsia); // Fuchsia is purple / pink colour
  delay(1); // Needed to prevent `M5.Speaker.setVolume()` from changing LED colour to light blue. No idea why?

  auto spk_cfg = M5.Speaker.config();
  spk_cfg.sample_rate = 192000; // M5 Unified default = 44,100
  M5.Speaker.config(spk_cfg);

  M5.Speaker.begin();
  // M5.Speaker.setVolume((30 * 255) / 100);  // Set volume to 30% - causes LED to be light blue colour?
  M5.Speaker.setAllChannelVolume((30 * 255) / 100);  // Set volume to 30% - LED is correct colour

  const uint8_t sin_wav[] = {128, 152, 176, 198, 218, 234, 245, 253, 255, 253, 245, 234, 218, 198, 176, 152, 128, 103, 79, 57, 37, 21, 10, 2, 0, 2, 10, 21, 37, 57, 79, 103};
  // const uint16_t C4 = 261.626;
  // const uint16_t E4 = 329.628;
  // const uint16_t G4 = 391.995;
  const uint16_t C6 = 1046.50;
  // const uint16_t E6 = 1318.51;
  const uint16_t G6 = 1567.98;
  uint16_t chord_duration_ms = 200;
  M5.Speaker.tone(C6, chord_duration_ms, 0, false, sin_wav, sizeof(sin_wav));
  M5.Speaker.tone(G6, chord_duration_ms, 1, false, sin_wav, sizeof(sin_wav));

  // other setup stuff
}

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

@patfelst
umm... The code you provided is incomplete, so I cannot reproduce the issue.
Please provide us with buildable code.

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

@patfelst umm... The code you provided is incomplete, so I cannot reproduce the issue. Please provide us with buildable code.

sorry about that.

I prepared some buildable code for you with the develop branch, but I can't reproduce the Fastled problem any more. So please ignore that comment above.

Also, the develop branch is great. The default settings sound much better. To be clear, I didn't specify the sin_wave[] array either.

from m5unified.

patfelst avatar patfelst commented on May 26, 2024

I should have said thank you once again for your work on this library.

I still have a question about how to generate c++ arrays from audio files. Is there an online tool? Or a command line tool for PC's. Thanks

from m5unified.

chuck808 avatar chuck808 commented on May 26, 2024

I'm a little late to this thread, but I probably need to be able to produce Tones using the M5Core2 library as I need the Accelerometer also. I have got the Tones working with the M5Unified.

Is there any way to achieve this with M5Core2.h?

from m5unified.

lovyan03 avatar lovyan03 commented on May 26, 2024

Hello, @chuck808
M5Unified's IMU cannot meet your request?

Since M5Core2.h does not have a tone function, it basically has to send sound data to I2S by itself.

from m5unified.

chuck808 avatar chuck808 commented on May 26, 2024

Hello @lovyan03,

Thank you for the quick reply. I was afraid of that :). It seems a bit odd that M5Core2.h doesn't have a tone function, but I suppose I can use the Speak example to achieve my needs, just a pain to have to create the wav's :(

I am also trying to recreate a 3-axis acceleration monitor (graph display) script from here, but it says it can't compile for Core2 when using the M5Unified.h library.

Regards

from m5unified.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.