2010-07-28 5 views
10

Ich benutze das OpenAL Soundframework auf dem iPhone, und ich stelle verschiedene Lautstärken für einzelne Sounds ein. Ich stoße auf ein Problem, bei dem ich beim Umschalten von einem Klang zum nächsten ein anfängliches Knacken höre.Seltsames Poppgeräusch beim Abspielen verschiedener Sounds mit unterschiedlichen Lautstärken, die über OpenAL auf dem iPhone eingestellt werden

Es ist wirklich auffällig, wenn ich einen Sound habe, der eine hohe Lautstärke (1,0) und einen zweiten Sound hat, der eine niedrige (0,2) hat. Wenn ich den lauten Ton trete, und dann den weichen Ton trete, höre ich den Pop/Klick. Aber wenn ich vom weichen Sound zum lauten gehe, merke ich nichts. Also der Pop/Klick wirklich passiert beim Umschalten von lauten zu leisen Tönen.

Hier ist die init-Sound-Methode:

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

und hier ist die Funktion spielen:

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

und hier ist die Funktion, wo ich die Lautstärke für jeden sofort klingen nach dem Spielen (ive versucht Einstellung vor dem Spielen auch):

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

Jede Hilfe wird sehr geschätzt, wie ich e was ich mir vorstellen kann. Ich wäre so dankbar.

+0

Es passiert auch auf dem Mac. Hast du eine Lösung gefunden? –

+0

@Quakeboy - Nein, habe ich nicht, ich habe es einfach aufgegeben. Dasselbe Problem mit der Einstellung der Tonhöhe einzelner Sounds. – c0dec0de

Antwort

3

Alles, was ich tun musste, war Calloc anstelle von malloc, um Speicher für den OpenAL-Puffer zuzuweisen. Oder Sie könnten auch den Speicher mit Memset auf Null setzen.

Das wierd knallende Geräusch ging aus. Es war wegen Junk-Speicher in meinem Fall. Deshalb war es auch zufällig. Hoffe das hilft.

+0

Danke. Ich werde es heute später ausprobieren und Sie wissen lassen. – codeman

+0

Wie würde ich die Calloc- oder Memset-Befehle implementieren? Hier sind die relevanten Zeilen zur Zeit: UInt32 dataSize = ((UInt32) theFileLengthInFrames) * theOutputFormat.mBytesPerFrame; \t theData = malloc (dataSize); – codeman

+0

theData = Calloc (dataSize, 1); –

0

Ich bin zufällig zu dieser unbeantworteten Frage gekommen und, nachdem ich festgestellt habe, dass das Problem nicht gelöst wurde, werde ich versuchen, meine Antwort zu geben, auch wenn eine lange Zeit vergangen ist.

Ich weiß nicht OpenAL, aber es klingt wie ein rein Audio-Problem ist. Es ist normal, kurze Klicks zu hören, wenn Sie plötzlich den Pegel des Audiosignals ändern, insbesondere von einem hohen Wert zu einem niedrigen Wert. Wenn Sie beispielsweise die Lautstärke des Audiomaterials direkt einem Schieberegler zuordnen, dessen Wert alle paar ms aktualisiert wird, können Sie Klicks und Knackser leicht hören, wenn Sie das Steuerelement schnell verschieben. Was Audio-Software-Entwickler machen, ist die Glättung der Parameteränderungen mit einem Tiefpassfilter. In meinem Fall würde ich vorschlagen, dass Sie den Clip nach dem Ausblenden stoppen und einen neuen Clip durch Einblenden starten. Die Überblendzeit kann so kurz wie 2 ms sein: Es ist nicht hörbar und der Sound wird nur fein wiedergegeben .

Ich frage mich, ob (einige Versionen von) OpenAL automatisch mit diesem Problem umgehen kann.

0

Dieses Problem wird dadurch verursacht, dass alSourceStop nicht aufgerufen wird.

Die Dokumentation besagt dies nicht wirklich, aber alSourceStop muss für eine Soundquelle aufgerufen werden, bevor es wiederverwendet werden kann, selbst wenn der Sound bereits beendet wurde und der AL_SOURCE_STATE-Parameter der Quelle nicht AL_PLAYING ist.