2010-07-28 9 views
10

Uso la struttura audio OpenAL sull'iPhone e sto impostando volumi diversi su singoli suoni. Mi sto imbattendo in un problema in cui sento un rumore scoppiettante/clic iniziale quando si passa da un suono all'altro.Rumore scoppiettante strano quando si riproducono suoni diversi con volumi diversi impostati tramite OpenAL sull'iPhone

È davvero notevole quando ho un suono con un volume elevato (1.0) e un secondo suono con uno basso (0,2). Quando colpisco il suono forte, e poi colpisco il suono debole, sento il pop/click. Ma quando vado dal suono morbido al forte, non noto nulla. Quindi il pop/click è veramente quando si passa da suoni forti a suoni soft.

Ecco il metodo suono init:

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

ed ecco la funzione di riproduzione:

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

Ed ecco la funzione in cui ho impostato il volume per ogni suono subito dopo la riproduzione (Ive ha provato impostazione prima di giocare troppo):

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

Qualsiasi aiuto è molto apprezzato come ho provato e tutto quello che posso pensare. Sarei così grato.

+0

Succede anche su Mac. Hai trovato una soluzione ? –

+0

@Quakeboy - No, non ho, ho appena rinunciato. Lo stesso problema con l'impostazione del tono dei suoni individuali. – c0dec0de

risposta

3

Tutto quello che dovevo fare era usare calloc invece di malloc per allocare memoria per il buffer OpenAL. Oppure è anche possibile azzerare la memoria con memset.

Il rumore scoppiettante si spense. Era dovuto alla memoria spazzatura nel mio caso. Ecco perché è stato anche casuale. Spero che questo ti aiuti.

+0

Grazie. Ci proverò più tardi oggi e ti faccio sapere. – codeman

+0

Come implementare i comandi calloc o memset? Ecco le linee rilevanti al momento: UInt32 dataSize = ((UInt32) theFileLengthInFrames) * theOutputFormat.mBytesPerFrame; \t theData = malloc (dataSize); – codeman

+0

theData = calloc (dataSize, 1); –

0

Ho casualmente ottenuto questa domanda senza risposta e, trovando che il problema non è stato risolto, cercherò di dare la mia risposta, anche se è passato molto tempo.

Non conosco OpenAL, ma sembra che si tratti di un problema puramente audio. È normale udire brevi clic quando si modifica improvvisamente il livello dell'audio, in particolare da un valore alto a un valore basso. Ad esempio, se si mappa direttamente il volume dell'audio su un dispositivo di scorrimento, il cui valore viene aggiornato ogni pochi ms, è possibile udire facilmente clic e pop quando si scorre rapidamente il controllo. Ciò che gli sviluppatori di software audio fanno è regolare le modifiche dei parametri con un filtro passa-basso. Nel tuo caso, ti suggerisco di fermare la clip dopo averla attenuata e iniziare una nuova clip facendola dissolvenza. Il tempo di dissolvenza può essere di soli 2 ms: non è udibile, e il suono verrà riprodotto solo finemente .

Mi chiedo se (alcune versioni di) OpenAL possano risolvere automaticamente questo problema.

0

Questo problema è causato da non chiamare alSourceStop.

La documentazione in realtà non lo indica, ma alSourceStop deve essere richiamato su una sorgente sonora prima che possa essere riutilizzato anche se il suono era già finito e il parametro AL_SOURCE_STATE dell'origine non è AL_PLAYING.

Problemi correlati