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