使用remoteIO生成iPhone音频时如何防止爆音?
所以,不久前我正在开发一个波浪发生器应用程序并遇到了一些问题,但 Kenny Winker 是一个真正的救星,帮助我基本上让一切顺利进行。然而,我最终遇到的一个问题是,每当我改变我正在使用的频率值时(当我改变音量值时,程度要小得多),我最终会得到这些丑陋的裂纹“爆裂”的声音。这是一个问题,因为重点是能够使用滑块平滑地改变波的频率和音量,而听起来像弄皱纸的东西确实会破坏这种效果。这是我的 OSStatus 控制音量/频率的代码。
OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
SlidersViewController *me = (SlidersViewController *)inRefCon;
static int phase = 1;
for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {
int samples = ioData->mBuffers[i].mDataByteSize / sizeof(SInt16);
SInt16 values[samples];
float waves;
for(int j = 0; j < samples; j++) {
waves = 0;
waves += sin(kWaveform * me.fr1 * phase)*(me.vol1);
waves += sin(kWaveform * me.fr2 * phase)*(me.vol2);
waves += sin(kWaveform * me.fr3 * phase)*(me.vol3);
waves *= sin(kWaveform * (me.fr4/100) * phase)*(me.vol4);
waves *= 32500 / 4;
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
}
memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));
}
return noErr;}
正如您所看到的,obj-c 变量“fr1”-“fr4”控制频率,而“vol1”到“vol4”控制幅度。这些值每次
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}
或被
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}
触发时都会更新。关于如何解决这个问题以使其听起来更流畅有什么想法吗? 谢谢!
So, a little while back I was working on a wave generator app and having some problems, but Kenny Winker was a real lifesaver and helped me to basically get everything going. One problem I ended up with, however, is the fact that whenever I change the value of the frequency I'm using (and to a much lesser extent when I change the value of the volume), I end up with these ugly crackly "popping" noises. This is a problem as the whole point is to be able to smoothly alter the frequency and volume of a wave with a slider, and what sounds like crumpling paper can really ruin that effect. Here is the code of my OSStatus that controls volume/frequency.
OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
SlidersViewController *me = (SlidersViewController *)inRefCon;
static int phase = 1;
for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {
int samples = ioData->mBuffers[i].mDataByteSize / sizeof(SInt16);
SInt16 values[samples];
float waves;
for(int j = 0; j < samples; j++) {
waves = 0;
waves += sin(kWaveform * me.fr1 * phase)*(me.vol1);
waves += sin(kWaveform * me.fr2 * phase)*(me.vol2);
waves += sin(kWaveform * me.fr3 * phase)*(me.vol3);
waves *= sin(kWaveform * (me.fr4/100) * phase)*(me.vol4);
waves *= 32500 / 4;
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
}
memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));
}
return noErr;}
As you might see, the obj-c variables "fr1"-"fr4" control frequency, while "vol1" to "vol4" control amplitude. These values are updated every time
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}
or
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}
is triggered. Any ideas on how to fix this to make it sound smoother?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在内部循环中相乘来计算相位。倍频器的任何变化都会导致相位发生潜在的大跳跃,从而产生“爆裂声”。
不要相乘,而是在内部循环中添加增量相位。由于δ相只会发生少量变化,因此相位也会发生少量变化,并且会出现更小的不连续性。
You are multiplying in your inner loop to calculate phase. Any change in the frequency multiplier and you get a potential big jump in phase, and thus a "pop".
Instead of multiplying, add the delta-phase in your inner loop. Since the delta-phase will only change by a small amount, so will the phase, and there will be much smaller discontinuities.
我的猜测是,您只是更改了波形参数,而没有在两个值之间进行平滑插值,因此您的波形会被破坏并且听起来“静态”。
更改波浪生成函数,以便它在旧值(在帧的开头)和新值(在帧的末尾)之间进行插值。
My guess is that you're just changing the wave parameters without smoothly interpolating between the two values, thus your waveform gets broken and sounds "staticky".
Change your wave generation function so that it interpolates between the old value (at the beginning of the frame) and the new value (at the end of the frame).
我认为以下帖子将解决您的问题:
http://cocoawithlove .com/2010/10/ios-tone-generator-introduction-to.html
I think the following post will solve your question:
http://cocoawithlove.com/2010/10/ios-tone-generator-introduction-to.html