Help me with callback funcion.

S

Solang

Hi Everyone,

I am trying to use third party library, namely portaudio in my
application. Unfortunately,
it is C API and has callback function in it. I have linking probplems again.
How do I solve this
callback problem?

Thank

Here is the error :

1>record.obj : error LNK2001: unresolved external symbol "public: static int
__cdecl RecordThread::recordCallback(void const *,void *,unsigned
long,struct PaStreamCallbackTimeInfo const *,unsigned long,void *)"
(?recordCallback@RecordThread@@SAHPBXPAXKPBUPaStreamCallbackTimeInfo@@K1@Z):

and here the header :

#include <QMutex>
#include <QSize>
#include <QThread>
#include <QWaitCondition>
#include "def.h"
#include "struct.h"
#include "c:\Users\portaudio\include\portaudio.h"
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/

/* Select sample format. */
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE (128)
#define PRINTF_S_FORMAT "%d"
#endif

typedef struct
{
int frameIndex; /* Index into sample array. */
int maxFrameIndex;
SAMPLE *recordedSamples;
}
paTestData;

QT_BEGIN_NAMESPACE
class QImage;
QT_END_NAMESPACE
class RecordThread : public QThread
{
Q_OBJECT

public:
RecordThread(QObject *parent = 0);
~RecordThread();
unsigned int uiBuffer[BUFFERSIZE];
bool on_going_flag;
void start_recording();
void stop_recording();
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );


signals:
void record_signal(const QByteArray &record_QByteArray, int length);

public:

protected:
void run();

private:
REC_SOUND rec_sound;
bool restart;
bool abort;

bool sound_init_flag;
QMutex mutex;
QWaitCondition condition;
bool recording_flag;
};


and the class:
#include <QtGui>
#include "record.h"
#define OUTPUT_WAVE_FILE "Capture.wav"
#define SERVICE_UPDATE_PERIOD (20)

#define TEST_WAVE_FILE "stereo.wav"


RecordThread::RecordThread(QObject *parent)
: QThread(parent)
{
int i;
restart = false;
abort = false;
sound_init_flag=false;
for (i=0;i<MAX_REC_SOUND;++i)
{
rec_sound.status=-1;
rec_sound.buffer=new char[BUFFERSIZE];
}
on_going_flag=false;


}
//! [0]

RecordThread::~RecordThread()
{
int i;
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();
for (i=0;i<MAX_REC_SOUND;++i)
delete rec_sound.buffer;
wait();
}


void RecordThread::start_recording()
{
recording_flag=true;
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}

}
void RecordThread::stop_recording()
{
recording_flag=false;
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}

}
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;

(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;

if( framesLeft < framesPerBuffer )
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}

if( inputBuffer == NULL )
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = SAMPLE_SILENCE; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE; /* right */
}
}
else
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
}
data->frameIndex += framesToCalc;
return finished;
}

void RecordThread::run()
{
forever
{
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
if (!sound_init_flag)
{
data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /*
Record for a few seconds. */
data.frameIndex = 0;
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on,
recordedSamples is initialised. */
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
// goto done;
}
for( i=0; i<numSamples; i++ ) data.recordedSamples = 0;

err = Pa_Initialize();
if (err == paNoError )
{
inputParameters.device = Pa_GetDefaultInputDevice(); /* default
input device */
inputParameters.channelCount = 2; /* stereo
input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo(
inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;

/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so
don't bother clipping them */
recordCallback,//(void const *,void *,unsigned long,struct
PaStreamCallbackTimeInfo const *,unsigned long,void *),
&data );
if( err != paNoError ) sound_init_flag=false;
} else sound_init_flag=false;
}
}
}
 
A

Alf P. Steinbach

* Solang:
I am trying to use third party library, namely portaudio in my
application. Unfortunately,
it is C API and has callback function in it. I have linking probplems
again. How do I solve this
callback problem?

Use the documented signature for the callback.

Or as we used to say, RTFM.

Probably the correct signature involves adding 'extern "C"'.


Cheers & hth.,

- Alf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top