我可以对此有所帮助吗?
在一个测试项目中,我有一个AUSampler -> MixerUnit -> ioUnit
并设置了一个渲染回调。一切正常。我正在使用MusicDeviceMIDIEvent
中定义的MusicDevice.h
方法来播放midi noteOn和noteOff。因此,在下面的hack测试代码中,noteOn发生了0.5秒。每2秒。MusicDeviceMIDIEvent
(以下)带有一个参数:inOffsetSampleFrame
,以便在将来的时间安排事件。我想做的是同时播放noteOn并安排noteOff(无需在下面进行黑客时间检查)。我只是不了解inOffsetSampleFrame
值应该是什么(例如:播放0.5秒或0.2秒的音符。(换句话说,我不了解音频计时的基础...)。
因此,如果有人可以指导我完成算法,以便从传入的AudioTimeStamp
中获取正确的值,那就太好了!也可以纠正我/澄清以下任何一个问题:
AudioTimeStamp->mSampleTime
-sampleTime是时间当前样本“切片”?这是毫秒吗?
AudioTimeStamp->mHostTime
-吗?主机是运行该应用程序的计算机,并且这是计算机启动以来的时间(以毫秒为单位)?这是一个 HUGE 数字。它不会滚动然后引起问题吗? inNumberFrames
-在iOS5上好像是512(通过kAudioUnitProperty_MaximumFramesPerSlice
)。这样就制成了 sample 最多512帧?
功能-特别是避免Objective C的调用-我理解
原因,但是如何向用户界面发送消息或执行其他操作
加工?
我想就是这样。感谢您的支持!
//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);
}
}
最佳答案
答案是我误解了inOffsetSampleFrame
的目的,尽管它被恰本地命名了。我以为可以在将来的任意时间使用它来安排noteOff事件,因此我不必管理noteOffs,但是其范围仅在当前示例框架之内。那好吧。