protection against extreme volume #1634
-
Problem DescriptionI am working on a project, that involves very large amplification of very quiet sounds, using the inmp441. I am creating a device, that people will connect headphones to and walk around to catch sometimes extremely quiet sounds. If however they encounter a loud noise for any reason, i need to limit the output through the headphone amplifier (pcm5102). How can the output volume limited? Device DescriptionESP32 wroom (cheap clone) Sketch#include "AudioTools.h"
AudioInfo info(96000, 2, 32);
I2SStream in;
I2SStream out;
VolumeStream volume(out);
ConverterFillLeftAndRight<int32_t> filler(RightIsEmpty); // fill both channels - or change to RightIsEmpty
StreamCopy copier(volume, in); // copies sound into i2s
// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
// change to Warning to improve the quality
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
// start I2S in
Serial.println("starting I2S...");
auto config_in = in.defaultConfig(RX_MODE);
config_in.copyFrom(info);
config_in.i2s_format = I2S_STD_FORMAT;
config_in.is_master = true;
// config_in.bits_per_sample = 32;
config_in.port_no = 0;
config_in.pin_bck = 14;
config_in.pin_ws = 27;
config_in.pin_data = 12;
// config_in.fixed_mclk = sample_rate * 256
// config_in.pin_mck = 2
in.begin(config_in);
// start I2S out
auto config_out = out.defaultConfig(TX_MODE);
config_out.copyFrom(info);
config_out.port_no = 1;
config_out.pin_bck = 26;
config_out.pin_ws = 25;
config_out.pin_data = 22;
out.begin(config_out);
auto configvol = volume.defaultConfig();
configvol.allow_boost = true;
//configvol.bits_per_sample = 16;
volume.begin(configvol);
volume.setVolume(20.0);
Serial.println("I2S started...");
}
// Arduino loop - copy sound to out
void loop() {
copier.copy(filler);
} Other Steps to ReproduceNo response What is your development environmentNo response I have checked existing issues, discussions and online documentation
|
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 9 replies
-
You can send the output to an MultiOutput instead of the VolumeStream. You can now make the output volume dependent from the input volume.... |
Beta Was this translation helpful? Give feedback.
-
I have renamed the VolumeOutput to VolumeMeter and extended the class, so that it can be used to wrap an input or output class. #include "AudioTools.h"
AudioInfo info(96000, 2, 32);
I2SStream in;
VolumeMeter meter(in);
I2SStream out;
VolumeStream volume(out);
ConverterFillLeftAndRight<int32_t> filler(RightIsEmpty); // fill both channels - or change to RightIsEmpty
StreamCopy copier(volume, meter); // copies sound into i2s This allows you to adjust the volume based on the input w/o any delay... |
Beta Was this translation helpful? Give feedback.
-
Awesome, thanks. I failed to configure the meter with meter.defaultConfig. The Compiler says: `#include "AudioTools.h" AudioInfo info(96000, 2, 32); //volume limiter to avoid extreme loudness // Arduino Setup // start I2S in // start I2S out auto configvol = volume.defaultConfig(); auto cfg_meter = meter.defaultConfig(); volume.setVolume(20.0); Serial.println("I2S started..."); } // Arduino loop - copy sound to out copier.copy(filler); |
Beta Was this translation helpful? Give feedback.
-
just call meter.begin(info); I would try a dynamically calculated volume value or you can just switch off the output (setting the volume to 0) if the input is too high. It should simplify the calculation logic if you configure the VolumeStream to use a linear volume logic. |
Beta Was this translation helpful? Give feedback.
-
Calling meter.begin(info) results in this: I dont yet understand what a linear VolumeStream logic is, but i will try to get that going! |
Beta Was this translation helpful? Give feedback.
-
It compiles using meter.begin(); but the volume is always 0.00 and the logger complains: |
Beta Was this translation helpful? Give feedback.
-
Sorry, i was not on the latest version of your library. It compiles fine now |
Beta Was this translation helpful? Give feedback.
-
Something is still not right. The code runs without error, but the volume value is always zero or "inf" when using volumeDB(). `#include "AudioTools.h" AudioInfo info(96000, 2, 32); //volume limiter to avoid extreme loudness // Arduino Setup //setAudioInfo(info); // start I2S in // start I2S out auto configvol = volume.defaultConfig(); meter.begin(info); volume.setVolume(20.0); Serial.println("I2S started..."); } // Arduino loop - copy sound to out copier.copy(filler); |
Beta Was this translation helpful? Give feedback.
-
But how come its constantly 0.00 with a working i2s stream from an inmp442? |
Beta Was this translation helpful? Give feedback.
You can send the output to an MultiOutput instead of the VolumeStream.
Add the VolumeOutput to measure the received volume and the VolumeStream to regulate the output.
You can now make the output volume dependent from the input volume....