iOS: salida de Pitch Shifting y Piping de OpenAL en un búfer

Recientemente he descubierto que es posible que iOS use OpenAL para cambiar de tono.

Estoy mirando al reproductor de banco de sonido de Hollance. tarda alnetworkingedor de 15 notas de piano salpicadas a través del range, y reproduce cualquier nota al determinar qué muestra es la más cercana, y el tono cambia esa muestra por una cantidad apropiada. Este es el código que lo hace:

- (void) noteOn: (int) midiNoteNumber gain: (float) gain { if (!initialized) { NSLog(@"SoundBankPlayer is not initialized yet"); return; } int sourceIndex = [self findAvailableSource]; if (sourceIndex != -1) { alGetError(); // clear any errors Note* note = notes + midiNoteNumber; if (note->bufferIndex != -1) { Buffer* buffer = buffers + note->bufferIndex; Source* source = sources + sourceIndex; source->noteIndex = midiNoteNumber; alSourcef(source->sourceId, AL_PITCH, note->pitch / buffer->pitch); alSourcei(source->sourceId, AL_LOOPING, AL_FALSE); alSourcef(source->sourceId, AL_REFERENCE_DISTANCE, 100.0f); alSourcef(source->sourceId, AL_GAIN, gain); float sourcePos[] = { note->panning, 0.0f, 0.0f }; alSourcefv(source->sourceId, AL_POSITION, sourcePos); alSourcei(source->sourceId, AL_BUFFER, AL_NONE); alSourcei(source->sourceId, AL_BUFFER, buffer->bufferId); ALenum error; if ((error = alGetError()) != AL_NO_ERROR) { NSLog(@"Error attaching buffer to source: %x", error); return; } alSourcePlay(source->sourceId); if ((error = alGetError()) != AL_NO_ERROR) { NSLog(@"Error starting source: %x", error); return; } } } } 

puedes ver esta línea cambia el tono:

  alSourcef(source->sourceId, AL_PITCH, note->pitch / buffer->pitch); 

desafortunadamente, esto no es bueno para jugar un package de notas simultáneamente, ya que requiere demasiada CPU. está cambiando de tono dinámicamente.

lo que quiero es crear un búfer para cada nota de piano y rellenar estos búferes utilizando esta tecnología de cambio de tono. pero no puedo ver cómo conseguir openAL para reproducir el sonido en un búfer en lugar de reproducirlo a través de los altavoces.

¿Hay alguna forma de canalizar la salida de alSourcePlay (source-> sourceId);

¿En un búfer?

Si no puedo hacer esto, ¿cuáles son mis opciones? He intentado usar smbPitchShift desde el artículo DSPDimension, pero no da buena fidelidad: la fase de ataque de la nota de piano está realmente perdida. Creo que podría usar la versión gratuita de Dirac3 … (No tengo dinero para la versión completa en este momento, pero creo que la versión gratuita permite el procesamiento de Mono, por lo que puedo hackear eso). ¿Hay alguna otra opcion?

EDIT: He probado desde entonces Dirac3, y comparte el mismo problema. parece envolver el ataque. parece que el cambio de tono de OpenAL de alguna manera hace algo que Dirac3 no hace.

AlSourcePlayv le permite reproducir varias fonts al mismo time: el número máximo de fonts depende de la plataforma, pero es de 32 en iOS (respondido en la list de audio central de Apple, aquí para ver si está completo)