解析回调函数到函数

时间:2017-11-01 21:39:55

标签: c++ class callback type-conversion portaudio

我的回调函数似乎有一个非常奇怪的错误,我试图解析我调用它的函数..

record.h

#pragma once
#include <iostream>
#include "portaudio.h"
#include <algorithm>
#define SAMPLE_RATE (44100)

typedef double SAMPLE;
#define NUM_SECONDS 30

#define NUM_CHANNELS  2
#define SAMPLE_SILENCE 0.0f
#define PA_SAMPLE_TYPE  paFloat32
#define FRAMES_PER_BUFFER (512)


typedef struct
{
    int     frameIndex;
    int     maxFrameindex;
    SAMPLE  *recordedSamples;
}
paTestData;

class record {
public:
    record();
    void start_record();
    int recordCallback(const void *inputBuffer, void *outputBuffer,
                       unsigned long framesPerBuffer,
                       const PaStreamCallbackTimeInfo* timeInfo,
                       PaStreamCallbackFlags statusFlags, void *userData);
private:
    PaStreamParameters  inputParameters,
                        outputParameters;
    PaStream*           stream;
    PaError             err = paNoError;
    paTestData          data;
    int                 totalFrames;
    int                 numSamples;
    int                 numBytes;
    SAMPLE              max, val;
    double              average;
};

record.cpp

#include "record.h"


record::record()
{
    std::cout << "Record object made" << std::endl;
    std::cout << Pa_GetVersion() << std::endl;
    this->data.maxFrameindex = this->totalFrames = NUM_SECONDS * SAMPLE_RATE;
    this->data.frameIndex = 0;
    this->numSamples = this->totalFrames * NUM_CHANNELS;
    numBytes = numSamples * sizeof(SAMPLE);
    data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
    if( data.recordedSamples == NULL )
    {
        std::cout << "Could not allocate record array" << std::endl;
        exit(1);
    }

    std::fill_n(this->data.recordedSamples,numSamples,0);
    int err = Pa_Initialize();

    if( err != paNoError )
    {
        std::cout << "Error" << std::endl;
        printf(  "PortAudio error: %s\n", Pa_GetErrorText( err ) );
    }
    else
    {
       printf(  "PortAudio init: %s\n", Pa_GetErrorText( err ) );
    }

    this->inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */


    if (this->inputParameters.device == paNoDevice) {
        std::cout << "Error: No default input device" << std::endl;
        exit(1);
    }

    this->inputParameters.channelCount = 2;                    /* stereo input */
    this->inputParameters.sampleFormat = PA_SAMPLE_TYPE;
    this->inputParameters.suggestedLatency = Pa_GetDeviceInfo( this->inputParameters.device )->defaultLowInputLatency;
    this->inputParameters.hostApiSpecificStreamInfo = NULL;

}

int record::recordCallback(const void *inputBuffer, void *outputBuffer,
                           unsigned long framesPerBuffer,
                           const PaStreamCallbackTimeInfo* timeInfo,
                           PaStreamCallbackFlags statusFlags, void *userData)
{
    this->data = (paTestData&) userData;
    const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
    SAMPLE *wptr = &this->data.recordedSamples[this->data.frameIndex * NUM_CHANNELS];
    long framesToCalc;
    long i;
    int finished;
    unsigned long framesLeft = this->data.maxFrameindex - this->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(int i=0; i<framesToCalc; i++ )
        {
            *wptr++ = SAMPLE_SILENCE;  /* left */
            if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE;  /* right */
        }
    }
    else
    {
        for(int i=0; i<framesToCalc; i++ )
        {
            *wptr++ = *rptr++;  /* left */
            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
        }
    }
    this->data.frameIndex += framesToCalc;
    return finished;
}

void record::start_record()
{

    err = Pa_OpenStream(
              &this->stream,
              &this->inputParameters,
              NULL,                  /* &outputParameters, */
              SAMPLE_RATE,
              FRAMES_PER_BUFFER,
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
              recordCallback,
              &data );
    if( err != paNoError )
    {
        std::cout << "Something wrong  - open_stream check" << std::endl;
        exit(1);
    }

    if( this->stream )
    {
        this->err = Pa_StartStream( this->stream );
        if( err != paNoError )
        {
            std::cout << "Something wrong in stream check" << std::endl;
            exit(1);
        }

        std::cout << "Waiting for playback to finish" << std::endl;

        while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
        {
            Pa_Sleep(100);
        }
        if( err < 0 )
        {
            std::cout << "error check with isStreamActive - something wrong" << std::endl;
            exit(1);
        }

        err = Pa_CloseStream( stream );
        if( err != paNoError )
        {
            std::cout << "error check with close_stream- something wrong" << std::endl;
            exit(1);
        }


        std::cout << "Everythin done!" << std::endl;
    }


}

错误:

record/record.cpp:107:21: error: cannot convert ‘record::recordCallback’ from type ‘int (record::)(const void*, void*, long unsigned int, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void*) {aka int (record::)(const void*, void*, long unsigned int, const PaStreamCallbackTimeInfo*, long unsigned int, void*)}’ to type ‘int (*)(const void*, void*, long unsigned int, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void*) {aka int (*)(const void*, void*, long unsigned int, const PaStreamCallbackTimeInfo*, long unsigned int, void*)}’
               &data );
                     ^
make[2]: *** [src/include/record/CMakeFiles/record.dir/record.cpp.o] Error 1
make[1]: *** [src/include/record/CMakeFiles/record.dir/all] Error 2
make: *** [all] Error 2

这里写的程序是这个github code post的一个副本, 我尝试格式化它有点c ++风格。问题似乎与start_recording()函数有关,我在其中将回调函数RecordCallback()解析为函数Pa_OpenStream()。出于某种原因,它被视为类型转换,但甚至错误消息指出两个版本都是相同的,这让我有疑问......为什么它认为它是类型转换,以及如何解决它?

0 个答案:

没有答案