AudioTimeStamp格式+'MusicDeviceMIDIEvent'

时间:2012-03-04 07:08:09

标签: ios audio ios5 core-audio coremidi

我可以获得一点帮助吗?

在测试项目中,我有AUSampler -> MixerUnit -> ioUnit并设置了渲染回调。一切正常。我正在使用MusicDeviceMIDIEvent中定义的MusicDevice.h方法播放midi noteOn& noteOff。因此,在下面的黑客测试代码中,noteOn会发生.5秒。每2秒钟。

MusicDeviceMIDIEvent(下方)采用参数:inOffsetSampleFrame以便在将来安排活动。我希望能够做的是播放noteOn并同时安排noteOff(没有黑客时间检查我在下面做)。我只是不明白inOffsetSampleFrame值应该是什么(例如:播放.5秒或.2秒音符。(换句话说,我不理解音频定时的基础......)

所以,如果有人可以引导我通过算术从传入的AudioTimeStamp中获取正确的值,那就太棒了!也许也可以纠正我/澄清其中任何一个:

  1. AudioTimeStamp->mSampleTime - sampleTime是时间 目前的样本“切片”?这是以毫秒为单位吗?

  2. AudioTimeStamp->mHostTime - ? host是应用程序运行的计算机,这是计算机启动以来的时间(以毫秒为单位?)这是巨大数字。是不是翻滚然后引起问题?

  3. inNumberFrames - 在iOS5上似乎是512(设置为 kAudioUnitProperty_MaximumFramesPerSlice)。所以样品制作完成 最多512帧?

  4. 我看到很多告诫不要重载渲染回调 功能 - 特别是为了避免客观C调用 - 我明白了 原因,但是如何传达UI或做其他事情 处理

  5. 我猜就是这样。谢谢你的支持!

      

    inOffsetSampleFrame                   如果您正在从音频单元的渲染线程安排MIDI事件,那么您可以提供一个                       音频单元在下一个音频单元渲染中应用该事件时可能应用的样本偏移量。                       这允许您安排样本,应用MIDI命令的时间,特别是                       在开始新笔记时很重要。如果您没有在音频单元的渲染线程中进行调度,                       那么你应该将此值设置为0

    // MusicDeviceMIDIEvent函数def:

    extern OSStatus
    MusicDeviceMIDIEvent(   MusicDeviceComponent    inUnit,
                        UInt32                  inStatus,
                        UInt32                  inData1,
                        UInt32                  inData2,
                        UInt32                  inOffsetSampleFrame)
    

    //我的回调

    OSStatus  MyCallback(   void *                          inRefCon,
                     AudioUnitRenderActionFlags *   ioActionFlags,
                     const AudioTimeStamp *         inTimeStamp,
                     UInt32                         inBusNumber,
                     UInt32                         inNumberFrames,
                     AudioBufferList *              ioData)
    {
    
    Float64 sampleTime = inTimeStamp->mSampleTime;
    UInt64 hostTime = inTimeStamp->mHostTime;
    
    [(__bridge Audio*)inRefCon audioEvent:sampleTime andHostTime:hostTime];
    
    return 1;
    }  
    

    // OBJ-C方法

    - (void)audioEvent:(Float64) sampleTime andHostTime:(UInt64)hostTime
    {
    OSStatus result = noErr;
    
    Float64 nowTime = (sampleTime/self.graphSampleRate); // sample rate: 44100.0
    if (nowTime - lastTime > 2) {
    
        UInt32 noteCommand =    kMIDIMessage_NoteOn << 4 | 0;
        result = MusicDeviceMIDIEvent (mySynthUnit, noteCommand, 60, 120, 0); 
        lastTime = sampleTime/self.graphSampleRate;
    }
    
    if (nowTime - lastTime > .5) {
        UInt32   noteCommand =  kMIDIMessage_NoteOff << 4 | 0;
        result = MusicDeviceMIDIEvent (mySynthUnit, noteCommand, 60, 0, 0);
    }
    }
    

1 个答案:

答案 0 :(得分:3)

这里的答案是我误解了inOffsetSampleFrame的目的,尽管它被恰当地命名。我以为我可以在将来的任意时间使用它来安排noteOff事件,所以我不需要管理noteOffs,但是这个范围只是在当前的示例框架内。哦,好吧。