A Collection of Useful C++ Classes for Signal Processing

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I'm trying to add one filter to an existing c++ program.

I don't claim to be much of programmer so my apologies up front.

My program compiles OK but I get link errors ,like this:

Code: Select all

Error	1	 error LNK2019: unresolved external symbol "protected: __thiscall Dsp::Cascade::Cascade(void)" (??0Cascade@Dsp@@IAE@XZ) referenced in function "?mch_interl.@@YAXPAM000000_J00@Z" (?mch_interl.@@YAXPAM000000_J00@Z)
OK, so I include the DSPFilters.lib as an additional dependency, and include the path in the Additional Library Directories box (Visual studio 2008), having successfully built DSPFilters.lib already.

This is normally how I link in external libs, however now I get link errors like this:

Code: Select all

Error	1	 error LNK2005: "protected: void __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Tidy(bool,unsigned int)" (?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEX_NI@Z) already defined in DSPFilters.lib(Cascade.obj)	
Can someone explain how to link to DSPFilters?

Thanks
Z

Post

I got it going by including the DSPFilters source code in my project.

Post

the reason it asks for the stl lib is because it's linked against another implementation of stl's std::string and components than the one your compiler uses.

always best to use source. compile your own lib files and link those if you want, but you need to always maintain a lib project or make-file so that you can keep those libs up to date.

any time you upgrade your compiler/linker you need to update the libs.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

I am, however, getting clicks and pops in the filtered signal (not there if I comment out the filter and listen to the same data).

Post

The clicking is due to the boundary between buffers of filtered audio. Given a sine wave input, the filter output takes about two cycles to go from zero amplitude to a steady ratio of input to output amplitude ratio.

Image

When you get to the end of the buffer and tag the next one on it creates a glitch because the 2nd buffer starts at zero amplitude again.

Image

How does one implement a digital filter that will not have this issue?

I've tried a bunch of different filters and they all do the same thing. The above was taken with this:

Code: Select all

	{
		Dsp::SimpleFilter <Dsp::Butterworth::LowPass <10>, 1> f;
		f.setup (5,    // order
				 srate,// sample rate
				 80); // cutoff frequency
		f.process ((int)insize, audioData);
	}
	{
		Dsp::SimpleFilter <Dsp::Butterworth::HighPass <10>, 1> f;
		f.setup (5,    // order
				 srate,// sample rate
				 20); // cutoff frequency
		f.process ((int)insize, audioData);
	}
and a 20Hz sine wave.

Post

You should not be re-creating the filter for each block of audio data. You need to keep the filter object around, since it has state information inside of it.

Did you have a look at the DspFiltersDemo? It produces audio...

Post

Thanks for that.

Not sure how to call f.process from outside the filter definition.

The DspFiltersDemo is too complex for me to even know where to look.

Need a few more hints.

Thanks,
Z

Post

create the filter in your constructor and run setup only in setsamplerate or setparameter.

process only calls the f.process() function.

so:

Code: Select all

class myvstclass 
{
 public:
 
typedef Dsp::SimpleFilter<Dsp::Butterworth::LowPass <10>, 1> myfilter;
 myvstclass() : f() {
 }

 setsamplerate() {
      f.setup (5,    // order
             getsamplerate(),// sample rate
             80); // cutoff frequency

 }

 process() {
     f.process ((int)insize, audioData); 
 }

 myfilter f;
}
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

OK, getting close.

FYI I'm not doing a VST so not sure if all of what you said still applies.

I've got this compiling:

Code: Select all

typedef Dsp::SimpleFilter<Dsp::Butterworth::LowPass <10>, 1> LowPass; 
 LfeFilters() : f() { 
 } 

void setsamplerate() { 
      f.setup (5,    // order 
             srate,// sample rate 
             80); // cutoff frequency 

 } 

void process() { 
     f.process (insize, audioData); 
 } 

 LowPass f; 
}; 
I had to add the "void"s and I had to make all the variables of global scope.

I'm doing:

LfeFilters::setsamplerate;
and
LfeFilters::process;

But it doesn't filter the audio. With LfeFilters::f->process I get "error: a nonstatic member reference must be relative to a specific object".


I really appreciate all the help. C++ is rough! Guess I need a class.

Post

yes, understanding the basics of the language first would be a good idea.

http://xhip.presetexchange.com/temp/example.cpp

there is a bit of an explanation here. it should take you at least a few months to start to understand this concept, and it often takes several years to learn most functionality and how to apply it in the best way. the way things are looking now by the time you understand c++ in it's current state everyone will be doing things differently :)
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Thank you for the documented code.

Still some difficulty getting it to compile.

Do I need a typedef before the my_filter_box()?

The compiler is looking for some sort of key word there. There error is "explicit type is missing" and "expedted a ";" on that same line.

Hmm. typedef didn't help.

Code: Select all

// this part should usually go in my_filter.h
class my_filter
{
public:
 // where f() is, you could be setting parameters of the filter object
 // through the interface provided by it's constructor[s], if available.
 my_filter_box() : f() { //errors on this line
  order = 1;
  sample_rate = 1.0f;
  hz = 0.0f;
  dirty = true;
 }

 void set_order(const int &v) {
  order = v;
  dirty = true;
 }

 void set_sample_rate(const float &v) {
  sample_rate = v;
  dirty = true;
 }

 void set_hz(const int &v) {
  hz = v;
  dirty = true;
 }

 void update() {
  f.setup(order, sample_rate, hz);
  dirty = false;
 }

 void process(float *audio_data_ptr, const int &insize) {
  if (dirty) {
   update();
  }
  f.process(inside, audio_data_ptr);
 }

private:
 int order;
 float sample_rate;
 float hz;
 bool dirty;

 // if we "encapsulate" this inside an object,
 // the outside world never needs to know it exists.
 Dsp::SimpleFilter<Dsp::Butterworth::LowPass <10>, 1> f;
};

Post

erase "_box", i renamed the class to my_filter without removing the _box from the constructor.

also i posted it as a link for a reason :)

read a c++ in 24h book. 24h refers to that you can probably manage each lesson in one hour and learn the basics. usually you'd want to multiply by 4x or so to really understand each lesson. the c++ bible and a few other more modern books are also good lessons/references.

so estimate it'll take you about 60 hours to learn the basics.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Got it!

Thanks again for the detailed help!

Cheers,
Z

Post

Still a glitch at the buffer transition, however:

Image

calling only "process" for each buffer. Filter instantiation and parameters once during program.

Post

It sure does look like you're calling reset() or something on the filter.

Post Reply

Return to “DSP and Plugin Development”