-1

An audio library I'm using takes a callback function as an argument, which writes audio into a buffer.

I'm writing a class called Instrument, in which I have a method oscillator() which writes a sine wave to the buffer:

class Instrument {
private:
   int oscillator(int16_t* outputBuffer, ...){ // Writes a sine wave to outputBuffer
      ...
   }  
   RtAudio output;  // Object for outputting audio

public:
   void start() {
      output.openStream(settingsAndStuff, &oscillator);  // Error here
      ...
   }
}

The compiler doesn't like this, saying the type of the oscillator() method is incompatible with the type that RtAudio.openStream() accepts.

It works fine if oscillator() is static, presumably because the implicit this pointer passed into the method changes its type. However, I can't have it be static because I need oscillator() to have access to Instrument fields (for stuff like amplitude and frequency).

Is there any sort of quick solution that requires a minimal amount of wrappers and such?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
eejakobowski
  • 105
  • 5

1 Answers1

2

RtAudio::openStream() takes a user-defined parameter as input to the callback, per the documentation:

https://rtaudio.docsforge.com/master/api/RtAudio/openStream/

void openStream(..., RtAudioCallback callback, void *userData=NULL, ...)

public function for opening a stream with the specified parameters.

...

Parameters

...

callback - A client-defined function that will be invoked when input data is available and/or output data is needed.

userData - An optional pointer to data that can be accessed from within the callback function.

...

https://rtaudio.docsforge.com/master/api/#RtAudioCallback

typedef int(* RtAudioCallback)(..., void *userData)

RtAudio callback function prototype.

...

Parameters

userData - A pointer to optional data provided by the client when opening the stream (default = NULL).

...

That userData parameter will allow you to pass your Instrument* object pointer to a static callback, eg:

class Instrument {
private:
    int static_oscillator(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData) {
        return static_cast<Instrument*>(userData)->oscillator(outputBuffer, inputBuffer, nFrames, streamTime, status);
    }

    int oscillator(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status) {
        // Writes a sine wave to outputBuffer
        return ...;
    }  

    RtAudio output;  // Object for outputting audio

public:
    void start() {
        output.openStream(..., &static_oscillator, this, ...);
        ...
    }
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770