error in running a demo called bounce.c in chipmunk - chipmunk

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "/home/satyajit/Chipmunk-5.2.0/include/chipmunk/chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
cpSpace *space;
cpBody *staticBody;
int i;
static void
update(int ticks)
{
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for( i=0; i<steps; i++)
{
cpSpaceStep(space, dt);
}
}
static void
add_box()
{
const cpFloat size = 10.0f;
const cpFloat mass = 1.0f;
cpVect verts[] = {
cpv(-size,-size),
cpv(-size, size),
cpv( size, size),
cpv( size,-size),
};
cpFloat radius = cpvlength(cpv(size, size));
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts, cpvzero)));
body->p = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
body->v = cpvmult(cpv(2*frand() - 1, 2*frand() - 1), 200);
cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 4, verts, cpvzero));
shape->e = 1.0f; shape->u = 0.0f;
}
static cpSpace *
init(void)
{
staticBody = cpBodyNew(INFINITY, INFINITY);
cpResetShapeIdCounter();
space = cpSpaceNew();
cpSpaceResizeActiveHash(space, 30.0f, 1000);
space->iterations = 10;
cpShape *shape;
// Create segments around the edge of the screen.
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
for(i=0; i<10; i++)
add_box();
cpBody *body = cpSpaceAddBody(space, cpBodyNew(100.0f, 10000.0f));
shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, cpv(-75,0), cpv(75,0), 5.0f));
shape->e = 1.0f; shape->u = 1.0f;
cpSpaceAddConstraint(space, cpPivotJointNew2(body, staticBody, cpvzero, cpvzero));
return space;
}
static void
destroy(void)
{
cpBodyFree(staticBody);
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
const chipmunkDemo Bounce = {
"Bounce",
NULL,
init,
update,
destroy,
};
This is the code . The error i get when i run it is .
/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
/tmp/ccyG1FXX.o: In function `update':
Bounce.c:(.text+0x37): undefined reference to `cpSpaceStep'
/tmp/ccyG1FXX.o: In function `add_box':
Bounce.c:(.text+0x18f): undefined reference to `cpvlength'
Bounce.c:(.text+0x1d3): undefined reference to `cpMomentForPoly'
Bounce.c:(.text+0x1e2): undefined reference to `cpBodyNew'
Bounce.c:(.text+0x1f4): undefined reference to `cpSpaceAddBody'
Bounce.c:(.text+0x368): undefined reference to `cpPolyShapeNew'
Bounce.c:(.text+0x37a): undefined reference to `cpSpaceAddShape'
/tmp/ccyG1FXX.o: In function `init':
Bounce.c:(.text+0x45c): undefined reference to `cpBodyNew'
Bounce.c:(.text+0x466): undefined reference to `cpResetShapeIdCounter'
Bounce.c:(.text+0x46b): undefined reference to `cpSpaceNew'
Bounce.c:(.text+0x48f): undefined reference to `cpSpaceResizeActiveHash'
Bounce.c:(.text+0x548): undefined reference to `cpSegmentShapeNew'
Bounce.c:(.text+0x55a): undefined reference to `cpSpaceAddStaticShape'
Bounce.c:(.text+0x610): undefined reference to `cpSegmentShapeNew'
Bounce.c:(.text+0x622): undefined reference to `cpSpaceAddStaticShape'
Bounce.c:(.text+0x6cf): undefined reference to `cpSegmentShapeNew'
Bounce.c:(.text+0x6e1): undefined reference to `cpSpaceAddStaticShape'
Bounce.c:(.text+0x78e): undefined reference to `cpSegmentShapeNew'
Bounce.c:(.text+0x7a0): undefined reference to `cpSpaceAddStaticShape'
Bounce.c:(.text+0x7fd): undefined reference to `cpBodyNew'
Bounce.c:(.text+0x80f): undefined reference to `cpSpaceAddBody'
Bounce.c:(.text+0x89b): undefined reference to `cpSegmentShapeNew'
Bounce.c:(.text+0x8ad): undefined reference to `cpSpaceAddShape'
Bounce.c:(.text+0x91d): undefined reference to `cpPivotJointNew2'
Bounce.c:(.text+0x92f): undefined reference to `cpSpaceAddConstraint'
/tmp/ccyG1FXX.o: In function `destroy':
Bounce.c:(.text+0x949): undefined reference to `cpBodyFree'
Bounce.c:(.text+0x956): undefined reference to `cpSpaceFreeChildren'
Bounce.c:(.text+0x963): undefined reference to `cpSpaceFree'
collect2: ld returned 1 exit status

You need to update your header search path.

Related

Populating an object array in Processing - All objects are the same

I assure you I have spent hours trying to find a solution on the internet to this already, but I am in dire need of a fresh pair of eyes. I am using ArrayLists at the moment but have tried using a normal object array and the same problem occurred. For context I am trying to simulate an epidemic and am attempting to populate an array of the type "Person" with random positions within the boundaries of a community. The Person class at the moment is as follows:
private PVector pos;
class Person{
public Person(float x, float y){
pos = new PVector(x, y);
}
void show(){
ellipse(pos.x, pos.y, 10, 10);
}
float xPos(){
return pos.x;
}
}
My Community class is as follows:
private float size;
private PVector origin;
private ArrayList<Person> personArr;
class Community{
public Community(float x, float y, float size_){
origin = new PVector(x, y);
size = size_;
personArr = new ArrayList<Person>();
}
void show(){
noFill();
rect(origin.x, origin.y, size, size);
showPersons();
}
void setupCommunity(){
for(int i = 0; i < initialPopulation; i++){
float x1 = random(origin.x, origin.x + size);
float y1 = random(origin.y, origin.y + size);
Person person = new Person(x1, y1);
personArr.add(person);
}
}
void showPersons(){
for(int i = 0; i < personArr.size(); i++){
personArr.get(i).show();
}
}
}
The show() method for the community is called once every frame in the draw() method in my main Simulation class, which for reference sake, looks like this so far:
Grapher graphInfected, graphSuseptible, graphRemoved;
Community community;
float graphLength = 250;
float communitySize;
int initialPopulation = 25, population;
int populationInfected = 2, populationSusceptible = 23, populationRemoved = 0;
public void settings(){
size(1700, 1000);
communitySize = height * 0.8;
}
void setup(){
population = initialPopulation;
community = new Community(150, 100, communitySize);
community.setupCommunity();
graphInfected = new Grapher(width/2 + 240 + 200, height/2 - 230, "Infected", graphLength);
graphSuseptible = new Grapher(width/2 + 240 + 200, height/2 + 90, "Suseptible", graphLength);
graphRemoved = new Grapher(width/2 + 240 + 200, height/2 + 400, "Removed", graphLength);
}
void draw(){
background(255);
community.show();
graphInfected.addToArray(populationInfected);
graphSuseptible.addToArray(populationSusceptible);
graphRemoved.addToArray(populationRemoved);
graphInfected.show();
graphSuseptible.show();
graphRemoved.show();
}
The idea is to display all the people in the Persons array within the community rectangle, which is happening, it just looks like 1 person because they are all being drawn at the same position. I know this because upon debugging, I saw that while adding to the personArr in the community setup, the random positions were different, but each time I added to the array list, the entire list was populated with the exact same Person. This resulted in the whole list consisting of the last person that was created. I would appreciate it if someone knew why! I just need the list to be populated with the individual Person objects! Thank you <3
In case you want to try and run the project, here is the code for the grapher:
class Grapher {
private IntList population;
private int countArr = 1, dataLength = 0;
private PVector[] linePos;
private PVector origin;
private String graphType = "";
private float length;
private String yLable = "";
Grapher(int x, int y, String graphType, float length){
origin = new PVector(x, y);
population = new IntList();
this.graphType = graphType;
this.length = length;
population.set(0, initialPopulation);
}
//Called every every frame
void show() {
dataLength = population.size();
linePos = new PVector[dataLength];
//background(255, 255, 255);
int largestPop = initialPopulation;
for (int i = 0; i < dataLength; i++) {
if (population.get(i) > largestPop) {
largestPop = population.get(i);
}
}
//UI code
stroke(0, 0, 0);
line(origin.x, origin.y, origin.x + (int) length, origin.y);
fill(0);
textSize(15);
text("" + largestPop, origin.x - 60, origin.y - length);
text("" + dataLength, origin.x + length, origin.y + 25);
fill(0);
textSize(15);
text("Time", (float) (origin.x + length/2 - length/10), origin.y + 30);
text(yLable, origin.x - 100, (float) (origin.y - length/2));
//Calculating the graph points
line(origin.x, origin.y, origin.x, origin.y - (int) length);
double yInterval = length/(largestPop);
double interval = length/dataLength;
for (int i = 0; i < dataLength; i++) {
float xPos = origin.x + (float) interval * i;
float yPos = origin.y - ((float) yInterval * (population.get(i)));
linePos[i] = new PVector(xPos, yPos);
//ellipse(xPos, yPos, 5, 5);
}
//Picking the graph colour
if(graphType.equalsIgnoreCase("Infected")){
stroke(255, 0, 0);
yLable = "Infected";
}else if(graphType.equalsIgnoreCase("Susceptible")){
stroke(0, 0, 255);
yLable = "Susceptible";
}else{
stroke(0, 0, 0);
yLable = "Removed";
}
//Drawing the graph and connecting the points
for (int i = 0; i < dataLength - 1; i++) {
line(linePos[i].x, linePos[i].y, linePos[i + 1].x, linePos[i + 1].y);
}
}
void addToArray(int population){
this.population.set(countArr, population);
countArr++;
}
}
PVector pos is placed outside the Person class. So all Person objects use the same pos.
Same thing with the Community class. May cause weird bugs if you create multiple Communities.

'class cv::BackgroundSubtractorMOG2' has no member named 'operator()'

I am trying to compile this c++ application
int main ()
{
Mat frame;
Mat back;
Mat fore;
VideoCapture cap1;
cap1.open(0); /*to capture from camera*/
cv::Ptr<BackgroundSubtractorMOG> pMOG = createBackgroundSubtractorMOG();
cv::Ptr<BackgroundSubtractorMOG2> pMOG2 = createBackgroundSubtractorMOG2();
pMOG2->setNMixtures(10);
vector < vector < Point > >contours;
namedWindow ("Frame");
int i=0;
for (;;)
{
cap1 >> frame;
pMOG2->operator()(frame, fore);
pMOG2->getBackgroundImage (back);
erode (fore, fore, cv::Mat ());
erode (fore, fore, cv::Mat ());
dilate (fore, fore, cv::Mat ());
dilate (fore, fore, cv::Mat ());
dilate (fore, fore, cv::Mat ());
findContours (fore, contours, CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
drawContours (frame, contours, -1, Scalar (255, 255, 255), 1);
Scalar color = Scalar(200,200,200);
int a=0;
vector<Rect> boundRect( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
boundRect[i] = boundingRect( contours[i] );
}
for( i = 0; i< contours.size(); i++ )
{
if(boundRect[i].width>=40 || boundRect[i].height>=40)//eliminates small boxes
{
a=a+(boundRect[i].height)*(boundRect[i].width);
}
// cout<<"Net contour area is "<<a<<"\n";
if(a>=int(frame.rows)*int(frame.cols)/2)//change denominator as per convenience
{
putText(frame,"Tampering",Point(5,30),FONT_HERSHEY_SIMPLEX,1,Scalar(0,255,255),2);
cout<<"\a";
}
}
imshow ("Frame", frame);
waitKey(10);
}
I am getting the following error while compiling
error:
Tampering.cpp:27:21: error: 'class cv::BackgroundSubtractorMOG2' has
no member named 'operator()'
pMOG2->operator()(frame, fore);
my opencv version-3.3.0
Thanks in advance
Firstly, thanks for subscribing to my repository: https://github.com/SaranshKejriwal/Tampering-Detection/blob/master/Tampering%20main/Tampering.cpp
In my case, I had used openCV 2.4.5, which has the operator() method within the BackgroundSubtractorMOG2 class.
Since you are using openCV 3.3.0, I encourage you to have a look at the documentation, to verify that this method still exists

Is there a way to create a static const class value that is initialized with a loop?

A static member may be declared const, but then it must be initialized in the declaration. Consider the following case of a static array to be initialized with code in loops:
class A {
private:
enum { SIZE = 360 };
static double* vertices;
public:
static void staticInit();
};
double* A::vertices = new double[SIZE];
void A::staticInit() {
double a = 0, b = 0;
for (int i = 0; i < SIZE; i++, a += .01, b += .02)
vertices[i] = sin(a) + c2 * sin(b);
}
The code above would work. But if the intent is to make vertices constant, then declaring it const will give a compile error on the staticInit function.
In older C++ I would declare the pointer const, and cast it to non-const just in this function, but today, compilers won't allow this because it is unsafe. Of course, not declaring the pointer const is even less unsafe.
Is there any clean way out?
Create a makeVertices function that returns an std::array, then initialize the static value by invoking it:
constexpr std::size_t size = 360;
std::array<double, size> makeVertices()
{
std::array<double, size> vertices;
double a = 0, b = 0;
for (int i = 0; i < size; i++, a += .01, b += .02)
vertices[i] = sin(a) + c2 * sin(b);
return vertices;
}
(Both makeVertices and size could be defined inside A.)
class A {
private:
static std::array<double, size> vertices;
};
std::array<double, size> A::vertices = makeVertices();
Also note the use of constexpr instead of enum to represent compile-time numerical constants - that's idiomatic C++11.
I don't see why you couldn't make everything const that you care about. To simplify the usecase:
const T * const p = Init();
T * Init()
{
T * result = new T[n];
for (std::size_t i = 0; i != n; ++i)
InitOne(result[i]);
return result;
}
You should be able to apply this scheme to your static class member.

Const-correct way to tell a function how to access required data from an arbitrary data structure?

In this game of life program the user tells the solve function how to access required data. Is it possible to be const-correct inside the function without supplying it with both const and non-const versions of data accessors? Clang complains about the constness of neighbor cell data when checking whether neighbors are alive or not (candidate function not viable: 1st argument ('const Cell') would lose const qualifier):
#include "array"
#include "iostream"
using namespace std;
struct Cell {
bool is_alive = false; int nr_live_neighs = 0;
};
template<
class Grid,
class Is_Alive_Getter,
class Nr_Live_Neighs_Getter
> void solve(
Grid& grid,
Is_Alive_Getter Is_Alive,
Nr_Live_Neighs_Getter Nr_Live_Neighs
) {
for (size_t i = 1; i < grid.size() - 1; i++) {
auto& cell = grid[i];
const auto // how to stay const-correct here?
&neigh_neg = grid[i - 1],
&neigh_pos = grid[i + 1];
if (Is_Alive(neigh_neg)) Nr_Live_Neighs(cell)++;
if (Is_Alive(neigh_pos)) Nr_Live_Neighs(cell)++;
}
for (auto& cell: grid) {
if (Nr_Live_Neighs(cell) == 3)
Is_Alive(cell) = true;
else if (Nr_Live_Neighs(cell) != 2)
Is_Alive(cell) = false;
Nr_Live_Neighs(cell) = 0;
}
}
int main() {
std::array<Cell, 10> grid;
for (size_t i = 0; i < grid.size(); i++) {
grid[i].is_alive = (i % 4 > 0);
}
solve(
grid,
[](Cell& cell_data) -> bool& {
return cell_data.is_alive;
},
[](Cell& cell_data) -> int& {
return cell_data.nr_live_neighs;
}
);
return 0;
}
I can use
if (Is_Alive(const_cast<decltype(cell)>(neigh_neg)))
instead of
if (Is_Alive(neigh_neg))
inside the solver but that feels hacky even though it doesn't seem to affect time to solution. What if a non-const reference isn't available to use in decltype? Is there a generic way to cast away the const by only referring to the const variable?

xCode 3.2.6. Audio unit programming. IIR filter

My name's Antonio from Italy.
I'm trying to create an Audio Unit using xCode 3.2.6, starting from the example at
this link.
This is my first AU project, and I have no other examples to follow.
My project consists of an IIR notch filter. The algorithm I made works fine (I tested in on Matlab), but the AU doesn't work properly (tested on AU Lab). The .mp3 file sounds filtered, but something like a square wave (I suppose by ear) is overlapped with it.
The frequency of that noise seems to be proportional to the f0 parameter.
Here is the .cpp file code:
// Filtro.cpp
#include "Filtro.h"
#define pi 3.1415926535
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
COMPONENT_ENTRY(Filtro)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::Filtro
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Filtro::Filtro (AudioUnit component) : AUEffectBase (component) {
CreateElements ();
Globals () -> UseIndexedParameters (kNumberOfParameters);
SetParameter (kParameter_Gain, kDefaultValue_Gain);
SetParameter (kParameter_f0, kDefaultValue_f0);
SetParameter (kParameter_Q, kDefaultValue_Q);
// code for setting default values for the audio unit parameters
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::GetParameterInfo
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma mark ____Parameters
ComponentResult Filtro::GetParameterInfo (
AudioUnitScope inScope,
AudioUnitParameterID inParameterID,
AudioUnitParameterInfo &outParameterInfo
) {
ComponentResult result = noErr;
outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable
| kAudioUnitParameterFlag_IsReadable;
if (inScope == kAudioUnitScope_Global) {
switch (inParameterID) {
case kParameter_Gain:
AUBase::FillInParameterName (
outParameterInfo,
kParamName_Gain,
false
);
outParameterInfo.unit = kAudioUnitParameterUnit_Decibels;
outParameterInfo.minValue = kMinimumValue_Gain;
outParameterInfo.maxValue = kMaximumValue_Gain;
outParameterInfo.defaultValue = kDefaultValue_Gain;
break;
case kParameter_f0: // 9
AUBase::FillInParameterName (
outParameterInfo,
kParamName_f0,
false
);
outParameterInfo.unit = kAudioUnitParameterUnit_Hertz;
outParameterInfo.minValue = kMinimumValue_f0;
outParameterInfo.maxValue = kMaximumValue_f0;
outParameterInfo.defaultValue = kDefaultValue_f0;
outParameterInfo.flags |= kAudioUnitParameterFlag_DisplayLogarithmic;
break;
case kParameter_Q: // 9
AUBase::FillInParameterName (
outParameterInfo,
kParamName_Q,
false
);
outParameterInfo.unit = kAudioUnitParameterUnit_Generic;
outParameterInfo.minValue = kMinimumValue_Q;
outParameterInfo.maxValue = kMaximumValue_Q;
outParameterInfo.defaultValue = kDefaultValue_Q;
outParameterInfo.flags |= kAudioUnitParameterFlag_DisplayLogarithmic;
break;
default:
result = kAudioUnitErr_InvalidParameter;
break;
}
} else {
result = kAudioUnitErr_InvalidParameter;
}
return result;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::GetPropertyInfo
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus Filtro::GetPropertyInfo ( AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
UInt32 &outDataSize,
Boolean &outWritable)
{
return AUEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::GetProperty
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus Filtro::GetProperty( AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
void *outData )
{
return AUEffectBase::GetProperty (inID, inScope, inElement, outData);
}
#pragma mark ____FiltroEffectKernel
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::FiltroKernel::FiltroKernel()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Filtro::FiltroKernel::FiltroKernel (AUEffectBase *inAudioUnit) :
AUKernelBase (inAudioUnit), mSamplesProcessed (0), mCurrentScale (0) // 1
{
mSampleFrequency = GetSampleRate ();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::FiltroKernel::Reset()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Filtro::FiltroKernel::Reset() {
mCurrentScale = 0;
mSamplesProcessed = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filtro::FiltroKernel::Process
void Filtro::FiltroKernel::Process (const Float32 *inSourceP,
Float32 *inDestP,
UInt32 inSamplesToProcess,
UInt32 inNumChannels,
bool &ioSilence
) {
if (!ioSilence) {
const Float32 *sourceP = inSourceP;
Float32 *destP = inDestP, inputSample, outputSample;
Float32 Fs= mSampleFrequency;
int f0;
float w0, alpha, b0, b1, b2, a0, a1, a2;
float gain, dBgain, Q, coeff[5], x[5]={0,0,0,0,0} , out = 0;
dBgain = GetParameter (kParameter_Gain); //Get parameter from interface
if (dBgain < kMinimumValue_Gain) dBgain = kMinimumValue_Gain; //Check the right range
if (dBgain > kMaximumValue_Gain) dBgain = kMaximumValue_Gain;
f0 = GetParameter (kParameter_f0);
if (f0 < kMinimumValue_f0) f0 = kMinimumValue_f0;
if (f0 > kMaximumValue_f0) f0 = kMaximumValue_f0;
Q = GetParameter (kParameter_Q);
if (Q < kMinimumValue_Q) Q = kMinimumValue_Q;
if (Q > kMaximumValue_Q) Q = kMaximumValue_Q;
w0 = 2*pi*f0/Fs;
alpha = sin(w0)*sinh(log(2)/(log(exp(1))*2) * Q * w0/sin(w0));
b0 = 1;
b1 = -2*cos(w0);
b2 = 1;
a0 = 1 + alpha;
a1 = -2*cos(w0);
a2 = 1 - alpha;
coeff[0] = b0/a0;
coeff[1] = b1/a0;
coeff[2] = b2/a0;
coeff[3] = -a1/a0;
coeff[4] = -a2/a0;
//----------------------------------------------------------------------------------------------//
// y(n) = b0/a0 * x(n) + b1/a0 * x(n-1) + b2/a0 * x(n-2) * -a1/a0 * y(n-1) * -a2/a0 * y(n-2) //
//----------------------------------------------------------------------------------------------//
for (int i = inSamplesToProcess; i > 0; --i) {
int index = static_cast<long>(mSamplesProcessed * mCurrentScale) % 512; //?
if ((mNextScale != mCurrentScale) && (index == 0)) { //??
mCurrentScale = mNextScale;
mSamplesProcessed = 0;
}
if ((mSamplesProcessed >= sampleLimit) && (index == 0)) { // ??
mSamplesProcessed = 0;
}
gain = pow(10, dBgain/20);
inputSample = *sourceP;
x[0] = inputSample; //x(n)
x[3] = outputSample; //y(n-1)
for (int h = 0; h < 5; h++) { // Processing output sample
out = out+x[h]*coeff[h];
}
for (int h = 4; h > 0; h--) {
x[h]=x[h-1]; //I/O array shifting
}
outputSample = out * gain;
out = 0;
*destP = outputSample;
sourceP += 1;
destP += 1;
mSamplesProcessed += 1;
}
}
}
And that's the header file:
// Filtro.h
#include "AUEffectBase.h"
#include "AUEffectBase.h"
#include "FiltroVersion.h"
#if AU_DEBUG_DISPATCHER
#include "AUDebugDispatcher.h"
#endif
#ifndef __Filtro_h__
#define __Filtro_h__
#pragma mark ____Filtro Parameter Constants
static CFStringRef kParamName_Gain = CFSTR ("Gain");
static const double kDefaultValue_Gain = 0;
static const double kMinimumValue_Gain = -40;
static const double kMaximumValue_Gain = 0;
static CFStringRef kParamName_f0 = CFSTR ("f0");
static const int kDefaultValue_f0 = 1048;
static const int kMinimumValue_f0 = 50;
static const int kMaximumValue_f0 = 20000;
static CFStringRef kParamName_Q = CFSTR ("Q");
static const double kDefaultValue_Q = 0.1;
static const double kMinimumValue_Q = 0.001;
static const double kMaximumValue_Q = 10;
// parameter identifiers
enum { // Defines constants for identifying the parameters; defines the total number of parameters
kParameter_Gain = 0,
kParameter_f0 = 1,
kParameter_Q = 2,
kNumberOfParameters = 3
};
#pragma mark ____Filtro
class Filtro : public AUEffectBase
{
public:
Filtro(AudioUnit component);
#if AU_DEBUG_DISPATCHER
virtual ~Filtro () { delete mDebugDispatcher; }
#endif
virtual AUKernelBase * NewKernel() { return new FiltroKernel(this); }
virtual OSStatus GetParameterInfo(AudioUnitScope inScope,
AudioUnitParameterID inParameterID,
AudioUnitParameterInfo &outParameterInfo);
virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
UInt32 & outDataSize,
Boolean & outWritable );
virtual OSStatus GetProperty(AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
void * outData);
virtual bool SupportsTail () { return false; } // FIND
/*! #method Version */
virtual OSStatus Version() { return kFiltroVersion; }
// virtual ComponentResult GetPresets (CFArrayRef *outData) const;
// virtual OSStatus NewFactoryPresetSet (const AUPreset &inNewFactoryPreset);
protected:
class FiltroKernel : public AUKernelBase {
public:
FiltroKernel (AUEffectBase *inAudioUnit); // 1
virtual void Process (
const Float32 *inSourceP,
Float32 *inDestP,
UInt32 inFramesToProcess,
UInt32 inNumChannels, // equal to 1
bool &ioSilence
);
virtual void Reset();
private:
Float32 mSampleFrequency;
long mSamplesProcessed;
enum {sampleLimit = (int) 10E6};
float mCurrentScale;
float mNextScale;
};
};
#endif#include "FiltroVersion.h"
#if AU_DEBUG_DISPATCHER
#include "AUDebugDispatcher.h"
#endif
#ifndef __Filtro_h__
#define __Filtro_h__
#pragma mark ____Filtro Parameter Constants
static CFStringRef kParamName_Gain = CFSTR ("Gain");
static const double kDefaultValue_Gain = 0;
static const double kMinimumValue_Gain = -40;
static const double kMaximumValue_Gain = 0;
static CFStringRef kParamName_f0 = CFSTR ("f0");
static const int kDefaultValue_f0 = 1048;
static const int kMinimumValue_f0 = 50;
static const int kMaximumValue_f0 = 20000;
static CFStringRef kParamName_Q = CFSTR ("Q");
static const double kDefaultValue_Q = 0.1;
static const double kMinimumValue_Q = 0.001;
static const double kMaximumValue_Q = 10;
// parameter identifiers
enum { // Defines constants for identifying the parameters; defines the total number of parameters
kParameter_Gain = 0,
kParameter_f0 = 1,
kParameter_Q = 2,
kNumberOfParameters = 3
};
#pragma mark ____Filtro
class Filtro : public AUEffectBase
{
public:
Filtro(AudioUnit component);
#if AU_DEBUG_DISPATCHER
virtual ~Filtro () { delete mDebugDispatcher; }
#endif
virtual AUKernelBase * NewKernel() { return new FiltroKernel(this); }
virtual OSStatus GetParameterInfo(AudioUnitScope inScope,
AudioUnitParameterID inParameterID,
AudioUnitParameterInfo &outParameterInfo);
virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
UInt32 & outDataSize,
Boolean & outWritable );
virtual OSStatus GetProperty(AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
void * outData);
virtual bool SupportsTail () { return false; }
/*! #method Version */
virtual OSStatus Version() { return kFiltroVersion; }
protected:
class FiltroKernel : public AUKernelBase {
public:
FiltroKernel (AUEffectBase *inAudioUnit);
virtual void Process (
const Float32 *inSourceP,
Float32 *inDestP,
UInt32 inFramesToProcess,
UInt32 inNumChannels, // equal to 1
bool &ioSilence
);
virtual void Reset();
private:
Float32 mSampleFrequency;
long mSamplesProcessed;
enum {sampleLimit = (int) 10E6};
float mCurrentScale;
float mNextScale;
};
};
#endif
Thank a lot. I hope my English is not too bad.
Your filter implementation does not look correct to me. Maybe it's fine, but it's hard to follow. For example, it looks like you are shifting your stored x values into your stored y values, and even though you clear that up on the next loop, it's all a bit hard to follow.
You might want to check out how I do it here: http://blog.bjornroche.com/2012/08/basic-audio-eqs.html Much cleaner!
Also, are you processing mono samples or multichannel audio, because your Process function looks like it will only work as you intend with mono audio. (I haven't worked with AU's recently enough to be able to answer this myself from looking at your code)
Problem solved!!! After 3 days, I found the right way to avoid the variables reset every audio frame. I just declared those state variables into the Filtro.h file at the fourth line from the bottom, and than I initialised them into the "AUKernelBase (inAudioUnit)" in Filtro.cpp file. I hope it can be helpful to other people. Bye.

Resources