Странный шум при воспроизведении разных звуков с разными объемами, установленными через OpenAL на iPhone

Я использую звуковую среду OpenAL на iPhone, и я настраиваю разные тома на отдельные звуки. У меня возникает проблема, когда я слышу начальный шум при щелчке/щелчке при переключении с одного звука на другой.

Это действительно заметно, когда у меня есть один звук, который получил большой объем (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);
    }

и здесь функция, в которой я устанавливаю громкость для каждого звука сразу после воспроизведения (ive пыталась установить его перед воспроизведением):

- (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);
 }
   } 

Любая помощь очень ценится, поскольку я пробовал все, что мог придумать. Я был бы так благодарен.

Ответ 1

Все, что мне нужно было сделать, это использовать calloc вместо malloc для выделения памяти для буфера OpenAL. Или вы также можете установить нуль в память с помощью memset.

Прозвучал странный шум. Это было из-за нежелательной памяти в моем случае. Вот почему это было случайно. Надеюсь, это поможет.

Ответ 2

Я случайно получил этот вопрос без ответа и, обнаружив, что проблема не была решена, я попытаюсь дать свой ответ, даже если прошло много времени.

Я не знаю OpenAL, но похоже, что это чисто аудио проблема. Нормально слышать короткие щелчки, когда вы внезапно меняете уровень звука, особенно от высокого значения до низкого значения. Например, если вы непосредственно сопоставляете громкость звука с ползунком, значение которого обновляется каждые несколько мс, вы можете легко слышать щелчки и всплывающие подсказки при быстром перемещении элемента управления. Разработчики программного обеспечения звука сглаживают изменения параметров с помощью фильтра нижних частот. В вашем случае я предлагаю вам остановить клип после его исчезновения и запустить новый клип, затухая его. Время затухания может быть как минимум 2 мс: оно не слышно, и звук будет играть точно.

Интересно, могут ли (некоторые версии) OpenAL автоматически решить эту проблему.

Ответ 3

Эта проблема вызвана не вызовом alSourceStop.

В документации это не указано, но alSourceStop должен быть вызван в источнике звука, прежде чем его можно будет повторно использовать, даже если звук уже завершен, а параметр AL_SOURCE_STATE источника не AL_PLAYING.