未保留目标 C 变量值

Posted

技术标签:

【中文标题】未保留目标 C 变量值【英文标题】:Objective C variable value not being preserved 【发布时间】:2012-10-27 01:56:15 【问题描述】:

我正在为客户进行一些音频编程,但遇到了一个我不明白的问题。

我有一个由 CoreAudio 反复调用的渲染回调。在此回调中,我有以下内容:

// Get the audio sample data
AudiosampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData;

Float32 data;

// Loop over the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++) 

    // Convert from SInt16 to Float32 just to prove it's possible
    data = (Float32) outA[frame] / (Float32) 32768;

    // Convert back to SInt16 to show that everything works as expected
    outA[frame] = (SInt16) round(next * 32768);


这按预期工作,表明没有任何意外的舍入错误。

接下来我想做的是添加一个小延迟。我在类中添加了一个全局变量:

即在@implementation 行下方

Float32 last = 0;

然后我使用这个变量来获得一帧延迟:

// Get the audio sample data
AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData;

Float32 data;
Float32 next;

// Loop over the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++) 

    // Convert from SInt16 to Float32 just to prove it's possible
    data = (Float32) outA[frame] / (Float32) 32768;

    next = last;
    last = data;


    // Convert back to SInt16 to show that everything works as expected
    outA[frame] = (SInt16) round(next * 32768);


这一次,信号出现了奇怪的音频失真。

我只是看不出我做错了什么!任何建议将不胜感激。

【问题讨论】:

我认为这是音频问题,而不是 C 问题。尝试记录所有变量的值,看看是否有帮助。总是在下结论之前先登录。 这可能是线程问题。检查您的代码是否一直在同一个线程上运行。即,NSLog(@"thread: %@", [NSThread currentThread]);。如果没有,您需要使用锁/互斥锁来保护您的全局。 【参考方案1】:

您所做的似乎是在您的音频上引入了无意的phaser 效果。

这是因为您只延迟了音频的一个通道,所以结果是左通道比右通道延迟了一帧。这会导致一些奇怪的频率消除/放大,符合您对“奇怪的音频失真”的描述。

尝试将效果应用到两个通道:

AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData;
AudioSampleType *outB = (AudioSampleType *)ioData->mBuffers[1].mData;
// apply the same effect to outB as you did to outA

这假设您正在使用立体声音频(即ioData-&gt;mNumberBuffers == 2

就风格而言,在渲染回调中使用像 last 这样的全局变量是一个坏主意。使用inRefCon 传递适当的上下文(作为单个变量或必要时作为结构)。不过,这可能与您遇到的问题无关。

【讨论】:

感谢您的回答。我实际上使用的是单声道流格式(用于 iPad),这就是我只使用通道的原因。问题原来是音频是 SInt32 而不是 SInt16。结果,我无意中将 SInt16 转换为 SInt32。这似乎导致一些随机数据位徘徊。道德 - 要非常小心你正在使用哪些类型的变量!我严格使用全局变量进行测试。实际上,我正在编写一个合唱效果,因此 inRefCon 包含很多变量和缓冲区。

以上是关于未保留目标 C 变量值的主要内容,如果未能解决你的问题,请参考以下文章

C# lambda,局部变量值未取时你认为?

C++ 变量值未从标头传递到主

在并行运行 2 个或更多任务时保留变量值

保留变量值的空间

保留来自 dataReader c# 的 int 变量值

更改目标主体内的 Makefile 变量值