Created
May 3, 2018 11:01
-
-
Save cstroie/42c42d75923bc5a76d245a94d49322e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************* SOURCE LICENSE ********************************* | |
Copyright (c) 2018 MicroModeler. | |
A non-exclusive, nontransferable, perpetual, royalty-free license is granted to the Licensee to | |
use the following Information for academic, non-profit, or government-sponsored research purposes. | |
Use of the following Information under this License is restricted to NON-COMMERCIAL PURPOSES ONLY. | |
Commercial use of the following Information requires a separately executed written license agreement. | |
This Information is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
******************************* END OF LICENSE *********************************/ | |
// A commercial license for MicroModeler DSP can be obtained at http://www.micromodeler.com/launch.jsp | |
// Begin header file, bpfic.h | |
#ifndef BPFIC_H_ // Include guards | |
#define BPFIC_H_ | |
static const int bpfic_numStages = 1; | |
static const int bpfic_coefficientLength = 5; | |
extern signed char bpfic_coefficients[5]; | |
typedef struct | |
{ | |
signed char state[4]; | |
signed char output; | |
} bpficType; | |
typedef struct | |
{ | |
signed char *pInput; | |
signed char *pOutput; | |
signed char *pState; | |
signed char *pCoefficients; | |
short count; | |
} bpfic_executionState; | |
bpficType *bpfic_create( void ); | |
void bpfic_destroy( bpficType *pObject ); | |
void bpfic_init( bpficType * pThis ); | |
void bpfic_reset( bpficType * pThis ); | |
#define bpfic_writeInput( pThis, input ) \ | |
bpfic_filterBlock( pThis, &input, &pThis->output, 1 ); | |
#define bpfic_readOutput( pThis ) \ | |
pThis->output | |
int bpfic_filterBlock( bpficType * pThis, signed char * pInput, signed char * pOutput, unsigned int count ); | |
#define bpfic_outputToFloat( output ) \ | |
(( (1.0f/64) * (output) )) | |
#define bpfic_inputFromFloat( input ) \ | |
((signed char)(128f * (input))) | |
void bpfic_filterBiquad_2_6_7( bpfic_executionState * pExecState ); | |
#endif // BPFIC_H_ | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************* SOURCE LICENSE ********************************* | |
Copyright (c) 2018 MicroModeler. | |
A non-exclusive, nontransferable, perpetual, royalty-free license is granted to the Licensee to | |
use the following Information for academic, non-profit, or government-sponsored research purposes. | |
Use of the following Information under this License is restricted to NON-COMMERCIAL PURPOSES ONLY. | |
Commercial use of the following Information requires a separately executed written license agreement. | |
This Information is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
******************************* END OF LICENSE *********************************/ | |
// A commercial license for MicroModeler DSP can be obtained at http://www.micromodeler.com/launch.jsp | |
#include "bpfic.h" | |
#include <stdlib.h> // For malloc/free | |
#include <string.h> // For memset | |
signed char bpfic_coefficients[5] = | |
{ | |
// Scaled for a 8x8:16 Direct form 2 IIR filter with: | |
// Output shift = 7 | |
// Input shift = 2 | |
// Central shift = 6 | |
// Input has a maximum value of 1, scaled by 2^7 | |
// Output has a maximum value of 1.271437815229513, scaled by 2^6 | |
74, 0, -74, 19, -55// b0 Q10(0.0727), b1 Q10(0.00), b2 Q10(-0.0727), a1 Q6(0.296), a2 Q6(-0.855) | |
}; | |
bpficType *bpfic_create( void ) | |
{ | |
bpficType *result = (bpficType *)malloc( sizeof( bpficType ) ); // Allocate memory for the object | |
bpfic_init( result ); // Initialize it | |
return result; // Return the result | |
} | |
void bpfic_destroy( bpficType *pObject ) | |
{ | |
free( pObject ); | |
} | |
void bpfic_init( bpficType * pThis ) | |
{ | |
bpfic_reset( pThis ); | |
} | |
void bpfic_reset( bpficType * pThis ) | |
{ | |
memset( &pThis->state, 0, sizeof( pThis->state ) ); // Reset state to 0 | |
pThis->output = 0; // Reset output | |
} | |
int bpfic_filterBlock( bpficType * pThis, signed char * pInput, signed char * pOutput, unsigned int count ) | |
{ | |
bpfic_executionState executionState; // The executionState structure holds call data, minimizing stack reads and writes | |
if( ! count ) return 0; // If there are no input samples, return immediately | |
executionState.pInput = pInput; // Pointers to the input and output buffers that each call to filterBiquad() will use | |
executionState.pOutput = pOutput; // - pInput and pOutput can be equal, allowing reuse of the same memory. | |
executionState.count = count; // The number of samples to be processed | |
executionState.pState = pThis->state; // Pointer to the biquad's internal state and coefficients. | |
executionState.pCoefficients = bpfic_coefficients; // Each call to filterBiquad() will advance pState and pCoefficients to the next biquad | |
// The 1st call to filter1_filterBiquad() reads from the caller supplied input buffer and writes to the output buffer. | |
// The remaining calls to filterBiquad() recycle the same output buffer, so that multiple intermediate buffers are not required. | |
bpfic_filterBiquad_2_6_7( &executionState ); // Run biquad #0 | |
executionState.pInput = executionState.pOutput; // The remaining biquads will now re-use the same output buffer. | |
// At this point, the caller-supplied output buffer will contain the filtered samples and the input buffer will contain the unmodified input samples. | |
return count; // Return the number of samples processed, the same as the number of input samples | |
} | |
void bpfic_filterBiquad_2_6_7( bpfic_executionState * pExecState ) | |
{ | |
// Read state variables | |
signed char w0, x0; | |
signed char w1 = pExecState->pState[0]; | |
signed char w2 = pExecState->pState[1]; | |
// Read coefficients into work registers | |
signed char b0 = *(pExecState->pCoefficients++); | |
signed char b1 = *(pExecState->pCoefficients++); | |
signed char b2 = *(pExecState->pCoefficients++); | |
signed char a1 = *(pExecState->pCoefficients++); | |
signed char a2 = *(pExecState->pCoefficients++); | |
// Read source and target pointers | |
signed char *pInput = pExecState->pInput; | |
signed char *pOutput = pExecState->pOutput; | |
short count = pExecState->count; | |
short accumulator; | |
// Loop for all samples in the input buffer | |
while( count-- ) | |
{ | |
// Read input sample | |
x0 = *(pInput++); | |
// Run feedback part of filter | |
accumulator = (short)w2 * a2; | |
accumulator += (short)w1 * a1; | |
accumulator += (short)x0 << 2; | |
w0 = accumulator >> 6; | |
// Run feedforward part of filter | |
accumulator = (short)w0 * b0; | |
accumulator += (short)w1 * b1; | |
accumulator += (short)w2 * b2; | |
w2 = w1; // Shuffle history buffer | |
w1 = w0; | |
// Write output | |
*(pOutput++) = accumulator >> 7; | |
} | |
// Write state variables | |
*(pExecState->pState++) = w1; | |
*(pExecState->pState++) = w2; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment