我尝试在C中编写一个简单的单AU播放,(几乎) - 无延迟跟踪阶段声码器原型。它是一个独立的程序。我想知道单个渲染回调可以安全承受多少处理负载,所以我更喜欢阻止异步DSP。
我的理念是只有一个预先确定的值 窗口步骤 ,或 跳跃大小 或 抽取因子 (不同文献资料中使用的同一术语的不同名称)。这个数字等于inNumberFrames
,这在某种程度上取决于 设备采样率 (还有什么?)。所有其他参数(例如 窗口大小 和 FFT大小 )将根据窗口步骤进行设置。这似乎是在一个回调中保留所有内容的最简单方法。
在实际渲染开始之前,即在调用inNumberFrames
之前,是否有一种安全的方法可以机器独立安全地猜测或查询AudioOutputUnitStart()
?
相位声码器算法主要是标准的,非常简单,使用vDSP函数进行FFT,加上自定义相位积分,我没有遇到任何问题。
此代码监视输入回调中的时间:
static Float64 prev_stime; //prev. sample time
static UInt64 prev_htime; //prev. host time
printf("inBus: %d\tframes: %d\tHtime: %lld\tStime: %7.2lf\n",
(unsigned int)inBusNumber,
(unsigned int)inNumberFrames,
inTimeStamp->mHostTime - prev_htime,
inTimeStamp->mSampleTime - prev_stime);
prev_htime = inTimeStamp->mHostTime;
prev_stime = inTimeStamp->mSampleTime;
很奇怪,inTimeStamp-> mSampleTime中的参数实际上显示了渲染帧的数量(参数的名称似乎有点误导)。无论是否在运行时通过 AudioMIDISetup.app 重新设置了另一个采样率,此数字始终为512
,就好像该值已通过编程方式硬编码一样。一方面,
inTimeStamp->mHostTime - prev_htime
间隔根据以数学上清晰的方式设置的采样率动态变化。只要采样率值匹配44100Hz的倍数,实际渲染就会继续。另一方面,48kHz倍数产生渲染error -10863 ( =
kAudioUnitErr_CannotDoInCurrentContext )
。我一定错过了一个非常重要的观点。
答案 0 :(得分:1)
假设audioUnit是输入音频单元:
from Tkinter import N S E W
答案 1 :(得分:0)
帧数通常是采样率乘以缓冲持续时间。有一个音频单元API来请求采样率和首选缓冲区持续时间(例如44100和5.8 mS导致256帧),但并非所有OS版本上的所有硬件都遵循所有请求的缓冲区持续时间或采样率。
答案 2 :(得分:0)
这个数字会等于inNumberFrames,它会以某种方式取决于设备的采样率(以及还有什么?)
这取决于您尝试将其设置为的内容。你可以设置它。
// attempt to set duration
NSTimeInterval _preferredDuration = ...
NSError* err;
[[AVAudioSession sharedInstance]setPreferredIOBufferDuration:_preferredDuration error:&err];
// now get the actual duration it uses
NSTimeInterval _actualBufferDuration;
_actualBufferDuration = [[AVAudioSession sharedInstance] IOBufferDuration];
它将使用大致围绕您设置的首选值的值。使用的实际值是基于2的幂和当前采样率的时间间隔。
如果您正在寻找跨设备的一致性,请选择大约10毫秒的值。性能最差的合理现代设备是iOS iPod touch 16gb,没有后置摄像头。但是,这个设备可以做大约10毫秒的回调没有问题。在某些设备上,您“可以”将持续时间设置得非常低并获得非常快速的回调,但通常会因为在下一次回调发生之前回调中的处理未完成而嘎嘎作响。