Comment utiliser une unité audio sur l'iPhone
-
20-08-2019 - |
Question
Je cherche un moyen de changer la hauteur de l’audio enregistré lorsqu’il est sauvegardé sur le disque ou lu (en temps réel). Je comprends que Audio Units peut être utilisé pour cela. L'iPhone offre une prise en charge limitée des unités audio (par exemple, il est impossible de créer / utiliser des unités audio personnalisées, pour autant que je sache), mais plusieurs unités audio prêtes à l'emploi sont disponibles, dont l'une est AUPitch.
Comment utiliser exactement une unité audio (en particulier AUPitch)? Le raccordez-vous à une file d’audio? Est-il possible de chaîner des unités audio ensemble (par exemple, d'ajouter simultanément un effet d'écho et un changement de hauteur)?
EDIT: Après avoir inspecté les en-têtes du SDK de l’iPhone (je pense que AudioUnit.h, je ne suis pas face à un Mac pour le moment), j’ai remarqué que AUPitch était mis en commentaire. Donc, il ne semble pas que AUPitch soit disponible sur l'iPhone, après tout. pleurer pleurer
Apple semble avoir mieux organisé la documentation de son kit de développement logiciel (SDK) pour iPhone sur developer.apple.com - il est maintenant plus difficile de trouver des références à AUPitch, etc.
Cela dit, je suis toujours intéressé par des réponses de qualité sur l'utilisation de Audio Units (en général) sur l'iPhone.
La solution
Il existe de très bonnes ressources ici ( http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/ ) pour utiliser l'unité audio RemoteIO. Dans mon expérience de travail avec Audio Units sur l'iPhone, j'ai constaté que je pouvais implémenter une transformation manuellement dans la fonction de rappel. Ce faisant, vous constaterez peut-être que cela résout votre problème.
Autres conseils
En ce qui concerne le changement de ton sur l'iPhone, OpenAL est la voie à suivre. Découvrez la classe SoundManager disponible sur www.71squared.com pour un excellent exemple de moteur de son OpenAL prenant en charge la tonalité.
- (void)modifySpeedOf:(CFURLRef)inputURL byFactor:(float)factor andWriteTo:(CFURLRef)outputURL {
ExtAudioFileRef inputFile = NULL;
ExtAudioFileRef outputFile = NULL;
AudioStreamBasicDescription destFormat;
destFormat.mFormatID = kAudioFormatLinearPCM;
destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
destFormat.mSampleRate = 44100 * factor;
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 1;
destFormat.mBitsPerChannel = 16;
destFormat.mReserved = 0;
ExtAudioFileCreateWithURL(outputURL, kAudioFileCAFType,
&destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile);
ExtAudioFileOpenURL(inputURL, &inputFile);
//find out how many frames is this file long
SInt64 length = 0;
UInt32 dataSize2 = (UInt32)sizeof(length);
ExtAudioFileGetProperty(inputFile,
kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);
SInt16 *buffer = (SInt16*)malloc(kBufferSize * sizeof(SInt16));
UInt32 totalFramecount = 0;
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = 1;
bufferList.mBuffers[0].mData = buffer; // pointer to buffer of audio data
bufferList.mBuffers[0].mDataByteSize = kBufferSize *
sizeof(SInt16); // number of bytes in the buffer
while(true) {
UInt32 frameCount = kBufferSize * sizeof(SInt16) / 2;
// Read a chunk of input
ExtAudioFileRead(inputFile, &frameCount, &bufferList);
totalFramecount += frameCount;
if (!frameCount || totalFramecount >= length) {
//termination condition
break;
}
ExtAudioFileWrite(outputFile, frameCount, &bufferList);
}
free(buffer);
ExtAudioFileDispose(inputFile);
ExtAudioFileDispose(outputFile);
}
cela changera la hauteur en fonction du facteur
J'ai déjà utilisé l'unité audio NewTimePitch pour cela auparavant, la description du composant audio est
var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter,
componentSubType: kAudioUnitSubType_NewTimePitch,
componentManufacturer: kAudioUnitManufacturer_Apple,
componentFlags: 0,
componentFlagsMask: 0)
alors vous pouvez changer le paramètre de hauteur avec un appel AudioUnitSetParamater. Par exemple, cela change la hauteur de -1 000 centimes
err = AudioUnitSetParameter(newTimePitchAudioUnit,
kNewTimePitchParam_Pitch,
kAudioUnitScope_Global,
0,
-1000,
0)
Les paramètres de cette unité audio sont les suivants
// Parameters for AUNewTimePitch
enum {
// Global, rate, 1/32 -> 32.0, 1.0
kNewTimePitchParam_Rate = 0,
// Global, Cents, -2400 -> 2400, 1.0
kNewTimePitchParam_Pitch = 1,
// Global, generic, 3.0 -> 32.0, 8.0
kNewTimePitchParam_Overlap = 4,
// Global, Boolean, 0->1, 1
kNewTimePitchParam_EnablePeakLocking = 6
};
mais il vous suffira de changer le paramètre de hauteur pour vos besoins. Pour un guide sur la façon de mettre en œuvre cela, reportez-vous à la réponse de Justin