在 iPhone 上通过 OpenAL 设置不同音量播放不同声音时出现奇怪的爆裂声

发布于 2024-09-11 20:31:47 字数 2059 浏览 3 评论 0原文

我在 iPhone 上使用 OpenAL 声音框架,并对各个声音设置不同的音量。我遇到了一个问题,从一种声音切换到下一种声音时,我听到最初的爆裂声/咔哒声。

当我有一个声音的音量很高(1.0)和第二个声音时,这真的很明显 声音较低 (0.2)。当我敲响响亮的声音,然后 敲击轻柔的声音,我听到爆裂声/咔哒声。但当我从柔软中走出来 声音很大,我没有注意到任何事情。所以弹出/点击真的 从响亮的声音切换到轻柔的声音时会发生这种情况。

这是初始化声音方法:

 - (id) initWithSoundFile:(NSString *)file doesLoop:(BOOL)loops
{
 self = [super init];
 if (self != nil) 
 {  
  if(![self loadSoundFile:file doesLoop:loops])
   {
   debug(@"Failed to load the sound file: %@...", file);
   [self release];
   return nil;
  }
  self.sourceFileName = file;

  //temporary sound queue
  self.temporarySounds = [NSMutableArray array];

  //default volume/pitch
  self.volume = 1.0;
  self.pitch = 1.0;  
  }
 return self;
    }

这是播放功能:

- (BOOL) play
{

 if([self isPlaying]) //see if the base source is busy...
 {
  //if so, create a new source
  NSUInteger tmpSourceID;
  alGenSources(1, &tmpSourceID);

  //attach the buffer to the source
  alSourcei(tmpSourceID, AL_BUFFER, bufferID);
  alSourcePlay(tmpSourceID);

  //add the sound id to the play queue so we can dispose of it later
  [temporarySounds addObject: [NSNumber numberWithUnsignedInteger:tmpSourceID]];

  //a "callback" for when the sound is done playing +0.1 secs
  [self performSelector:@selector(deleteTemporarySource)
   withObject:nil
   afterDelay:(duration * pitch) + 0.1];

  return ((error = alGetError()) != AL_NO_ERROR);
 }

 //if the base source isn't busy, just use that one...

 alSourcePlay(sourceID);
 return ((error = alGetError()) != AL_NO_ERROR);
    }

这是我在播放后立即设置每个声音的音量的功能(我也尝试在播放前设置它):

- (void) setVolume:(ALfloat)newVolume
{
 volume = MAX(MIN(newVolume, 1.0f), 0.0f); //cap to 0-1
 alSourcef(sourceID, AL_GAIN, volume); 

 //now set the volume for any temporary sounds...

 for(NSNumber *tmpSourceID in temporarySounds)
 {
  //tmpSourceID is the source ID for the temporary sound
  alSourcef([tmpSourceID unsignedIntegerValue], AL_GAIN, volume);
 }
   } 

非常感谢任何帮助,因为我已经尝试了一切想到。我将非常感激。

I'm using OpenAL sound framework on the iPhone, and I'm setting different volumes on individual sounds. I'm running into a problem where I'm hearing an initial popping/clicking noise when switching from one sound to the next.

It's really noticeable when I have one sound that's got a high volume (1.0) and a second
sound that has a low one (0.2). When I hit the loud sound, and then
hit the soft sound, I hear the pop/click. But when I go from the soft
sound to the loud, I don't notice anything. So the pop/click really
happens when switching from loud to soft sounds.

Here's the init sound method:

 - (id) initWithSoundFile:(NSString *)file doesLoop:(BOOL)loops
{
 self = [super init];
 if (self != nil) 
 {  
  if(![self loadSoundFile:file doesLoop:loops])
   {
   debug(@"Failed to load the sound file: %@...", file);
   [self release];
   return nil;
  }
  self.sourceFileName = file;

  //temporary sound queue
  self.temporarySounds = [NSMutableArray array];

  //default volume/pitch
  self.volume = 1.0;
  self.pitch = 1.0;  
  }
 return self;
    }

and here's the play function:

- (BOOL) play
{

 if([self isPlaying]) //see if the base source is busy...
 {
  //if so, create a new source
  NSUInteger tmpSourceID;
  alGenSources(1, &tmpSourceID);

  //attach the buffer to the source
  alSourcei(tmpSourceID, AL_BUFFER, bufferID);
  alSourcePlay(tmpSourceID);

  //add the sound id to the play queue so we can dispose of it later
  [temporarySounds addObject: [NSNumber numberWithUnsignedInteger:tmpSourceID]];

  //a "callback" for when the sound is done playing +0.1 secs
  [self performSelector:@selector(deleteTemporarySource)
   withObject:nil
   afterDelay:(duration * pitch) + 0.1];

  return ((error = alGetError()) != AL_NO_ERROR);
 }

 //if the base source isn't busy, just use that one...

 alSourcePlay(sourceID);
 return ((error = alGetError()) != AL_NO_ERROR);
    }

and here's the function where i set the volume for each sound immediately after playing (ive tried setting it before playing too):

- (void) setVolume:(ALfloat)newVolume
{
 volume = MAX(MIN(newVolume, 1.0f), 0.0f); //cap to 0-1
 alSourcef(sourceID, AL_GAIN, volume); 

 //now set the volume for any temporary sounds...

 for(NSNumber *tmpSourceID in temporarySounds)
 {
  //tmpSourceID is the source ID for the temporary sound
  alSourcef([tmpSourceID unsignedIntegerValue], AL_GAIN, volume);
 }
   } 

Any help is greatly appreciated as I've tried everything I can think of. I would be so grateful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏末 2024-09-18 20:31:47

我所要做的就是使用 calloc 而不是 malloc 为 OpenAL 缓冲区分配内存。
或者您也可以使用 memset 将内存设置为零。

奇怪的爆裂声消失了。就我而言,这是由于垃圾内存造成的。这就是为什么它也是随机的。希望这有帮助。

All I had to do was use calloc instead of malloc to allocate memory for the OpenAL buffer.
Or you could also zero set the memory with memset.

The wierd popping noise went off. It was due to junk memory in my case. That's why it was random too. Hope this helps.

海拔太高太耀眼 2024-09-18 20:31:47

这个问题是由于没有调用alSourceStop引起的。

文档并没有真正说明这一点,但必须在声源上调用 alSourceStop 才能重新使用它,即使声音已经完成并且源的 AL_SOURCE_STATE 参数不是 AL_PLAYING。

This problem is caused by not calling alSourceStop.

The documentation doesn't really state this, but alSourceStop must be called on a sound source before it can be reused even if the sound had already finished and the AL_SOURCE_STATE parameter of the source is not AL_PLAYING.

那伤。 2024-09-18 20:31:47

我随机遇到了这个没有答案的问题,发现问题没有解决,我会尝试给出我的答案,即使已经过去很长时间了。

我不知道 OpenAL,但这听起来像是一个纯粹的音频问题。当您突然改变音频电平时,尤其是从高值更改为低值时,听到短促的咔哒声是正常的。例如,如果您将音频音量直接映射到滑块(该值每隔几毫秒更新一次),则在快速滑动控件时您可以轻松听到咔嗒声和爆裂声。音频软件开发人员所做的是使用低通滤波器平滑参数变化。
对于您的情况,我建议您在淡出后停止剪辑,并通过淡入开始新的剪辑。淡入淡出时间可以短至 2 毫秒:听不到,而且声音播放得很好。

我想知道(某些版本的)OpenAL 是否可以自动处理这个问题。

I've randomly got to this unaswered question and, finding that the problem was not solved, I'll try to give my answer, even if a long time has passed.

I don't know OpenAL, but it sounds like this is a purely audio problem. It is normal to hear short clicks when you change suddenly the level of the audio, especially from a high value to a low value. For example, if you map directly the volume of the audio to a slider, which value is updated every few ms, you can easily hear clicks and pops when sliding fast the control. What audio software developers do is smoothing the parameter changes with a low pass filter.
In your case, I would suggest you to stop the clip after fading it out, and start a new clip by fading it in. The fade time can be as short as 2 ms: it's not audible, and the sound will play just finely.

I wonder if (some versions of) OpenAL can automatically deal with this issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文