Skip to content

Commit

Permalink
Unsigned support for NumberFormatConverterStreamT
Browse files Browse the repository at this point in the history
  • Loading branch information
pschatzmann committed Nov 16, 2024
1 parent 2d5d09a commit b63db61
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "AudioTools.h"

using target_t = uint32_t; // uint8_t, int8_t, int16_t, uint16_t, int24_t, uint32_t, int32_t, FloatAudio
SineWaveGenerator<int16_t> sineWave; // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
CsvOutput<target_t> out(Serial, sound.audioInfo().channels);
NumberFormatConverterStreamT<int16_t, target_t> nfc(out);
StreamCopy copier(nfc, sound); // copies sound into i2s

// Arduino Setup
void setup(void) {
// Open Serial
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);

nfc.begin();
out.begin();
sineWave.begin();

// Setup sine wave
sineWave.setFrequency(N_B4);
Serial.println("started...");
}

// Arduino loop - copy sound to out
void loop() {
copier.copy();
}
2 changes: 2 additions & 0 deletions src/AudioConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,8 @@ using WiFiServerSecure = BearSSL::WiFiServerSecure;
// select int24 implementation
#include "AudioTools/CoreAudio/AudioBasic/Int24_3bytes_t.h"
#include "AudioTools/CoreAudio/AudioBasic/Int24_4bytes_t.h"
#include "AudioTools/CoreAudio/AudioBasic/FloatAudio.h"

namespace audio_tools {
#ifdef USE_3BYTE_INT24
using int24_t = audio_tools::int24_3bytes_t;
Expand Down
2 changes: 1 addition & 1 deletion src/AudioTools/AudioLibs/FFTDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class FFTDisplay {
}

int getMagnitudeScaled(int x, int max) {
int result = mapFloat(getMagnitude(x), 0, fft_max_magnitude, 0.0f,
int result = mapT<float>(getMagnitude(x), 0, fft_max_magnitude, 0.0f,
static_cast<float>(max));
if (result > max){
LOGD("fft_max_magnitude too small: current value is %f", getMagnitude(x))
Expand Down
2 changes: 1 addition & 1 deletion src/AudioTools/AudioLibs/LEDOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ void fftLEDOutput(LEDOutputConfig *cfg, LEDOutput *matrix) {
/// Default update implementation which provides the fft result as "barchart"
void volumeLEDOutput(LEDOutputConfig *cfg, LEDOutput *matrix) {
float vol = matrix->getMaxMagnitude();
int currY = mapFloat(vol, 0,
int currY = mapT<float>(vol, 0,
cfg->max_magnitude, 0.0f,
static_cast<float>(cfg->y));
matrix->addColumnBar(currY);
Expand Down
2 changes: 1 addition & 1 deletion src/AudioTools/AudioLibs/LEDOutputUnoR4.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void fftLEDOutputUnoR4(LEDOutputUnoR4Config *cfg, LEDOutputUnoR4 *matrix) {
/// Default update implementation which provides the fft result as "barchart"
void volumeLEDOutputUnoR4(LEDOutputUnoR4Config *cfg, LEDOutputUnoR4 *matrix) {
float vol = matrix->getMaxMagnitude();
int currY = mapFloat(vol, 0.0,
int currY = mapT<float>(vol, 0.0,
cfg->max_magnitude, 0.0f,
static_cast<float>(cfg->y));
matrix->addColumnBar(currY);
Expand Down
52 changes: 52 additions & 0 deletions src/AudioTools/CoreAudio/AudioBasic/FloatAudio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once
#include "AudioConfig.h"

namespace audio_tools {

/***
* A simple float number (in the range of -1.0 to 1.0) the supports the conversion to
* it's corresponding scaled int values.
*/

class FloatAudio {
public:
FloatAudio() = default;
FloatAudio(float in) { this->value = in; }

explicit inline operator int8_t() { return value * 127; }

explicit inline operator int16_t() { return value * 32767; }

inline operator float() { return value; }

// explicit inline operator int24_t() {
// return value * 8388607;
// }

explicit inline operator int32_t() { return value * 2147483647; }

protected:
float value = 0.0f;
};

} // namespace audio_tools

#ifdef USE_TYPETRAITS

namespace std {
template <>
class numeric_limits<audio_tools::FloatAudio> {
public:
static audio_tools::FloatAudio lowest() {
return audio_tools::FloatAudio(-1.0f);
};
static audio_tools::FloatAudio min() {
return audio_tools::FloatAudio(-1.0f);
};
static audio_tools::FloatAudio max() {
return audio_tools::FloatAudio(1.0f);
};
};
} // namespace std

#endif
15 changes: 14 additions & 1 deletion src/AudioTools/CoreAudio/AudioBasic/Int24_3bytes_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,17 @@ class int24_3bytes_t {
};


} // namespace audio_tools
} // namespace audio_tools

#ifdef USE_TYPETRAITS

namespace std {
template<> class numeric_limits<audio_tools::int24_3bytes_t> {
public:
static audio_tools::int24_3bytes_t lowest() {return audio_tools::int24_3bytes_t(-0x7FFFFF);};
static audio_tools::int24_3bytes_t min() {return audio_tools::int24_3bytes_t(-0x7FFFFF);};
static audio_tools::int24_3bytes_t max() {return audio_tools::int24_3bytes_t(0x7FFFFF);};
};
}

#endif
15 changes: 14 additions & 1 deletion src/AudioTools/CoreAudio/AudioBasic/Int24_4bytes_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,17 @@ class int24_4bytes_t {
};


} // namespace audio_tools
} // namespace audio_tools

#ifdef USE_TYPETRAITS

namespace std {
template<> class numeric_limits<audio_tools::int24_4bytes_t> {
public:
static audio_tools::int24_4bytes_t lowest() {return audio_tools::int24_4bytes_t(-0x7FFFFF);};
static audio_tools::int24_4bytes_t min() {return audio_tools::int24_4bytes_t(-0x7FFFFF);};
static audio_tools::int24_4bytes_t max() {return audio_tools::int24_4bytes_t(0x7FFFFF);};
};
}

#endif
2 changes: 1 addition & 1 deletion src/AudioTools/CoreAudio/AudioOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ template <typename T> class CsvOutput : public AudioOutput {
for (size_t j = 0; j < frameCount; j++) {
for (int ch = 0; ch < cfg.channels; ch++) {
if (out_ptr != nullptr && data_ptr != nullptr) {
int value = *data_ptr;
T value = *data_ptr;
out_ptr->print(value);
}
data_ptr++;
Expand Down
6 changes: 6 additions & 0 deletions src/AudioTools/CoreAudio/AudioStreamsConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,13 @@ class NumberFormatConverterStreamT : public ReformatBaseStream {
TRACED();
if (p_print == nullptr) return 0;
//addNotifyOnFirstWrite();

#ifdef USE_TYPETRAITS
if (std::is_same<TFrom, TTo>::value) return p_print->write(data, len);
#else
if (sizeof(TFrom) == sizeof(TTo)) return p_print->write(data, len);
#endif

size_t samples = len / sizeof(TFrom);
size_t result_size = 0;
TFrom *data_source = (TFrom *)data;
Expand Down
60 changes: 45 additions & 15 deletions src/AudioTools/CoreAudio/AudioTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include "AudioConfig.h"
#ifdef USE_TYPETRAITS
# include <type_traits>
# include <limits>
#endif

#include "AudioTools/CoreAudio/AudioLogger.h"
#include "AudioTools/CoreAudio/AudioBasic/Collections/Vector.h"

Expand Down Expand Up @@ -291,6 +293,20 @@ class AudioTime {
}
};

/// @brief Similar to Arduino map function but using floats
/// @param x
/// @param in_min
/// @param in_max
/// @param out_min
/// @param out_max
/// @return
template <typename T>
inline T mapT(T x, T in_min, T in_max, T out_min, T out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}



/**
* @brief Converts from a source to a target number with a different type
* @ingroup basic
Expand All @@ -314,15 +330,29 @@ class NumberConverter {

/// provides the biggest number for the indicated type
template <typename T>
static int64_t maxValueT(){
static float maxValueT(){
#ifdef USE_TYPETRAITS
// int24_t uses 4 bytes instead of 3!
return (std::is_same<T, int24_t>::value ) ? 8388607 : maxValue(sizeof(T)*8);
//return (std::is_same<T, int24_t>::value ) ? 8388607 : maxValue(sizeof(T)*8);
return std::numeric_limits<T>::max();
#else
return maxValue(sizeof(T)*8);
#endif
}

template <typename T>
static float minValueT(){
#ifdef USE_TYPETRAITS
// int24_t uses 4 bytes instead of 3!
//return (std::is_same<T, int24_t>::value ) ? 8388607 : maxValue(sizeof(T)*8);
return std::numeric_limits<T>::min();
#else
return -maxValue(sizeof(T)*8);
#endif
}



/// Clips the value to avoid any over or underflows
template <typename T>
static T clipT(float value){
Expand Down Expand Up @@ -372,7 +402,18 @@ class NumberConverter {
template <typename FromT, typename ToT>
static ToT convert(FromT value){
float value1 = value;
return clipT<ToT>(value1 * maxValueT<ToT>() / maxValueT<FromT>());
float minTo = minValueT<ToT>();
float maxTo = maxValueT<ToT>();
float maxFrom = maxValueT<FromT>();
float minFrom = minValueT<FromT>();

if (maxTo - minTo > 1.0f
|| maxFrom - minFrom > 1.0f) {
return mapT<float>(value1, minFrom, maxFrom, minTo, maxTo);
}


return value1 * maxValueT<ToT>() / maxValueT<FromT>();
}

/// Convert an array of int types
Expand All @@ -381,7 +422,7 @@ class NumberConverter {
float factor = static_cast<float>(maxValueT<ToT>()) / maxValueT<FromT>();
float vol_factor = factor * vol;
for (int j=0;j<samples;j++){
to[j] = clipT<ToT>(vol_factor * from[j]);
to[j] = clipT<ToT>(vol * convert<FromT, ToT>(from[j]));
}
}

Expand Down Expand Up @@ -478,17 +519,6 @@ size_t writeSamples(Print* p_out, T* data, int samples, int maxSamples=512){
}


/// @brief Similar to Arduino map function but using floats
/// @param x
/// @param in_min
/// @param in_max
/// @param out_min
/// @param out_max
/// @return
inline float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

/// @brief Mime type for PCM
static const char* mime_pcm = "audio/pcm";

Expand Down
2 changes: 1 addition & 1 deletion src/AudioTools/CoreAudio/ResampleStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class ResampleStream : public ReformatBaseStream {
T val0 = lookup<T>(data, frame_idx0, channel);
T val1 = lookup<T>(data, frame_idx1, channel);

float result = mapFloat(frame_idx, frame_idx0, frame_idx1, val0, val1);
float result = mapT<float>(frame_idx, frame_idx0, frame_idx1, val0, val1);
LOGD("getValue idx: %d:%d / val: %d:%d / %f -> %f", frame_idx0, frame_idx1,
(int)val0, (int)val1, frame_idx, result)
return (float)round(result);
Expand Down
4 changes: 2 additions & 2 deletions src/AudioTools/CoreAudio/VolumeControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ class SimulatedAudioPot : public VolumeControl {
virtual float getVolumeFactor(float volume) {
float result = 0;
if (volume<=x){
result = mapFloat(volume, 0.0, x, 0, y );
result = mapT<float>(volume, 0.0, x, 0, y );
} else {
result = mapFloat(volume, x, 1.0, y, 1.0);
result = mapT<float>(volume, x, 1.0, y, 1.0);
}
return limit(result);
}
Expand Down

0 comments on commit b63db61

Please sign in to comment.