11

我在 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);
 }
   } 

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

4

3 回答 3

3

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

诡异的爆裂声消失了。就我而言,这是由于垃圾记忆。这就是为什么它也是随机的。希望这可以帮助。

于 2011-05-24T17:54:37.143 回答
2

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

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

于 2012-09-20T05:17:22.547 回答
0

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

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

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

于 2011-05-31T10:42:25.247 回答