J'ai récemment remarqué qu'il est possible dans iOS d'utiliser OpenAL pour changer de pitch.iOS: Sortie Pitch Shifting & Piping d'OpenAL dans un buffer
Je regarde le lecteur de banque de sons de Hollance. il prend environ 15 notes de piano éparpillées à travers la gamme, et joue n'importe quelle note en déterminant quel échantillon il est le plus proche de, et en transposant cet échantillon d'une quantité appropriée. Ceci est le code qui le fait:
- (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;
}
}
}
}
vous pouvez voir cette ligne ne le pitch shifting:
alSourcef(source->sourceId, AL_PITCH, note->pitch/buffer->pitch);
c'est malheureusement pas bon pour jouer un paquet de notes en même temps, car il prend trop CPU. c'est le pitch qui change dynamiquement. Ce que je veux, c'est créer un tampon pour chaque note de piano, et remplir ces tampons en utilisant cette technologie de pitch shifting. mais je ne vois pas comment ouvrir le son dans un buffer au lieu de le jouer à travers les enceintes.
est-il un moyen de canaliser la sortie de alSourcePlay (source-> sourceId);
dans un tampon?
Si je ne peux pas faire cela, quelles sont mes options? J'ai essayé d'utiliser smbPitchShift de l'article DSPDimension, mais cela ne donne pas une bonne fidélité: la phase d'attaque de la note de piano est vraiment perdue. Je suppose que je pourrais utiliser la version gratuite de Dirac3 ... (je n'ai pas d'argent pour la version complète pour le moment, mais je pense que la version gratuite permet le traitement Mono, donc je peux bidouiller ça). Y a-t-il une autre option?
EDIT: J'ai depuis testé Dirac3, et il partage le même problème. il semble envelopper l'attaque. il semble que le pitch shifter d'OpenAL fasse quelque chose que Dirac3 ne fait pas.
I love questions avec la source d'illustration codes! Merci beaucoup pour ça, ça m'a beaucoup aidé! :) – cregox
Ne pas oublier de le cogner alors;) –