AudioTimeStamp格式+'MusicDeviceMIDIEvent'

No *_*ing 6 audio core-audio ios coremidi ios5

我可以得到一些帮助吗?

在测试项目中,我有一个AUSampler -> MixerUnit -> ioUnit并设置了渲染回调.一切正常.我正在使用MusicDeviceMIDIEvent定义的方法MusicDevice.h播放midi noteOn¬eOff.因此,在下面的黑客测试代码中,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发送消息或进行其他处理?

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

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

// MusicDeviceMIDIEvent函数def:

extern OSStatus
MusicDeviceMIDIEvent(   MusicDeviceComponent    inUnit,
                    UInt32                  inStatus,
                    UInt32                  inData1,
                    UInt32                  inData2,
                    UInt32                  inOffsetSampleFrame)
Run Code Online (Sandbox Code Playgroud)

//我的回调

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;
}  
Run Code Online (Sandbox Code Playgroud)

// 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);
}
}
Run Code Online (Sandbox Code Playgroud)

No *_*ing 3

这里的答案是我误解了它的目的,inOffsetSampleFrame尽管它的名字很恰当。我认为我可以使用它在将来的某个任意时间安排 noteOff 事件,这样我就不必管理 noteOffs,但其范围仅在当前示例框架内。那好吧。