AudioBuffer<float> &outputBuffer; - how to initialize


#1

Hello,
in my own class I try to create reference of type AudioBuffer & outputBuffer; Compiler gives me error that I shoul md initialize it in the constructor of my class. But I have no idea how to initialize it. Please help me.


#2

I believe you’d need to use an initialization list for that so it’d look something like this:

yourClassConstructor : yourAudioBuffer <float> (initialized arguments here)

Hope that helps


#3

@JoshuaHodge is right, but the syntax is a bit different:
The template argument <float> is only needed where you declared the reference. So it looks like:

class YourClass {
public:
    YourClass (AudioBuffer<float>& b) : outputBuffer (b)
    {
    // ...
    }
private:
    AudioBuffer<float>& outputBuffer;
}; 

References cannot be created without something to point to. That is the main difference between a reference and a pointer.


#4

Hey Daniel thanks, I tried that, and that’s Ok but only if I create variable of my class type in the class that has initialized already buffer. By I want to create variable of my class type in the MainComponent() class which has not initialized any AudioBuffer().


#5

But in MainComponent() class there is a method getNextRenderBlock (or something like that) and that method uses AudioBuffer in some way, and I want to get that buffer reference into my class


#6

A core principle of C++ (or any OO-programming) is encapsulation, which means, shield your data against any influence from outside, so you can eliminate errors, that messed up your data.
If you only need the buffer to process it in a function of YourClass, than it would be best to call that function with a reference as argument. So in getNextRenderBlock, where you have the buffer you want to fill, you can call the method of your class handing over the reference.

BTW. that is exactly, what every AudioSource derived class does, they just wrap the AudioBuffer together with startSample and numSamples in a struct, called AudioSourceChannelInfo and call the source to fill it up.
Here is some example code, the JUCE Sine generating source:


#7

Hey Daniel great great thanks for help, but to be honest I was affraid you answer like that :slight_smile: Of course I know I can just create variable of my class in the getNextRenderBlock, and then I have easy access to AudioBuffer (by AudioSourseChannelInfo). But then variable of my class will be created every buffer block (very often) and I want to avoid that due to fact my class will perform some complicated tasks like (DFT) which could make lags in the getNextRenderBlock. That,s why I want to create my class bariable once and keep in it reference to the AudioBuffer.


#8

Like I explained already in your previous thread, make your audio visualizer class have its own internal audio buffer instance (obviously as a member variable), there’s no need to attempt to initialize a reference from the outside. It wouldn’t work like that since the FFT length is probably not going to match the length of the audio buffers coming into getNextRenderBlock anyway, so you need to do your own buffering for the FFT.

Look in JUCE\examples\Audio\SimpleFFTDemo.h how it could be done.


#9

Hey Xenakios,
Thanks for reply. That whole thread is because your answer in my previous thread :slight_smile:
That’s why on the beginning I told, when I create my own member, like:

private:
AudioBuffer<float> &outputBuffer;

I get error that I shoul initialize AudioBuffer in the constructor of my class. And that’s all about that thread is.


#10

Because

AudioBuffer<float> &outputBuffer;

is a reference to an AudioBuffer, not an AudioBuffer instance. Remove the & from the line.

AudioBuffer<float> outputBuffer;

#11

:slight_smile:
Really?
But are you sure I get exactly the same data as thay are in the getNextRenderBlock?


#12

Of course not. You will need to copy the samples you get in getNextRenderBlock into the other buffer. (There’s no way to avoid that, you need to do the separate buffering anyway because the FFT size can’t be expected to match the length of the buffer you get in getNextRenderBlock.)


#13

OK, but let’s not talk about FFT, and its buffer size, it’s separate topic.

Last 2 months I’ve worked with many kind of FFT algorithms, and even made my own implementations of various type of FFT algorithms, like Radix-2, mixed Radix, and even one that I haven’t heard about before. So I have impression like I know a lot about buffer sizing in FFT :slight_smile: .

So let’s assume that now I just want to use exactly the same data (with the same buffer size) as it is in the getNextRenderBlock. So do you still claim I need to copy each buffer to my class, can’t I just make a reference to it?


#14

Of course you don’t need to copy in that case. But you can’t have the reference to the data as a member in your other class. (It wouldn’t make much sense to do it like that.) Just pass a reference or pointer to the data via function arguments.

class Analyzer
{
public:
  void analyzeData(const AudioSourceChannelInfo& inbuf)
  {
    // ... do my analysis stuff...
  }
}

Then in the class with the getNextAudioBlock call :

void MyAudioApp::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
  myAnalyzer.analyzeData(bufferToFill);
}

Note that in that AudioSourceChannelInfo is passed around because it may happen the information about the start sample number and partial length of the buffer may be needed. (AudioSourceChannelInfo is used together with an AudioBuffer where the whole content of the buffer might not be valid to use.)


#15

Hey Xenakios, OK great thanks for your support, I will try that what you talking about. Thanks.


#16

But now after some wondering. I am sure it will work but It still looks in your code if in the getNextRenderBlock I would call:
void MyAudioApp::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
myAnalyzer.analyzeData(bufferToFill);
}

It will set in my class pointer to the AudioBuffer each buffer (very often) but wouldn’t it be better if I set it just one time?
PS. Sorry for not formating text, I write from phone and see no option to format.


#17

You must not set (or at least store them in the class members) any pointers or references in your other class from the buffer provided into getNextAudioBlock in the other class. (The buffer provided into getNextAudioBlock should be considered temporary, for all intents and purposes, so it would be a very bad idea to store pointers or references into it or the data stored in it.)

I am assuming here you are working here with real time audio input. If you already have all the input audio stored (read from an audio file for example) in a buffer, then all this discussion has been a bit useless. But it hasn’t been completely clear what you are actually trying to do…


#18

What I try to do is:
Now in the getNextRenderBlock I call the function which write waves data to bufferToFill - I mean simple waves like sine, saw, squere, noise etc. Like a simple oscillator. I also have knobs that change the frequency of waves, and its amplitude. So I can’t store wavedata in the file, couse I want to change them in the real time.
All of that I have now, and it works. And now I am looking for best/most efficient way to send those real time waves to the FFT algorithm, and plot it as a graph. That’s what I want to do. Why I want do that? It’s other topic, just want to train my skills in programming, that’s all :slight_smile:


#19

And my next aim is to do the same with the audio files, so then I have data which are stored in the files, but it’s next aim. Now I am focused on real time oscilators.


#20

Well, I will repeat : to do FFT properly, you will need a separate buffer where you will need to copy the audio from the audio source. (No pointer or reference tricks, a real copy of the audio data.) For example my audio hardware works in Windows WASAPI mode with block sizes of 441 samples. Obviously that wouldn’t be compatible with a FFT size of for example 1024 samples. (Even if you have a FFT algorithm that can do arbitrary FFT sizes, it would be a bad idea to force the FFT to the size of the audio processing buffer coming from elsewhere. In plugins you couldn’t even expect the buffer size to be the same between calls to the processBlock function…)