pschatzmann / arduino-audio-tools

Arduino Audio Tools (a powerful Audio library not only for Arduino)
GNU General Public License v3.0
1.39k stars 220 forks source link

Use PWM output on RP2040 #1603

Closed pierrotm777 closed 2 months ago

pierrotm777 commented 2 months ago

Problem Description

Try to read a header file and output an audio signal on pins 2 and 3 on a RP2040 Zero

Device Description

Waveshare RP2040 Zero

Sketch

#include "AudioTools.h"
#include "AudioCodecs/CodecMP3Helix.h"
#include "BabyElephantWalk60_mp3.h"

/*
EarPhone    ESP32   RPI Pico    MBED
Left        GPI2       GPI2       GPI2
Right     GPI3     GPIO3      GPI3
GND         GND        GND      GND
To verify check the PIN_PWM_START in AudioConfig.h or you can set the pins by calling setPins() method on the PWMConfig object.
*/
//PWMConfig config;

MemoryStream mp3(BabyElephantWalk60_mp3, BabyElephantWalk60_mp3_len);
PWMAudioOutput out;  // PWM output 
EncodedAudioStream decoded(&out, new MP3DecoderHelix()); // output to decoder
StreamCopy copier(decoded, mp3);    // copy in to out

void setup(){
  Serial.begin(115200);

  AudioLogger::instance().begin(Serial, AudioLogger::Info);  

  // begin processing
  auto cfg = out.defaultConfig();
  Pins pins = {2, 3};
  cfg.setPins(pins);//6 par défaut, voir 
  out.begin(cfg);

  decoded.begin();
}

void loop(){
  if (mp3) {
    copier.copy();
  } else {
    auto info = decoded.decoder().audioInfo();
    LOGI("The audio rate from the mp3 file is %d", info.sample_rate);
    LOGI("The channels from the mp3 file is %d", info.channels);
    out.end();
    stop();
  }
}

Other Steps to Reproduce

My scope see nothing on pin 2 or 3.

What is your development environment

Arduino IDE

I have checked existing issues, discussions and online documentation

pschatzmann commented 2 months ago

What is the logging output ? I am not sure what max sample rate the PWMAudioOutput supports on a RP2040. You might need to resample to a lower rate

pierrotm777 commented 2 months ago

/ Restarting... [I] PWMAudioBase.h : 124 - decimation: 1 [I] PWMAudioBase.h : 87 - sample_rate: 8000 [I] PWMAudioBase.h : 88 - channels: 1 [I] PWMAudioBase.h : 89 - bits_per_sample: 16 [I] PWMAudioBase.h : 90 - buffer_size: 1024 [I] PWMAudioBase.h : 91 - buffer_count: 4 [I] PWMAudioBase.h : 92 - pwm_frequency: 30000 [I] PWMAudioBase.h : 93 - resolution: 8 [I] PWMAudioRP2040.h : 112 - ->wrap_value = 63 [I] PWMAudioRP2040.h : 113 - ->max clock speed = 133000000.000000 [I] PWMAudioRP2040.h : 114 - ->divider = 70.370369 [I] PWMAudioRP2040.h : 115 - ->clock speed = 1890000.000000 [I] PWMAudioRP2040.h : 92 - PWM pin 3 [I] PWMAudioBase.h : 153 - ->Buffer available: 0 [I] PWMAudioBase.h : 154 - ->Buffer available for write: 4096 [I] PWMAudioBase.h : 155 - ->is_timer_started: false [I] C:\tmp\Arduino_Compilateur\arduino-1.8.19\MyArduinoSketch\streams_memory_wav_pwm\streams_memory_wav_pwm.ino : 44 - The audio rate from the wav file is 44100 [I] C:\tmp\Arduino_Compilateur\arduino-1.8.19\MyArduinoSketch\streams_memory_wav_pwm\streams_memory_wav_pwm.ino : 45 - The channels from the wav file is 2 Restarting...

pschatzmann commented 2 months ago

I guess you will need to add a while(!Serial) delay(100); after Serial.begin() to get the full log

pierrotm777 commented 2 months ago

I have tried the merge demo with success.

But PWM return no signal on the pin 3. [I] AudioTypes.h : 127 - sample_rate: 8000 / channels: 1 / bits_per_sample: 16 [I] PWMAudioBase.h : 124 - decimation: 1 [I] PWMAudioBase.h : 132 - ->Allocating new buffer 4 * 1024 bytes [I] Buffers.h : 372 - resize: 4096 [I] PWMAudioBase.h : 87 - sample_rate: 8000 [I] PWMAudioBase.h : 88 - channels: 1 [I] PWMAudioBase.h : 89 - bits_per_sample: 16 [I] PWMAudioBase.h : 90 - buffer_size: 1024 [I] PWMAudioBase.h : 91 - buffer_count: 4 [I] PWMAudioBase.h : 92 - pwm_frequency: 30000 [I] PWMAudioBase.h : 93 - resolution: 8 [I] PWMAudioRP2040.h : 112 - ->wrap_value = 63 [I] PWMAudioRP2040.h : 113 - ->max clock speed = 133000000.000000 [I] PWMAudioRP2040.h : 114 - ->divider = 70.370369 [I] PWMAudioRP2040.h : 115 - ->clock speed = 1890000.000000 [I] PWMAudioRP2040.h : 92 - PWM pin 3 [I] PWMAudioBase.h : 153 - ->Buffer available: 0 [I] PWMAudioBase.h : 154 - ->Buffer available for write: 4096 [I] PWMAudioBase.h : 155 - ->is_timer_started: false [I] C:\tmp\Arduino_Compilateur\arduino-1.8.19\MyArduinoSketch\streams_memory_mp3_pwm\streams_memory_mp3_pwm.ino : 52 - The audio rate from the mp3 file is 2010926598 [I] C:\tmp\Arduino_Compilateur\arduino-1.8.19\MyArduinoSketch\streams_memory_mp3_pwm\streams_memory_mp3_pwm.ino : 53 - The channels from the mp3 file is 55684

pschatzmann commented 2 months ago

There seems to be an issue with the mp3 decoder: mp3 should return true. What happens if you just leave the copy() in the loop ?

pierrotm777 commented 2 months ago

yes, i have a signal now :-)

pierrotm777 commented 2 months ago

[I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops

pschatzmann commented 2 months ago

In the sketch you can replace if (mp3) with if (mp3.available()). Some time ago I have made a generic change that a class needs to have the AudioInfo defined to return true. This is valid for most of the audio classes except the MemoryStream. I committed a correction so that if (mp3) will work again.

pierrotm777 commented 2 months ago

It's OK,

[I] AudioTypes.h : 127 - sample_rate: 8000 / channels: 1 / bits_per_sample: 16 [I] PWMAudioBase.h : 124 - decimation: 1 [I] PWMAudioBase.h : 132 - ->Allocating new buffer 4 * 1024 bytes [I] Buffers.h : 372 - resize: 4096 [I] PWMAudioBase.h : 87 - sample_rate: 8000 [I] PWMAudioBase.h : 88 - channels: 1 [I] PWMAudioBase.h : 89 - bits_per_sample: 16 [I] PWMAudioBase.h : 90 - buffer_size: 1024 [I] PWMAudioBase.h : 91 - buffer_count: 4 [I] PWMAudioBase.h : 92 - pwm_frequency: 30000 [I] PWMAudioBase.h : 93 - resolution: 8 [I] PWMAudioRP2040.h : 112 - ->wrap_value = 63 [I] PWMAudioRP2040.h : 113 - ->max clock speed = 133000000.000000 [I] PWMAudioRP2040.h : 114 - ->divider = 70.370369 [I] PWMAudioRP2040.h : 115 - ->clock speed = 1890000.000000 [I] PWMAudioRP2040.h : 92 - PWM pin 6 [I] PWMAudioBase.h : 153 - ->Buffer available: 0 [I] PWMAudioBase.h : 154 - ->Buffer available for write: 4096 [I] PWMAudioBase.h : 155 - ->is_timer_started: false [I] AudioEncoded.h : 321 - virtual void audio_tools::EncodedAudioOutput::addNotifyAudioChange(audio_tools::AudioInfoSupport&) [I] AudioTimerRP2040.h : 37 - timer time: 125 us [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops [I] StreamCopy.h : 158 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops

pierrotm777 commented 2 months ago

Thanks for your help. One question, i am a naval RC modelist and i should like use your lib for simulate a motor. But i should like that sound change with the motor's speed. Is it possible, if yes whitch demo would be the best for me. I should like to use wav from sd or hearder file (mp3 or wav).

pschatzmann commented 2 months ago

I guess a short WAV file stored in PSRAM will be sufficient since you can endlessly loop over it. To change the pitch you can dynamically resample. or use some pitch shifting

pierrotm777 commented 2 months ago

Thanks again,

I see that

pierrotm777 commented 2 months ago

I try this code:

`#include "AudioTools.h"

include "AudioCodecs/CodecMP3Helix.h"

include "BabyElephantWalk60_mp3.h"

/ EarPhone ESP32 RPI Pico MBED Left GPI2 GPI2 GPI2 Right GPI3 GPIO3 GPI3 GND GND GND GND To verify check the PIN_PWM_START in AudioConfig.h or you can set the pins by calling setPins() method on the PWMConfig object. / //PWMConfig config; MemoryStream mp3(BabyElephantWalk60_mp3, BabyElephantWalk60_mp3_len); PWMAudioOutput out; // PWM output ResampleStream resample(out); EncodedAudioStream decoded(&out, new MP3DecoderHelix()); // output to decoder StreamCopy copier(decoded, mp3); // copy in to out

void setup(){ Serial.begin(115200); while(!Serial) delay(100);

AudioLogger::instance().begin(Serial, AudioLogger::Info);

// define resampling info auto rcfg = resample.defaultConfig(); //rcfg.copyFrom(info); rcfg.step_size = 1.5; resample.begin(rcfg);

// begin processing // Define CSV Output auto config = out.defaultConfig(); config.sample_rate = sample_rate; config.channels = channels; out.begin(config);

decoded.begin(); }

void loop(){ if (mp3.available()) { copier.copy(); } else { auto info = decoded.decoder().audioInfo(); LOGI("The audio rate from the mp3 file is %d", info.sample_rate); LOGI("The channels from the mp3 file is %d", info.channels); out.end(); stop(); } }`

With an error: Compilation error: 'sample_rate' was not declared in this scope; did you mean 'samplerateTab'?

pierrotm777 commented 2 months ago

Idem for channels

pierrotm777 commented 2 months ago

Ok, i have found for sample_rate and channels.

But this code return an error: PitchShiftOutput<int16_t, VariableSpeedRingBuffer> pitchShift(out); <int16_t, VariableSpeedRingBuffer> pitchShift(out); StreamCopy copier(pitchShift, sound); // copies sound to out

Compilation error: expected unqualified-id before '>' token