[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    C++ template question.
From:       Jonas Widarsson <jonas.widarsson () home ! se>
Date:       2005-02-27 19:11:48
Message-ID: 200502272011.48798.jonas.widarsson () home ! se
[Download RAW message or body]

If you like to comment on something not related to KDE at all, read on.
Someone granted a couple of months ago that I can ask some newbie questions on 
this list, so here comes one! ;)

Skip to B if your'e in a hurry ... :)
If you prefer skipping the background completely, jump to C which is at the 
end of this email.


A:

I am trying to learn C++ the *right* way, meaning trying to obey any 
recommendations to make code very portable and modular. At this point I am 
struggling with low level classes for sending some audio procduced by an 
oscillator to "jack audio connection kit". I try to abstract the audio driver 
communication by making a the oscillators (that fill the sample buffer) 
template driven, so I can implement other backends later on, for example arts 
or plain ALSA. In addition, I'd like to keep this low level code NOT 
dependent on Qt or KDE. Then it's all Qt/KDE to give it a GUI to make it all 
usable. But I haven't really got there yet.

Maybe I should say that I have got the jack communication working perfectly 
some weeks ago, but that was just a non-modular "quick hack". So this is not 
about getting hardware communication working. In fact, my oscillator below 
isn't even doing audio...

aaand maybe I should say I don't want to simply use another package that 
already does these things. I am here to LEARN.

B:

I have two books available:
printed: Bjarne Stroustrup - The C++ Programming Language Special Edition
online: Frank B. Brokken  - http://www.icce.rug.nl/documents/cplusplus/  

They both cover template functions and template classes. Still, I get lost in 
them while trying to find out if these concepts can legally be combined.

Here's what I would like to do:

********************* oscillatorbase.h START
#ifndef OSCILLATORBASE_H
#define OSCILLATORBASE_H

/**
Base class for creating oscillators
@author Jonas Widarsson
 */
 
class OscillatorBase{

 public:
    OscillatorBase();
    ~OscillatorBase();
    template< typename SampleType> 
      void fillBuffer( SampleType *buffer, const unsigned &nframes, const int 
&sampleFreq);
};

#endif // OSCILLATORBASE_H
********************* oscillatorbase.h END

And corresponding implementation:

********************* oscillatorbase.cpp START
#include "oscillatorbase.h"
#include <iostream>
OscillatorBase::OscillatorBase(){
}

OscillatorBase::~OscillatorBase(){
}

template< typename SampleType>
  void OscillatorBase::fillBuffer( SampleType *buffer, const unsigned 
&nframes, const int &sampleFreq){
 // reimplement this; Iterate over *buffer to fill it with samples, as 
preferred by child class.
 SampleType *dummy = buffer;
 if (false) nframes = 0;
 if (false) sampleFreq = 0;
 std::cerr << "Subclass and reimplement this method with some real audio 
processing ;)" << std::endl;
}
********************* oscillatorbase.cpp END

This is used in another class called jackClient.
*********************<snip>
int JackClient::jackProcess(jack_nframes_t nframes){
 jack_default_audio_sample_t* out_buffer = (jack_default_audio_sample_t *) 
jack_port_get_buffer (this->output_port, nframes);
 
 vector<OscillatorBase*>::const_iterator osc_it = oscillators.begin();
 vector<OscillatorBase*>::const_iterator osc_it_end = oscillators.end();
 OscillatorBase* osc;
 while(osc_it != osc_it_end){
  osc = *osc_it;
  osc->fillBuffer(out_buffer, nframes,  sampleFreq);
  ++osc_it;
 };
 return 0;      
}
*********************</snip>

All this works very well when I don't make a template of 
OscillatorBase::fillBuffer().

The template code compiles perfectly, however, I have been struggling several 
evenings trying to make it LINK !!

here's the error message:
/usr/lib/gcc-lib/i586-pc-linux-gnu/3.3.2/include/g++-v3/bits/vector.tcc:244: 
undefined reference to `void OscillatorBase::fillBuffer<float>(float*, 
unsigned const&, int const&)'

The oscillatorbase files reside in a subdirectory called oscillators and my 
first attempt was to make a noinst library to provide functionality from that 
subdir.
Then I read about linking and templates requires some sort of export, which I 
tried but it wouldn't link then either.

So now I added the oscillator files to the program target and symlinked the 
oscillator files up one dir.

But no difference at all, even though all classes are in the same target now.


C:

So I start wondering. Is my use of templates illegal?
I mean, people talk about template functions and template classes.
My OscillatorBase::fillBuffer() code is supposed to be a template function 
within an ordinary class. Is that a design error?

Thanks.
-- 
Jonas Widarsson

tel: +46 271 152 00 - tel: +46 271 121 42 (hemma/home) - gsm: +46 70 539 64 79
 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic