瀏覽代碼

Add AudioFilterStateVariable (work in progress....)

dds
PaulStoffregen 10 年之前
父節點
當前提交
ffa3f618b8
共有 4 個檔案被更改,包括 225 行新增0 行删除
  1. +1
    -0
      Audio.h
  2. +154
    -0
      filter_variable.cpp
  3. +68
    -0
      filter_variable.h
  4. +2
    -0
      keywords.txt

+ 1
- 0
Audio.h 查看文件

@@ -60,6 +60,7 @@
#include "effect_delay.h"
#include "filter_biquad.h"
#include "filter_fir.h"
#include "filter_variable.h"
#include "input_adc.h"
#include "input_i2s.h"
#include "mixer.h"

+ 154
- 0
filter_variable.cpp 查看文件

@@ -0,0 +1,154 @@
/* 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 "filter_variable.h"
#include "utility/dspinst.h"


// State Variable Filter (Chamberlin) with 2X oversampling
// http://www.musicdsp.org/showArchiveComment.php?ArchiveID=92

//#define MULT(a, b) (int32_t)(((int64_t)(a) * (b)) >> 30)
#define MULT(a, b) (multiply_32x32_rshift32_rounded(a, b) << 2)

static bool first = true;

void AudioFilterStateVariable::update_fixed(const int16_t *in,
int16_t *lp, int16_t *bp, int16_t *hp)
{
const int16_t *end = in + AUDIO_BLOCK_SAMPLES;
int32_t input, inputprev;
int32_t lowpass, bandpass, highpass;
int32_t lowpasstmp, bandpasstmp, highpasstmp;
int32_t fmult, damp;

fmult = setting_fmult;
damp = setting_damp;
inputprev = state_inputprev;
lowpass = state_lowpass;
bandpass = state_bandpass;

do {
input = (*in++) << 12;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = ((input + inputprev)>>1) - lowpass - MULT(damp, bandpass);
inputprev = input;
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = lowpass;
bandpasstmp = bandpass;
highpasstmp = highpass;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = input - lowpass - MULT(damp, bandpass);
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = signed_saturate_rshift(lowpass+lowpasstmp, 16, 13);
bandpasstmp = signed_saturate_rshift(bandpass+bandpasstmp, 16, 13);
highpasstmp = signed_saturate_rshift(highpass+highpasstmp, 16, 13);
*lp++ = lowpasstmp;
*bp++ = bandpasstmp;
*hp++ = highpasstmp;
#if 0
if (first) {
Serial.print(input >> 12);
Serial.print(", ");
Serial.print(lowpasstmp);
Serial.print(", ");
Serial.print(bandpasstmp);
Serial.print(", ");
Serial.print(highpasstmp);
Serial.println();
}
#endif
} while (in < end);

state_inputprev = inputprev;
state_lowpass = lowpass;
state_bandpass = bandpass;
first = false;
}

void AudioFilterStateVariable::update_variable(const int16_t *in,
const int16_t *ctl, int16_t *lp, int16_t *bp, int16_t *hp)
{
// TODO: implement control signal modulation of corner frequency
update_fixed(in, lp, bp, hp);
}

void AudioFilterStateVariable::update(void)
{
audio_block_t *input_block=NULL, *control_block=NULL;
audio_block_t *lowpass_block=NULL, *bandpass_block=NULL, *highpass_block=NULL;

input_block = receiveReadOnly(0);
control_block = receiveReadOnly(1);
if (!input_block) {
if (control_block) release(control_block);
return;
}
lowpass_block = allocate();
if (!lowpass_block) {
release(input_block);
if (control_block) release(control_block);
return;
}
bandpass_block = allocate();
if (!bandpass_block) {
release(input_block);
release(lowpass_block);
if (control_block) release(control_block);
return;
}
highpass_block = allocate();
if (!highpass_block) {
release(input_block);
release(lowpass_block);
release(bandpass_block);
if (control_block) release(control_block);
return;
}

if (control_block) {
update_variable(input_block->data,
control_block->data,
lowpass_block->data,
bandpass_block->data,
highpass_block->data);
release(control_block);
} else {
update_fixed(input_block->data,
lowpass_block->data,
bandpass_block->data,
highpass_block->data);
}
release(input_block);
transmit(lowpass_block, 0);
release(lowpass_block);
transmit(bandpass_block, 1);
release(bandpass_block);
transmit(highpass_block, 2);
release(highpass_block);
return;
}


+ 68
- 0
filter_variable.h 查看文件

@@ -0,0 +1,68 @@
/* 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.
*/

#ifndef filter_variable_h_
#define filter_variable_h_

#include "AudioStream.h"

class AudioFilterStateVariable: public AudioStream
{
public:
AudioFilterStateVariable() : AudioStream(2, inputQueueArray) {
frequency(1000);
resonance(0.707);
state_inputprev = 0;
state_lowpass = 0;
state_bandpass = 0;
}
void frequency(float freq) {
if (freq < 20.0) freq = 20.0;
else if (freq > AUDIO_SAMPLE_RATE_EXACT/2.5) freq = AUDIO_SAMPLE_RATE_EXACT/2.5;
setting_fmult = sinf(freq * (3.141592654/(AUDIO_SAMPLE_RATE_EXACT*2.0)))
* 2147483647.0;
}
void resonance(float q) {
if (q < 0.7) q = 0.7;
else if (q > 5.0) q = 5.0;
// TODO: allow lower Q when frequency is lower
setting_damp = (1.0 / q) * 1073741824.0;
}
virtual void update(void);
private:
void update_fixed(const int16_t *in,
int16_t *lp, int16_t *bp, int16_t *hp);
void update_variable(const int16_t *in, const int16_t *ctl,
int16_t *lp, int16_t *bp, int16_t *hp);
int32_t setting_fmult;
int32_t setting_damp;
int32_t state_inputprev;
int32_t state_lowpass;
int32_t state_bandpass;
audio_block_t *inputQueueArray[2];
};

#endif

+ 2
- 0
keywords.txt 查看文件

@@ -19,6 +19,7 @@ AudioEffectMultiply KEYWORD2
AudioEffectDelay KEYWORD2
AudioFilterBiquad KEYWORD2
AudioFilterFIR KEYWORD2
AudioFilterStateVariable KEYWORD2
AudioInputAnalog KEYWORD2
AudioMixer4 KEYWORD2
AudioOutputAnalog KEYWORD2
@@ -42,6 +43,7 @@ play KEYWORD2
updateCoefs KEYWORD2
frequency KEYWORD2
amplitude KEYWORD2
resonance KEYWORD2
modify KEYWORD2
output KEYWORD2
trigger KEYWORD2

Loading…
取消
儲存