首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用openFrameworks + CoreAudio

使用openFrameworks + CoreAudio
EN

Stack Overflow用户
提问于 2011-07-14 02:50:16
回答 4查看 947关注 0票数 0

我的C++技能很轻,但我设法把事情做好--直到我撞到墙上。目前的墙:

我正在使用CoreAudio来做一些与Midi播放有关的事情。我已经做了很多工作,但被困在一件简单的事情上。(我不知道正确的C++术语,所以请原谅我.)

我在CoreAudio中使用了一个呈现回调函数来指示一个AU何时呈现一个midi便笺事件。如果我将它定义为一个非类函数,并将它粘贴到main.cpp (或testApp.cpp )中,它就会工作--我会得到事件。问题是,我需要能够让testApp的实例获取这些事件。

所以..。是否有一种方法可以从testApp获取main.cpp的实例,以便调用所需的testApp方法?

或者是否有一些C++伏都教可以让一个非类函数驻留在类中,调用一个实例的方法?例如,如果下面的函数在我的类中,它如何对类的实例调用一个方法.

代码语言:javascript
复制
    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不把实例方法作为回调--至少这是我从错误msg (下面)中收集到的。不管怎样,我都没问题。

谢谢你的建议!

错误: OSStatus (testApp::)(void*,AudioUnitRenderActionFlags*,const *,UInt32,UInt32,AudioBufferList*)‘与OSStatus()不匹配(OSStatus(),AudioUnitRenderActionFlags*,const *,UInt32,UInt32,AudioBufferList*)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-07-14 04:34:23

您不需要处理静态实例就可以做到这一点。当您添加呈现回调时,将您的C++对象作为refcon传递,然后在回调中将该refcon转换为您的对象:

代码语言:javascript
复制
// 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
}
票数 2
EN

Stack Overflow用户

发布于 2011-07-14 03:04:09

sbooth的回答是这里的解析器,因为api设计人员为您提供了一个很好的技巧。但是,如果您将回调传递到设计较差的c++库中,下面的答案可能会有所帮助。

您需要从指针到成员函数到指针到函数。

c++ faq 这里这里有您的答案

你可以:

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

下面是方法1的一个示例,我将向您推荐

代码语言:javascript
复制
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++知识的情况,我建议您阅读所有的常问石,然后阅读fqa。我真希望在我开始的时候有人推荐给我。

票数 0
EN

Stack Overflow用户

发布于 2011-07-14 03:10:06

在这里不能使用指向实例方法的指针是正确的(由于回调实际上不是通过一个对象调用的,所以无法提供指向成员函数的隐式'this‘指针)。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6687954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档