Wie eine Audioeinheit auf dem iPhone verwenden,
-
20-08-2019 - |
Frage
Ich bin auf der Suche nach einer Möglichkeit, die Tonhöhe des aufgezeichneten Audio zu ändern, wie es auf der Festplatte gespeichert wird, oder wiedergegeben werden (in Echtzeit). Ich verstehe, Audio Units kann hierfür verwendet werden. Das iPhone bietet begrenzte Unterstützung für Audio Units (zum Beispiel ist es nicht möglich zu erstellen / verwenden, um benutzerdefinierte Audiogeräte, soweit ich das beurteilen kann), aber einige out-of-the-Box-Audio-Geräte verfügbar sind, von denen eine AUPitch.
Wie genau würde ich verwenden, um eine Audio-Einheit (speziell AUPitch)? irgendwie Haben Sie es in eine Audio-Warteschlange Haken? Ist es möglich, Ketten Audio-Einheiten zusammen (zum Beispiel, um gleichzeitig einen Echo-Effekt und eine Änderung in der Tonhöhe hinzufügen)?
EDIT: Nach dem iPhone SDK Header Inspektion (ich glaube, AudioUnit.h, ich bin nicht vor einem Mac im Moment), bemerkte ich, dass AUPitch Kommentar gesetzt ist. So sieht es nicht wie AUPitch auf dem iPhone nach allen zur Verfügung steht. weep weep
Apple-scheint besser organisiert zu haben, um ihre iPhone-SDK-Dokumentation auf developer.apple.com von spät - jetzt seinem schwierigen Verweise auf AUPitch zu finden, usw.
Das heißt, ich bin immer noch interessiert an Qualität Antworten auf Audio Units mit (im Allgemeinen) auf dem iPhone.
Lösung
Es gibt einige sehr gute Ressourcen hier ( http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/ ) für die RemoteIO Audio Einheit. Nach meiner Erfahrung mit Audio Units auf dem iPhone funktioniert, habe ich festgestellt, dass ich eine Transformation manuell in der Callback-Funktion implementieren kann. Dabei könnten Sie feststellen, dass löst man Probleme.
Andere Tipps
In Bezug auf Tonhöhe auf dem iPhone zu ändern, ist OpenAL der Weg zu gehen. Schauen Sie sich die Soundmanager-Klasse erhältlich von www.71squared.com für ein großartiges Beispiel für eine OpenAL Sound-Engine, die Tonhöhe unterstützt.
- (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);
}
es wird Tonhöhe basierend auf dem Faktor
Ich habe die NewTimePitch Audioeinheit für diese vor der Verwendung, für die Audio-Komponente Beschreibung dh
var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter,
componentSubType: kAudioUnitSubType_NewTimePitch,
componentManufacturer: kAudioUnitManufacturer_Apple,
componentFlags: 0,
componentFlagsMask: 0)
, dann können Sie die Pitch-Parameter mit einem AudioUnitSetParamater Anruf ändern. Zum Beispiel ändert sich die Tonhöhe von -1000 Cent
err = AudioUnitSetParameter(newTimePitchAudioUnit,
kNewTimePitchParam_Pitch,
kAudioUnitScope_Global,
0,
-1000,
0)
Die Parameter für diese Audio-Einheit sind wie folgt
// 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
};
aber Sie brauchen nur die Tonhöhe Parameter für Ihre Zwecke zu ändern. Für eine Anleitung, wie man Justin Antwort implementieren diese beziehen