iPhone에서 오디오 장치를 사용하는 방법
-
20-08-2019 - |
문제
녹음 된 오디오의 피치가 디스크에 저장되거나 다시 재생 될 때 (실시간으로) 재생 될 수있는 방법을 찾고 있습니다. 오디오 장치가 사용될 수 있다는 것을 이해합니다. iPhone은 오디오 장치에 대한 제한된 지원을 제공합니다 (예 : 내가 알 수있는 한 사용자 정의 오디오 장치를 만들거나 사용할 수는 없습니다). 그러나 몇 가지 상자 오디오 장치를 사용할 수 있습니다. 그 중 하나는 Aupitch입니다.
오디오 장치 (특히 Aupitch)를 정확히 어떻게 사용합니까? 어떻게 든 오디오 대기열에 연결합니까? 오디오 장치를 함께 체인 할 수 있습니까 (예 : 에코 효과와 피치의 변화를 동시에 추가하기 위해)?
편집 : iPhone SDK 헤더를 검사 한 후 (Audiounit.h라고 생각합니다. 지금은 Mac 앞에 있지 않음) Aupitch에 댓글을 달았습니다. 결국 Aupitch가 iPhone에서 사용할 수있는 것처럼 보이지 않습니다. 울다 울다
Apple은 Developer.apple.com에서 iPhone SDK 문서를 더 잘 정리 한 것으로 보입니다. 이제 Aupitch 등에 대한 참조를 찾기가 더 어렵습니다.
즉, 저는 여전히 iPhone에서 오디오 장치 (일반적으로) 사용에 대한 품질 답변에 관심이 있습니다.
해결책
여기에는 아주 좋은 자원이 있습니다 (http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/) 원격 오디오 장치를 사용합니다. iPhone에서 오디오 장치를 사용한 경험에서 콜백 기능에서 수동으로 변환을 구현할 수 있음을 발견했습니다. 그렇게하면 문제가 해결 될 수 있습니다.
다른 팁
iPhone의 피치 변경과 관련하여 Openal은가는 길입니다. 피치를 지원하는 개방형 사운드 엔진의 훌륭한 예는 www.71squared.com에서 구할 수있는 SoundManager 클래스를 확인하십시오.
- (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);
}
요인에 따라 피치가 변경됩니다
이전에 NewTimePitch 오디오 장치를 사용했는데, 오디오 구성 요소 설명은
var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter,
componentSubType: kAudioUnitSubType_NewTimePitch,
componentManufacturer: kAudioUnitManufacturer_Apple,
componentFlags: 0,
componentFlagsMask: 0)
그런 다음 AudiounitsetParamater 호출로 피치 매개 변수를 변경할 수 있습니다. 예를 들어 피치가 -1000 센트 만 변경됩니다
err = AudioUnitSetParameter(newTimePitchAudioUnit,
kNewTimePitchParam_Pitch,
kAudioUnitScope_Global,
0,
-1000,
0)
이 오디오 장치의 매개 변수는 다음과 같습니다
// 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
};
그러나 목적을 위해 피치 매개 변수 만 변경하면됩니다. 이 구현 방법에 대한 가이드는 저스틴의 답변을 참조하십시오.