2012-04-30 8 views
6

Estoy reproduciendo sonidos para mi juego con openAL y tengo algunos problemas que a veces se reproduce un pequeño error mientras se repite. También sin bucle obtengo un pequeño pop ... a veces, pero no todos.Fallo en la creación de OpenAL cuando se repite el sonido

Creo que tiene algo que ver con que el búfer sea demasiado largo, por lo que al final hay algunos datos no definidos. Simplemente no puedo entender cómo cambiar esto. Estoy cargando un archivo CAF con esta función:

void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate, ALdouble *duration) { 
OSStatus      err = noErr;  
SInt64       theFileLengthInFrames = 0; 
AudioStreamBasicDescription  theFileFormat; 
UInt32       thePropertySize = sizeof(theFileFormat); 
ExtAudioFileRef     extRef = NULL; 
void*       theData = NULL; 
AudioStreamBasicDescription  theOutputFormat; 

// Open a file with ExtAudioFileOpen() 
err = ExtAudioFileOpenURL(inFileURL, &extRef); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", err); goto Exit; } 

// Get the audio data format 
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", err); goto Exit; } 
if (theFileFormat.mChannelsPerFrame > 2) { printf("MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); goto Exit;} 

// Set the client format to 16 bit signed integer (native-endian) data 
// Maintain the channel count and sample rate of the original source format 
theOutputFormat.mSampleRate = theFileFormat.mSampleRate; 
theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame; 

theOutputFormat.mFormatID = kAudioFormatLinearPCM; 
theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame; 
theOutputFormat.mFramesPerPacket = 1; 
theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame; 
theOutputFormat.mBitsPerChannel = 16; 
theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 

// Set the desired client (output) data format 
err = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", err); goto Exit; } 

// Get the total frame count 
thePropertySize = sizeof(theFileLengthInFrames); 
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", err); goto Exit; } 

// Read all the data into memory 
UInt32  dataSize = theFileLengthInFrames * theOutputFormat.mBytesPerFrame;; 
theData = malloc(dataSize); 
if (theData) 
{ 
    AudioBufferList  theDataBuffer; 
    theDataBuffer.mNumberBuffers = 1; 
    theDataBuffer.mBuffers[0].mDataByteSize = dataSize; 
    theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame; 
    theDataBuffer.mBuffers[0].mData = theData; 

    // Read the data into an AudioBufferList 
    err = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer); 
    if(err == noErr) 
    { 
     // success 
     *outDataSize = (ALsizei)dataSize; 
     *outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; 
     *outSampleRate = (ALsizei)theOutputFormat.mSampleRate; 
    } 
    else 
    { 
     // failure 
     free (theData); 
     theData = NULL; // make sure to return NULL 
     printf("MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", err); goto Exit; 
    } 
} 

// Alex(Colombiamug): get the file duration... 
// first, get the audioID for the file... 
AudioFileID audioID; 
UInt32 audioIDSize = sizeof(audioID); 
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_AudioFile, &audioIDSize, &audioID); 
if(err) { printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_AudioFile) FAILED, Error = %ld\n", err); goto Exit; } 

//now the duration... 
double soundDuration; 
UInt32 durationSize = sizeof(soundDuration); 
err = AudioFileGetProperty(audioID, kAudioFilePropertyEstimatedDuration, &durationSize, &soundDuration); 
if(err) { printf("MyGetOpenALAudioData: AudioFileGetProperty(kAudioFilePropertyEstimatedDuration) FAILED, Error = %ld\n", err); goto Exit; } 

*duration = soundDuration; 
//printf("Audio duration:%f secs.\n", soundDuration); 

Salir: // Disponer la ExtAudioFileRef, ya no es necesaria si (extRef) ExtAudioFileDispose (extRef); return theData; }

Es parte de esta SoundEngine: SoundEngine

he tratado de poner mi archivo de café directamente en el código de ejemplo y es el mismo pequeño fallo. (Este archivo CAF estaba haciendo bien con el viejo de Apple SoundEngine.cpp pero yo tenía otros problemas con eso, así que decidió cambiar)

+0

Pops pueden ocurrir como resultado de una discontinuidad en el ciclo. ¿Estás cruzando el desvanecimiento? – learnvst

+0

Sí, hice un fundido cruzado cuando edité el archivo de sonido. Está girando perfectamente en mi servidor de sonido, así que sé que no es mi archivo de café – broch

Respuesta

4

responder a mi propia pregunta;)

Por pura suerte Debo admitir que intenté quitar la bandera kAudioFormatFlagIsPacked de esta línea:

theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 

y que arreglado.

Si alguien me puede decir por qué podría ser bueno saberlo ... o si hay algún problema para quitar esa bandera, también me gustaría saberlo.

+0

Mismo problema. Esto no me ayudó. ¿Alguna otra solución? –

+0

Terminé usando otro motor de búsqueda, a saber: https://github.com/alexrestrepo/SoundEngine Parece que funciona mucho mejor – broch

Cuestiones relacionadas