Skip to content

Commit 494aaa8

Browse files
committed
Rename VolumeOutput to VolumeMeter
1 parent 7240eca commit 494aaa8

File tree

5 files changed

+173
-110
lines changed

5 files changed

+173
-110
lines changed

examples/examples-stream/streams-generator-volume/streams-generator-volume.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
AudioInfo info(44100, 2, 16);
1111
SineWaveGenerator<int16_t> sineWave(32000); // subclass of SoundGenerator with max amplitude of 32000
1212
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
13-
VolumeOutput out;
14-
StreamCopy copier(out, sound, 1024*2); // copies sound into VolumeOutput
13+
VolumeMeter out;
14+
StreamCopy copier(out, sound, 1024*2); // copies sound into VolumeMeter
1515

1616
// Arduino Setup
1717
void setup(void) {

src/AudioLibs/LEDOutput.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ class LEDOutput {
5656
cfg.update_callback = fftLEDOutput;
5757
}
5858

59-
/// @brief Constructor for VolumeOutput scenario
59+
/// @brief Constructor for VolumeMeter scenario
6060
/// @param vol
61-
LEDOutput(VolumeOutput &vol) {
61+
LEDOutput(VolumeMeter &vol) {
6262
p_vol = &vol;
6363
cfg.update_callback = volumeLEDOutput;
6464
}
@@ -198,7 +198,7 @@ class LEDOutput {
198198
CRGB not_valid;
199199
Vector<CRGB> leds{0};
200200
LEDOutputConfig cfg;
201-
VolumeOutput *p_vol = nullptr;
201+
VolumeMeter *p_vol = nullptr;
202202
FFTDisplay *p_fft = nullptr;
203203
uint64_t count = 0;
204204
int max_column = -1;

src/AudioLibs/LEDOutputUnoR4.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ class LEDOutputUnoR4 {
5151
cfg.update_callback = fftLEDOutputUnoR4;
5252
}
5353

54-
/// @brief Constructor for VolumeOutput scenario
54+
/// @brief Constructor for VolumeMeter scenario
5555
/// @param vol
56-
LEDOutputUnoR4(VolumeOutput &vol) {
56+
LEDOutputUnoR4(VolumeMeter &vol) {
5757
p_vol = &vol;
5858
cfg.update_callback = volumeLEDOutputUnoR4;
5959
}
@@ -89,7 +89,7 @@ class LEDOutputUnoR4 {
8989
return frame[x + (y * cfg.x)];
9090
}
9191

92-
/// Provodes the max magnitude for the VolumeOutput and FFT scenario
92+
/// Provodes the max magnitude for the VolumeMeter and FFT scenario
9393
virtual float getMaxMagnitude() {
9494
// get magnitude from
9595
if (p_vol != nullptr) {
@@ -149,7 +149,7 @@ class LEDOutputUnoR4 {
149149
friend class AudioFFTBase;
150150
LEDOutputUnoR4Config cfg;
151151
FFTDisplay *p_fft = nullptr;
152-
VolumeOutput *p_vol = nullptr;
152+
VolumeMeter *p_vol = nullptr;
153153
uint64_t count = 0;
154154
ArduinoLEDMatrix led_matrix;
155155
Vector<bool> frame{0};

src/AudioTools/AudioOutput.h

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -552,107 +552,6 @@ class OutputMixer : public Print {
552552
}
553553
};
554554

555-
/**
556-
* @brief A simple class to determine the volume
557-
* @ingroup io
558-
* @ingroup volume
559-
* @author Phil Schatzmann
560-
* @copyright GPLv3
561-
*/
562-
class VolumeOutput : public AudioOutput {
563-
public:
564-
void setAudioInfo(AudioInfo info) {
565-
this->info = info;
566-
if (info.channels > 0) {
567-
volumes.resize(info.channels);
568-
volumes_tmp.resize(info.channels);
569-
}
570-
}
571-
572-
size_t write(const uint8_t *data, size_t len) {
573-
clear();
574-
switch (info.bits_per_sample) {
575-
case 16:
576-
updateVolumes<int16_t>(data, len);
577-
break;
578-
case 24:
579-
updateVolumes<int24_t>(data, len);
580-
break;
581-
case 32:
582-
updateVolumes<int32_t>(data, len);
583-
break;
584-
default:
585-
LOGE("Unsupported bits_per_sample: %d", info.bits_per_sample);
586-
break;
587-
}
588-
return len;
589-
}
590-
591-
/// Determines the volume (max amplitude). The range depends on the
592-
/// bits_per_sample.
593-
float volume() { return f_volume; }
594-
595-
/// Determines the volume for the indicated channel. You must call the begin
596-
/// method to define the number of channels
597-
float volume(int channel) {
598-
if (volumes.size() == 0) {
599-
LOGE("begin not called!");
600-
return 0.0f;
601-
}
602-
if (channel >= volumes.size()) {
603-
LOGE("invalid channel %d", channel);
604-
return 0.0f;
605-
}
606-
return volumes[channel];
607-
}
608-
609-
/// Resets the actual volume
610-
void clear() {
611-
f_volume_tmp = 0;
612-
for (int j = 0; j < info.channels; j++) {
613-
volumes_tmp[j] = 0;
614-
}
615-
}
616-
617-
protected:
618-
AudioInfo info;
619-
float f_volume_tmp = 0;
620-
float f_volume = 0;
621-
Vector<float> volumes{0};
622-
Vector<float> volumes_tmp{0};
623-
624-
template <typename T> void updateVolumes(const uint8_t *buffer, size_t size) {
625-
T *bufferT = (T *)buffer;
626-
int samplesCount = size / sizeof(T);
627-
for (int j = 0; j < samplesCount; j++) {
628-
float tmp = abs(static_cast<float>(bufferT[j]));
629-
updateVolume(tmp, j);
630-
}
631-
commit();
632-
}
633-
634-
void updateVolume(float tmp, int j) {
635-
if (tmp > f_volume_tmp) {
636-
f_volume_tmp = tmp;
637-
}
638-
if (volumes_tmp.size() > 0 && info.channels > 0) {
639-
int ch = j % info.channels;
640-
if (tmp > volumes_tmp[ch]) {
641-
volumes_tmp[ch] = tmp;
642-
}
643-
}
644-
}
645-
646-
void commit() {
647-
f_volume = f_volume_tmp;
648-
for (int j = 0; j < info.channels; j++) {
649-
volumes[j] = volumes_tmp[j];
650-
}
651-
}
652-
};
653-
654-
// legacy name
655-
using VolumePrint = VolumeOutput;
656555

657556
/**
658557
* @brief Writes to a preallocated memory

src/AudioTools/AudioStreams.h

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,170 @@ class FilteredStream : public ModifyingStream {
16001600

16011601
};
16021602

1603+
/**
1604+
* @brief A simple class to determine the volume. You can use it as
1605+
* final output or as output or input in your audio chain.
1606+
* @ingroup io
1607+
* @ingroup volume
1608+
* @author Phil Schatzmann
1609+
* @copyright GPLv3
1610+
*/
1611+
class VolumeMeter : public ModifyingStream {
1612+
public:
1613+
VolumeMeter() = default;
1614+
VolumeMeter(AudioStream& as) {
1615+
addNotifyAudioChange(as);
1616+
setStream(as);
1617+
}
1618+
VolumeMeter(AudioOutput& ao) {
1619+
addNotifyAudioChange(ao);
1620+
setOutput(ao);
1621+
}
1622+
VolumeMeter(Print& print) {
1623+
setOutput(print);
1624+
}
1625+
VolumeMeter(Stream& stream) {
1626+
setStream(stream);
1627+
}
1628+
1629+
void setAudioInfo(AudioInfo info) {
1630+
ModifyingStream::setAudioInfo(info);
1631+
if (info.channels > 0) {
1632+
volumes.resize(info.channels);
1633+
volumes_tmp.resize(info.channels);
1634+
}
1635+
}
1636+
1637+
size_t write(const uint8_t *data, size_t len) {
1638+
updateVolumes(data, len);
1639+
size_t result = len;
1640+
if (p_out!=nullptr){
1641+
result = p_out->write(data, len);
1642+
}
1643+
return len;
1644+
}
1645+
1646+
size_t readBytes(uint8_t *data, size_t len){
1647+
if (p_stream==nullptr) return 0;
1648+
size_t result = p_stream->readBytes(data, len);
1649+
updateVolumes((const uint8_t*)data, len);
1650+
return result;
1651+
}
1652+
1653+
/// Determines the volume (max amplitude). The range depends on the
1654+
/// bits_per_sample.
1655+
float volume() { return f_volume; }
1656+
1657+
/// Determines the volume for the indicated channel. You must call the begin
1658+
/// method to define the number of channels
1659+
float volume(int channel) {
1660+
if (volumes.size() == 0) {
1661+
LOGE("begin not called!");
1662+
return 0.0f;
1663+
}
1664+
if (channel >= volumes.size()) {
1665+
LOGE("invalid channel %d", channel);
1666+
return 0.0f;
1667+
}
1668+
return volumes[channel];
1669+
}
1670+
1671+
1672+
/// Volume Ratio: max amplitude is 1.0
1673+
float volumeRatio() { return volume() / NumberConverter::maxValue(info.bits_per_sample);}
1674+
1675+
/// Volume Ratio of indicated channel: max amplitude is 1.0
1676+
float volumeRatio(int channel) { return volume(channel) / NumberConverter::maxValue(info.bits_per_sample);}
1677+
1678+
/// Volume in db: max amplitude is 0
1679+
float volumeDB() { return 20.0f * log10(volumeRatio());}
1680+
1681+
/// Volume of indicated channel in db: max amplitude is 0
1682+
float volumeDB(int channel) { return 20.0f * log10(volumeRatio(channel));}
1683+
1684+
/// Volume in %: max amplitude is 100
1685+
float volumePercent() { return 100.0f * volumeRatio();}
1686+
1687+
/// Volume of indicated channel in %: max amplitude is 100
1688+
float volumePercent(int channel) { return 100.0f * volumeRatio(channel);}
1689+
1690+
1691+
/// Resets the actual volume
1692+
void clear() {
1693+
f_volume_tmp = 0;
1694+
for (int j = 0; j < info.channels; j++) {
1695+
volumes_tmp[j] = 0;
1696+
}
1697+
}
1698+
1699+
void setOutput(Print &out) override {
1700+
p_out = &out;
1701+
}
1702+
void setStream(Stream &io) override {
1703+
p_out = &io;
1704+
p_stream = &io;
1705+
}
1706+
1707+
protected:
1708+
float f_volume_tmp = 0;
1709+
float f_volume = 0;
1710+
Vector<float> volumes{0};
1711+
Vector<float> volumes_tmp{0};
1712+
Print* p_out = nullptr;
1713+
Stream* p_stream = nullptr;
1714+
1715+
void updateVolumes(const uint8_t *data, size_t len){
1716+
clear();
1717+
switch (info.bits_per_sample) {
1718+
case 16:
1719+
updateVolumesT<int16_t>(data, len);
1720+
break;
1721+
case 24:
1722+
updateVolumesT<int24_t>(data, len);
1723+
break;
1724+
case 32:
1725+
updateVolumesT<int32_t>(data, len);
1726+
break;
1727+
default:
1728+
LOGE("Unsupported bits_per_sample: %d", info.bits_per_sample);
1729+
break;
1730+
}
1731+
}
1732+
1733+
template <typename T> void updateVolumesT(const uint8_t *buffer, size_t size) {
1734+
T *bufferT = (T *)buffer;
1735+
int samplesCount = size / sizeof(T);
1736+
for (int j = 0; j < samplesCount; j++) {
1737+
float tmp = abs(static_cast<float>(bufferT[j]));
1738+
updateVolume(tmp, j);
1739+
}
1740+
commit();
1741+
}
1742+
1743+
void updateVolume(float tmp, int j) {
1744+
if (tmp > f_volume_tmp) {
1745+
f_volume_tmp = tmp;
1746+
}
1747+
if (volumes_tmp.size() > 0 && info.channels > 0) {
1748+
int ch = j % info.channels;
1749+
if (tmp > volumes_tmp[ch]) {
1750+
volumes_tmp[ch] = tmp;
1751+
}
1752+
}
1753+
}
1754+
1755+
void commit() {
1756+
f_volume = f_volume_tmp;
1757+
for (int j = 0; j < info.channels; j++) {
1758+
volumes[j] = volumes_tmp[j];
1759+
}
1760+
}
1761+
};
1762+
1763+
// legacy names
1764+
using VolumePrint = VolumeMeter;
1765+
using VolumeOutput = VolumeMeter;
1766+
16031767
#ifdef USE_TIMER
16041768
/**
16051769
* @brief TimerCallbackAudioStream Configuration

0 commit comments

Comments
 (0)