parent
291f97c4ba
commit
dbf79e1d1e
@ -0,0 +1,90 @@ |
|||||||
|
/*
|
||||||
|
* This is a direct translation of the Teensy Audio Library Peak Analyze |
||||||
|
* to use floating point f32. This is intended to be compatible with |
||||||
|
* Chip Audette's floating point libraries. |
||||||
|
* Bob Larkin 23 April 2020 - AudioAnalyze_Peak_F32 |
||||||
|
* |
||||||
|
* Regard the Paul Stoffregen copyright and licensing: |
||||||
|
* |
||||||
|
* Audio Library for Teensy 3.X |
||||||
|
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com |
||||||
|
* |
||||||
|
* Development of this audio library was funded by PJRC.COM, LLC by sales of |
||||||
|
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop |
||||||
|
* open source software by purchasing Teensy or other PJRC products. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice, development funding notice, and this permission |
||||||
|
* notice shall be included in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
* THE SOFTWARE. |
||||||
|
*/ |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
#include "analyze_peak_f32.h" |
||||||
|
|
||||||
|
void AudioAnalyzePeak_F32::update(void) { |
||||||
|
audio_block_f32_t *blockIn; |
||||||
|
const float32_t *p, *end; |
||||||
|
float32_t min, max, d; |
||||||
|
|
||||||
|
blockIn = AudioStream_F32::receiveReadOnly_f32(); |
||||||
|
if (!blockIn) { |
||||||
|
if(errorPrint) Serial.println("AN_PEAK ERR: No input memory"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Variable just_read allows both read() and readPeakToPeak() to be used
|
||||||
|
if(just_read) { |
||||||
|
// Start new collection of min_sample and max_sample
|
||||||
|
min_sample = blockIn->data[0]; |
||||||
|
max_sample = blockIn->data[0]; |
||||||
|
} |
||||||
|
|
||||||
|
p = blockIn->data; |
||||||
|
end = p + block_size; |
||||||
|
min = min_sample; |
||||||
|
max = max_sample; |
||||||
|
do { |
||||||
|
d=*p++; |
||||||
|
if (d<min) min=d; |
||||||
|
if (d>max) max=d; |
||||||
|
} while (p < end); |
||||||
|
min_sample = min; |
||||||
|
max_sample = max; |
||||||
|
new_output = true; // Tell available() that data is available
|
||||||
|
AudioStream_F32::release(blockIn); |
||||||
|
} |
||||||
|
|
||||||
|
float AudioAnalyzePeak_F32::read(void) { |
||||||
|
// Tell update to start new
|
||||||
|
just_read = true; |
||||||
|
__disable_irq(); |
||||||
|
float32_t min = min_sample; |
||||||
|
float32_t max = max_sample; |
||||||
|
__enable_irq(); |
||||||
|
min = abs(min); |
||||||
|
max = abs(max); |
||||||
|
if (min > max) max = min; |
||||||
|
return max; |
||||||
|
} |
||||||
|
|
||||||
|
float AudioAnalyzePeak_F32:: readPeakToPeak(void) { |
||||||
|
just_read = true; |
||||||
|
__disable_irq(); |
||||||
|
float32_t min = min_sample; |
||||||
|
float32_t max = max_sample; |
||||||
|
__enable_irq(); |
||||||
|
return (max - min); |
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
/* This is a direct translation of the Teensy Audio Library Peak Analyze
|
||||||
|
* to use floating point f32. This is intended to be compatible with |
||||||
|
* Chip Audette's floating point libraries. |
||||||
|
* Bob Larkin 24 April 2020 - AudioAnalyze_Peak_F32 |
||||||
|
* |
||||||
|
* Regard the copyright and the licensing: |
||||||
|
* Audio Library for Teensy 3.X |
||||||
|
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com |
||||||
|
* |
||||||
|
* Development of this audio library was funded by PJRC.COM, LLC by sales of |
||||||
|
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop |
||||||
|
* open source software by purchasing Teensy or other PJRC products. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice, development funding notice, and this permission |
||||||
|
* notice shall be included in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
* THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Input is a block of f32 numbers. Output is the peak signal amplitude
|
||||||
|
* calculated over multiple blocks. Useful for audio level response projects, |
||||||
|
* and general troubleshooting. |
||||||
|
*
|
||||||
|
* Status: Tested 3.6 and 4.0, no known bugs |
||||||
|
* Functions: |
||||||
|
* available(); Returns true if new peak data is available. |
||||||
|
* read(); Read the new peak value. |
||||||
|
* Return is absolute + or - peak value in float. |
||||||
|
* readPeakToPeak(); Same, but the differnce in + and - values. |
||||||
|
* Examples: |
||||||
|
* TestPeakRMS.ino |
||||||
|
* Similar: File > Examples > Audio > Analysis > PeakAndRMSMeterStereo |
||||||
|
* Time: Measured Teensy 3.6 time for the update() is 10 microseconds, |
||||||
|
* for 128 block size. For Teensy 4.0 this is about 4 mcroseconds. |
||||||
|
* |
||||||
|
* The two variables, min_sample and max_sample, are checked until |
||||||
|
* an available() takes place. This is fine if the statistics of the input data are |
||||||
|
* stationary, i.e., not changing with time. But, if the process is not |
||||||
|
* stationary, be aware and do available() & read() at appropriate times. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef analyze_peak_f32_h_ |
||||||
|
#define analyze_peak_f32_h_ |
||||||
|
|
||||||
|
#include "Arduino.h" |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
|
||||||
|
class AudioAnalyzePeak_F32 : public AudioStream_F32 { |
||||||
|
//GUI: inputs:1, outputs:0 //this line used for automatic generation of GUI node
|
||||||
|
//GUI: shortName: AnalyzePeak
|
||||||
|
public: |
||||||
|
AudioAnalyzePeak_F32(void) : AudioStream_F32(1, inputQueueArray_f32) { |
||||||
|
} |
||||||
|
// Alternate specification of block size. Sample rate does not apply for analyze_peak
|
||||||
|
AudioAnalyzePeak_F32(const AudioSettings_F32 &settings) : AudioStream_F32(1, inputQueueArray_f32) { |
||||||
|
block_size = settings.audio_block_samples; |
||||||
|
} |
||||||
|
|
||||||
|
bool available(void) { // true means read() or readPeakToPeak() will return a new value
|
||||||
|
__disable_irq(); |
||||||
|
bool flag = new_output; |
||||||
|
if (flag) new_output = false; |
||||||
|
__enable_irq(); |
||||||
|
return flag; |
||||||
|
} |
||||||
|
|
||||||
|
void showError(uint16_t e) { // 0/1 Disables/Enables printing of update() errors
|
||||||
|
errorPrint = e; |
||||||
|
} |
||||||
|
|
||||||
|
virtual void update(void); |
||||||
|
float32_t read(void); |
||||||
|
float32_t readPeakToPeak(void); |
||||||
|
|
||||||
|
private: |
||||||
|
audio_block_f32_t *inputQueueArray_f32[1]; |
||||||
|
uint16_t block_size = AUDIO_BLOCK_SAMPLES; |
||||||
|
volatile bool new_output = false; |
||||||
|
volatile bool just_read = true; |
||||||
|
float32_t min_sample; |
||||||
|
float32_t max_sample; |
||||||
|
|
||||||
|
// Control error printing in update(). Should never be enabled
|
||||||
|
// until all audio objects have been initialized.
|
||||||
|
// Only used as 0 or 1 now, but 16 bits are available.
|
||||||
|
uint16_t errorPrint = 0; |
||||||
|
}; |
||||||
|
#endif |
||||||
|
|
||||||
|
|
@ -0,0 +1,68 @@ |
|||||||
|
/*
|
||||||
|
* This is a direct translation of the Teensy Audio Library RMS Analyze |
||||||
|
* to use floating point f32. This is intended to be compatible with |
||||||
|
* Chip Audette's floating point libraries. |
||||||
|
* Bob Larkin 23 April 2020 - AudioAnalyze_RMS_F32 |
||||||
|
* |
||||||
|
* Regard the Paul Stoffregen copyright and licensing: |
||||||
|
* |
||||||
|
* Audio Library for Teensy 3.X |
||||||
|
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com |
||||||
|
* |
||||||
|
* Development of this audio library was funded by PJRC.COM, LLC by sales of |
||||||
|
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop |
||||||
|
* open source software by purchasing Teensy or other PJRC products. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice, development funding notice, and this permission |
||||||
|
* notice shall be included in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
* THE SOFTWARE. |
||||||
|
*/ |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
#include "analyze_rms_f32.h" |
||||||
|
|
||||||
|
void AudioAnalyzeRMS_F32::update(void) { |
||||||
|
float32_t *p; |
||||||
|
float32_t sum = 0.0f; |
||||||
|
audio_block_f32_t *blockIn; |
||||||
|
|
||||||
|
blockIn = AudioStream_F32::receiveReadOnly_f32(); |
||||||
|
if (!blockIn) { |
||||||
|
if(errorPrint) Serial.println("AN_RMS ERR: No input"); |
||||||
|
// count++; // Why ++? We are not adding to accum
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
p = blockIn->data; |
||||||
|
// Find sum of powers for full vector, see
|
||||||
|
// https://github.com/ARM-software/CMSIS/blob/master/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c
|
||||||
|
// arguments are (source vector 1, source vector 2, number of samples, pointer to f32 out)
|
||||||
|
arm_dot_prod_f32(p, p, block_size, &sum); |
||||||
|
accum += (double)sum; |
||||||
|
count++; |
||||||
|
AudioStream_F32::release(blockIn); |
||||||
|
} |
||||||
|
|
||||||
|
float AudioAnalyzeRMS_F32::read(void) { |
||||||
|
__disable_irq(); |
||||||
|
// It is safe to convert back to float now
|
||||||
|
float32_t sum = (float32_t)accum; |
||||||
|
accum = 0.0; |
||||||
|
float32_t num = (float32_t)count; |
||||||
|
count = 0; |
||||||
|
__enable_irq(); |
||||||
|
return sqrtf(sum / (num * (float32_t)block_size)); |
||||||
|
} |
@ -0,0 +1,105 @@ |
|||||||
|
/* This is a direct translation of the Teensy Audio Library RMS Analyze
|
||||||
|
* to use floating point f32. This is intended to be compatible with |
||||||
|
* Chip Audette's floating point libraries. |
||||||
|
* Bob Larkin 23 April 2020 - AudioAnalyze_RMS_F32 |
||||||
|
* |
||||||
|
* Regard the copyright and licensing: |
||||||
|
* Audio Library for Teensy 3.X |
||||||
|
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com |
||||||
|
* |
||||||
|
* Development of this audio library was funded by PJRC.COM, LLC by sales of |
||||||
|
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop |
||||||
|
* open source software by purchasing Teensy or other PJRC products. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice, development funding notice, and this permission |
||||||
|
* notice shall be included in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
* THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Input is a block of f32 numbers. Output is the signal RMS amplitude
|
||||||
|
* calculated over multiple blocks. Useful for audio level response projects, |
||||||
|
* and general troubleshooting. |
||||||
|
*
|
||||||
|
* Status: Tested 3.6 and T4.0 No known bugs. |
||||||
|
* Functions: |
||||||
|
* available(); Returns true if new RMS data is available. |
||||||
|
* read(); Read the new RMS value. Return is rms value in float. |
||||||
|
* Examples:
|
||||||
|
* TestPeakRMS.ino |
||||||
|
* Similar: File > Examples > Audio > Analysis > PeakAndRMSMeterStereo |
||||||
|
* Time: Measured time for the update of F32 RMS is 7 microseconds |
||||||
|
* for 128 block size. |
||||||
|
* |
||||||
|
* The average "power" is found by squaring the sample values, adding them |
||||||
|
* together and dividing by the number of samples. The RMS value is a "voltage" |
||||||
|
* found by taking the square root of the power. This is in DSP lingo, and |
||||||
|
* the units are vague. But, since usually, only relative values are important, |
||||||
|
* the units will cancel out! |
||||||
|
* |
||||||
|
* The two variables, accum and count, keep adding to the power sum until |
||||||
|
* a read() takes place. This is fine if the statistics of the input data are |
||||||
|
* stationary, i.e., not changing with time. But, if the process is not |
||||||
|
* stationary, be aware and do read() at appropriate times. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef analyze_rms_f32_h_ |
||||||
|
#define analyze_rms_f32_h_ |
||||||
|
|
||||||
|
#include "Arduino.h" |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
|
||||||
|
class AudioAnalyzeRMS_F32 : public AudioStream_F32 { |
||||||
|
//GUI: inputs:1, outputs:0 //this line used for automatic generation of GUI node
|
||||||
|
//GUI: shortName: AnalyzeRMS
|
||||||
|
public: |
||||||
|
AudioAnalyzeRMS_F32(void) : AudioStream_F32(1, inputQueueArray_f32) { |
||||||
|
// default values from initialization below
|
||||||
|
} |
||||||
|
// Alternate specification of block size. Sample rate does not apply for analyze_rms
|
||||||
|
AudioAnalyzeRMS_F32(const AudioSettings_F32 &settings) : AudioStream_F32(1, inputQueueArray_f32) { |
||||||
|
block_size = settings.audio_block_samples; |
||||||
|
} |
||||||
|
|
||||||
|
bool available(void) { |
||||||
|
return count > 0; |
||||||
|
} |
||||||
|
|
||||||
|
void showError(uint16_t e) { // 0/1 Disables/Enables printing of update() errors
|
||||||
|
errorPrint = e; |
||||||
|
} |
||||||
|
|
||||||
|
float read(void); |
||||||
|
|
||||||
|
virtual void update(void); |
||||||
|
|
||||||
|
private: |
||||||
|
audio_block_f32_t *inputQueueArray_f32[1]; |
||||||
|
uint16_t block_size = AUDIO_BLOCK_SAMPLES; |
||||||
|
// double for accum is very safe, but needed? Well, power dynamic Range x 1 sec of data =~ 1E7 x 4E4 = 4E11
|
||||||
|
// whereas float range for positive numbers is 2^23 =~ 1E7 so double is easily justified for accuracy.
|
||||||
|
// The timing 7 microseconds per 128, includes using double for accum, so the price is reasonable.
|
||||||
|
double accum = 0.0; |
||||||
|
uint32_t count = 0; |
||||||
|
|
||||||
|
// Control error printing in update(). Should never be enabled
|
||||||
|
// until all audio objects have been initialized.
|
||||||
|
// Only used as 0 or 1 now, but 16 bits are available.
|
||||||
|
uint16_t errorPrint = 0; |
||||||
|
}; |
||||||
|
#endif |
||||||
|
|
||||||
|
|
@ -0,0 +1,103 @@ |
|||||||
|
/* SignalNoise_float.ino Bob Larkin 19 June 2020
|
||||||
|
* |
||||||
|
* Generate White Noise, Pink Noise, Gaussian White Noise and a Sine Wave |
||||||
|
* Combine all four in a adding "mixer", send to Codec and to peak/rms. |
||||||
|
* |
||||||
|
* Following is for all objects enabled (amplitudes non-zero) |
||||||
|
* T3.6 Processor load, measured: 10.6% |
||||||
|
* T4.0 Processor load, measured: 3.2% |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "Audio.h" |
||||||
|
#include "OpenAudio_ArduinoLibrary.h" |
||||||
|
|
||||||
|
// To work with T4.0 the I2S routine outputs 16-bit integer (I16). Then
|
||||||
|
// use Audette I16 to F32 convert. Same below for output, in reverse.
|
||||||
|
AudioInputI2S in1; |
||||||
|
AudioSynthNoisePink_F32 pink1; |
||||||
|
AudioSynthNoiseWhite_F32 white1; |
||||||
|
AudioSynthGaussian_F32 gaussian1; |
||||||
|
AudioSynthWaveformSine_F32 sine1; |
||||||
|
AudioMixer4_F32 sum1; |
||||||
|
AudioConvert_F32toI16 cnvrt1; // Left
|
||||||
|
AudioConvert_F32toI16 cnvrt2; // Right
|
||||||
|
AudioOutputI2S i2sOut; |
||||||
|
AudioAnalyzePeak_F32 peak1; |
||||||
|
AudioAnalyzeRMS_F32 rms1; |
||||||
|
AudioControlSGTL5000 codec; |
||||||
|
AudioConnection_F32 connect1(pink1, 0, sum1, 0); |
||||||
|
AudioConnection_F32 connect2(white1, 0, sum1, 1); |
||||||
|
AudioConnection_F32 connect3(gaussian1, 0, sum1, 2); |
||||||
|
AudioConnection_F32 connect4(sine1, 0, sum1, 3); |
||||||
|
AudioConnection_F32 connect6(sum1, 0, cnvrt1, 0); // Out to the CODEC left
|
||||||
|
AudioConnection_F32 connect7(sum1, 0, cnvrt2, 0); // and right
|
||||||
|
AudioConnection_F32 connect8(sum1, 0, peak1, 0); |
||||||
|
AudioConnection_F32 connect9(sum1, 0, rms1, 0); |
||||||
|
AudioConnection conI16_2(cnvrt1, 0, i2sOut, 0); // DAC L
|
||||||
|
AudioConnection conI16_3(cnvrt2, 0, i2sOut, 1); // DAC R
|
||||||
|
|
||||||
|
|
||||||
|
// ********* Mini Control Panel *********
|
||||||
|
// Off/On switches, 0 for off, 1 for on
|
||||||
|
#define WHITE 0 |
||||||
|
#define PINK 0 |
||||||
|
#define GAUSSIAN 1 |
||||||
|
#define SINE 1 |
||||||
|
|
||||||
|
int gainControlDB = -35; // Set gain in dB.
|
||||||
|
// *****************************************
|
||||||
|
|
||||||
|
void setup(void) { |
||||||
|
float32_t gain; |
||||||
|
AudioMemory(5); |
||||||
|
AudioMemory_F32(8); |
||||||
|
|
||||||
|
for (int i=0; i<4; i++) sum1.gain(i, 0.0); // All off
|
||||||
|
|
||||||
|
Serial.begin(1); delay(1000); |
||||||
|
|
||||||
|
gain = powf( 10.0f, (gainControlDB/20.0f) ); |
||||||
|
white1.amplitude(0.5f); |
||||||
|
gaussian1.amplitude(0.5f); |
||||||
|
sine1.frequency(1000.0f); |
||||||
|
sine1.amplitude(0.2f); |
||||||
|
codec.enable(); |
||||||
|
delay(10); |
||||||
|
if(PINK) sum1.gain(0, gain); |
||||||
|
else sum1.gain(0, 0.0f); |
||||||
|
|
||||||
|
if(WHITE) sum1.gain(1, gain); |
||||||
|
else sum1.gain(1, 0.0f); |
||||||
|
|
||||||
|
if(GAUSSIAN) sum1.gain(2, gain); |
||||||
|
else sum1.gain(2, 0.0f); |
||||||
|
|
||||||
|
if(SINE) sum1.gain(3, gain); |
||||||
|
else sum1.gain(3, 0.0f); |
||||||
|
} |
||||||
|
|
||||||
|
void loop(void) { |
||||||
|
// Here is where the adjustment of the volume control could go.
|
||||||
|
// And anything else that needs regular attention, other
|
||||||
|
// than the audio stream.
|
||||||
|
|
||||||
|
if (rms1.available() ) {Serial.print("RMS ="); Serial.println(rms1.read(), 6);} |
||||||
|
if (peak1.available() ) {Serial.print("P-P ="); Serial.println(peak1.readPeakToPeak(), 6);} |
||||||
|
Serial.print("CPU: Percent Usage, Max: "); |
||||||
|
Serial.print(AudioProcessorUsage()); |
||||||
|
Serial.print(", "); |
||||||
|
Serial.print(AudioProcessorUsageMax()); |
||||||
|
Serial.print(" "); |
||||||
|
Serial.print("Int16 Memory: "); |
||||||
|
Serial.print(AudioMemoryUsage()); |
||||||
|
Serial.print(", "); |
||||||
|
Serial.print(AudioMemoryUsageMax()); |
||||||
|
Serial.print(" "); |
||||||
|
Serial.print("Float Memory: "); |
||||||
|
Serial.print(AudioMemoryUsage_F32()); |
||||||
|
Serial.print(", "); |
||||||
|
Serial.println(AudioMemoryUsageMax_F32()); |
||||||
|
Serial.println(); |
||||||
|
|
||||||
|
delay(1000); |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
/*
|
||||||
|
* synth_GaussianWhiteNoise_F32.cpp |
||||||
|
* by Bob Larkin W7PUA 15 June 2020 |
||||||
|
*
|
||||||
|
* Created: Chip Audette, OpenAudio, Feb 2017 |
||||||
|
|
||||||
|
|
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice, development funding notice, and this permission |
||||||
|
* notice shall be included in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
* THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "synth_GaussianWhiteNoise_F32.h" |
||||||
|
|
||||||
|
// Park-Miller-Carta Pseudo-Random Number Generator
|
||||||
|
// http://www.firstpr.com.au/dsp/rand31/
|
||||||
|
|
||||||
|
void AudioSynthGaussian_F32::update(void) |
||||||
|
{ |
||||||
|
audio_block_f32_t *blockOut; |
||||||
|
uint32_t it; |
||||||
|
float32_t rdev = 0.0f; |
||||||
|
float32_t* pd; |
||||||
|
|
||||||
|
if (sd < 0.01f) { |
||||||
|
return; // Not enabled
|
||||||
|
} |
||||||
|
|
||||||
|
#if TEST_TIME_GWN |
||||||
|
if (iitt++ >1000000) iitt = -10; |
||||||
|
uint32_t t1, t2; |
||||||
|
t1 = tElapse; |
||||||
|
#endif |
||||||
|
blockOut = AudioStream_F32::allocate_f32(); |
||||||
|
if (!blockOut) { |
||||||
|
if(errorPrint) Serial.println("GWN-ERR: No output memory"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
pd = &blockOut->data[0]; // Pointer to write data
|
||||||
|
/* The "Even Quicker" uniform random sample generator from D. E. Knuth and
|
||||||
|
* H. W. Lewis and described in Chapter 7 of "Numerical Receipes in C", |
||||||
|
* 2nd ed, with the comment "this is about as good as any 32-bit linear |
||||||
|
* congruential generator, entirely adequate for many uses." |
||||||
|
*/ |
||||||
|
for(int i=0; i<blockSize; i++) { |
||||||
|
rdev = 0.0f; |
||||||
|
for (int j=0; j<12; j++){ // Add 12, using Central Limit to get Gaussian
|
||||||
|
idum = (uint32_t)1664525 * idum + (uint32_t)1013904223; |
||||||
|
it = FL_ONE | (FL_MASK & idum); // Generate random number
|
||||||
|
rdev += (*(float *)&it) - 1.0f; // Cute convert to float
|
||||||
|
|
||||||
|
/* ====================================
|
||||||
|
union ( |
||||||
|
uint32_t i32; |
||||||
|
float32_t f32; |
||||||
|
) uinf; |
||||||
|
|
||||||
|
uinf.i32 = it; |
||||||
|
rdev += uinf.f32 - 1.0f; |
||||||
|
=================================== |
||||||
|
*/
|
||||||
|
} |
||||||
|
// Next, to get general form
|
||||||
|
// return mu + sd * 3.4641016f * (rdev - 0.5*(float)M) / sqrtf((float32_t)M);
|
||||||
|
*pd++ = sd*(rdev - 6.0f); // Specific for mu=0.0, M=12
|
||||||
|
} |
||||||
|
|
||||||
|
AudioStream_F32::transmit(blockOut); |
||||||
|
AudioStream_F32::release(blockOut); |
||||||
|
|
||||||
|
#if TEST_TIME_GWN |
||||||
|
t2 = tElapse; |
||||||
|
if(iitt++ < 0) { |
||||||
|
Serial.print("At Gaussian Noise end, microseconds = "); |
||||||
|
Serial.println (t2 - t1); |
||||||
|
} |
||||||
|
t1 = tElapse; |
||||||
|
#endif |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
/*
|
||||||
|
* synth_GaussianWhiteNoise_F32.h |
||||||
|
* W7PUA 15 June 2020 |
||||||
|
* |
||||||
|
* Thanks to PJRC and Pau Stoffregen for the Teensy processor, Teensyduino |
||||||
|
* and Teensy Audio. Thanks to Chip Audette for the F32 extension |
||||||
|
* work. Alll of that makes this possible. Bob |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Bob Larkin |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice, development funding notice, and this permission |
||||||
|
* notice shall be included in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||||
|
* THE SOFTWARE. |
||||||
|
*/ |
||||||
|
/* This noise source is very close to a Gaussian distribution with mean of
|
||||||
|
* zero and a standard deviation specified by amplitude(). Default amlitude |
||||||
|
* is 0.0 (off). Time requirements: |
||||||
|
* For generating a block of 128, Teensy 3.6, 121 microseconds |
||||||
|
* For generating a block of 128, Teensy 4.0, 36 microseconds |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef synth_GaussianWhiteNoise_f32_h_ |
||||||
|
#define synth_GaussianWhiteNoise_f32_h_ |
||||||
|
#include "Arduino.h" |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
|
||||||
|
// Temporary timing test
|
||||||
|
#define TEST_TIME_GWN 0 |
||||||
|
|
||||||
|
#define FL_ONE 0X3F800000 |
||||||
|
#define FL_MASK 0X007FFFFF |
||||||
|
|
||||||
|
class AudioSynthGaussian_F32 : public AudioStream_F32 |
||||||
|
{ |
||||||
|
//GUI: inputs:0, outputs:1 //this line used for automatic generation of GUI node
|
||||||
|
//GUI: shortName:Gaussianwhitenoise //this line used for automatic generation of GUI node
|
||||||
|
public: |
||||||
|
AudioSynthGaussian_F32() : AudioStream_F32(0, NULL) { } |
||||||
|
// Allow for changing block size?
|
||||||
|
AudioSynthGaussian_F32(const AudioSettings_F32 &settings) : AudioStream_F32(0, NULL) { } |
||||||
|
|
||||||
|
// Gaussian amplitude is specified by the 1-sigma (standard deviation) value.
|
||||||
|
// sd=0.0 is un-enabled.
|
||||||
|
void amplitude(float _sd) { |
||||||
|
sd = _sd; // Enduring copy
|
||||||
|
if (sd<0.0) sd=0.0; |
||||||
|
} |
||||||
|
// Add printError(uint16_t e) - not currently used.
|
||||||
|
virtual void update(void); |
||||||
|
|
||||||
|
private: |
||||||
|
uint16_t blockSize = AUDIO_BLOCK_SAMPLES; |
||||||
|
uint32_t idum = 12345; |
||||||
|
float32_t sd = 0.0; // Default to off
|
||||||
|
uint16_t errorPrint = 0; |
||||||
|
// *Temporary* - TEST_TIME allows measuring time in microseconds for each part of the update()
|
||||||
|
#if TEST_TIME_GWN |
||||||
|
elapsedMicros tElapse; |
||||||
|
int32_t iitt = 999000; // count up to a million during startup
|
||||||
|
#endif |
||||||
|
}; |
||||||
|
#endif |
Loading…
Reference in new issue