Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用openFrameworks+;核心音频 我的C++技能很轻,但我设法把事情做完——直到我撞到墙上。当前墙:_C++_Core Audio_Openframeworks - Fatal编程技术网

使用openFrameworks+;核心音频 我的C++技能很轻,但我设法把事情做完——直到我撞到墙上。当前墙:

使用openFrameworks+;核心音频 我的C++技能很轻,但我设法把事情做完——直到我撞到墙上。当前墙:,c++,core-audio,openframeworks,C++,Core Audio,Openframeworks,我正在使用CoreAudio做一些Midi播放的事情。我有很多工作要做,但我只做了一件简单的事情。(我不知道正确的C++术语,所以请容忍我……) 我在CoreAudio中使用一个render回调函数来指示AU渲染midi音符事件的时间。如果我将它定义为一个非类函数并将其粘贴到main.cpp(或testApp.cpp)上,它就可以工作了——我得到了事件。问题是我需要能够让testApp实例获取这些事件 所以。。有没有办法从main.cpp获取testApp实例,以便调用所需的testApp方法

我正在使用CoreAudio做一些Midi播放的事情。我有很多工作要做,但我只做了一件简单的事情。(我不知道正确的C++术语,所以请容忍我……) 我在CoreAudio中使用一个render回调函数来指示AU渲染midi音符事件的时间。如果我将它定义为一个非类函数并将其粘贴到main.cpp(或testApp.cpp)上,它就可以工作了——我得到了事件。问题是我需要能够让testApp实例获取这些事件

所以。。有没有办法从main.cpp获取testApp实例,以便调用所需的testApp方法

还是有一些C++ Vodoo有一个类中的非类函数调用一个实例的方法?例如,如果下面的函数在我的类中,它如何调用类实例上的方法

    OSStatus renderCallback(void *inRefCon,
                                              AudioUnitRenderActionFlags *  ioActionFlags,
                                              const AudioTimeStamp *        inTimeStamp,
                                              UInt32                inBusNumber,
                                              UInt32                inNumberFrames,
                                              AudioBufferList *     ioData)
{

           someClassMethod(); // doesn't work
           this.someClassMethod(); // doesn't work
           self.someClassMethod(); // doesn't work

}
我不确定,但我认为CoreAudio并没有将实例方法作为回调——至少这是我从错误消息(如下)中收集到的。不管怎么说,我都很好,这很有效

谢谢你的提示

错误:OSStatus类型的参数(testApp::)(void*, AudioUnitRenderActionFlags*,const AudioTimeStamp*,UInt32,UInt32, AudioBufferList*)'与'OSStatus()(无效, AudioUnitRenderActionFlags*,const AudioTimeStamp*,UInt32,UInt32, 音频缓冲列表*)

sbooth是这里的anwser,因为api设计师为您提供了一个很好的技巧。但是,如果将回调传递到设计不太好的c库中,下面的答案可能会有所帮助

您需要从指向成员函数的指针到指向函数的指针

C++ FAQ Lite,并有你的答案< /P> 您可以:

1.使someMethod()保持静态,并保留testApp的静态实例(如果需要旋转实例数据) 2。全局存储testApp指针,并从已使用的全局函数中使用它

下面是我推荐的方法1的一个示例

class Test
{
public:
    Test();
    void InstanceCallback();
    static void StaticCallbackMethod();

private:
    static Test* instance;
};


// Normally in cpp
Test* Test::instance = 0;

Test::Test()
{
    instance = this;
}

void Test::InstanceCallback()
{
    // do stuff;
}

void Test::StaticCallbackMethod()
{
    if (instance)
    {
        instance->InstanceCallback();
    }
}

int main()
{
    Test* t = new Test();

    void (*mf)();
    mf = &Test::StaticCallbackMethod;   
    mf();

    return 0;
}

在你的C++知识的基础上,我真的建议阅读所有的,然后。我希望在我开始时有人向我推荐它。

您是正确的,您不能在这里使用指向实例方法的指针(无法提供指向成员函数的隐式“this”指针,因为回调实际上不是通过对象调用的)


您可以为此使用静态成员函数(然后您需要某种方式为该函数提供指向testApp实例(全局变量、静态实例等)的指针)。

如果您可以安装boost,boost::bind可以为您做到这一点。

您不需要使用静态实例来完成此操作。添加渲染回调时,将C++对象作为ReFCON传递,然后将回调映射到回调中的对象:

// The actual callback is defined as a static function
static OSStatus
myAURenderCallback(void *inRefCon, 
                   AudioUnitRenderActionFlags *ioActionFlags,
                   const AudioTimeStamp *inTimeStamp,
                   UInt32 inBusNumber,
                   UInt32 inNumberFrames,
                   AudioBufferList *ioData)
{
    MyClass *object = static_cast<MyClass *>(inRefCon);
    return object->Render(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}


// When adding the render callback pass this as the context
AURenderCallbackStruct cbs = { myAURenderCallback, this };
OSStatus result = AUGraphSetNodeInputCallback(graph, node, 0, &cbs);


// The callback will look like
OSStatus MyClass::Render(AudioUnitRenderActionFlags *ioActionFlags,
                         const AudioTimeStamp *inTimeStamp,
                         UInt32 inBusNumber,
                         UInt32 inNumberFrames,
                         AudioBufferList *ioData)
{
  // Do something
}
//实际回调被定义为静态函数
静态骨状态
myAURenderCallback(在Refcon中无效*,
AudioUnitRenderActionFlags*ioActionFlags,
常量音频时间戳*inTimeStamp,
UInt32 InBunsNumber,
UInt32数字帧,
音频缓冲列表*ioData)
{
MyClass*object=static\u cast(inRefCon);
返回对象->渲染(ioActionFlags、inTimeStamp、inBusNumber、inNumberFrames、ioData);
}
//添加渲染回调时,将其作为上下文传递
AURenderCallbackStruct cbs={myAURenderCallback,this};
OSStatus结果=AUGraphSetNodeInputCallback(图形、节点、0和cbs);
//回调将如下所示
OSStatus MyClass::Render(AudioUnitRenderActionFlags*ioActionFlags,
常量音频时间戳*inTimeStamp,
UInt32 InBunsNumber,
UInt32数字帧,
音频缓冲列表*ioData)
{
//做点什么
}

这是一个漂亮的API技巧,显然有人在考虑人们如何使用它。在我的回答中,我假设询问者正在调用一个常规的c库。是的,苹果清楚地意识到这个API通常是如何使用的。我似乎还记得在Pascal工具箱编程时代的这种模式,所以我认为它已经存在了一段时间。谢谢大家的回复。我能够用上面的方法使它工作。CoreAudio一开始用所有的指针让我困惑,但我已经掌握了窍门。