현재 아이폰의 마이크에서 미리 정의 된 주파수 (16780Hz)로 크기를 계산하는 응용 프로그램을 만들고 있습니다.코어 오디오, Goertzel 알고리즘이 작동하지 않습니다.
버퍼에 소리 데이터가 있고이 작업을 위해 고안된 알고리즘 인 Goertzel을 사용하여 처리하려고합니다. Goertzel info. 문제가 시작되는 곳입니다.
소리가 정의 된 것 (16780Hz)보다 훨씬 낮은 (5000Hz) 주파수로 녹음 될 때 알고리즘은 매우 긍정적 인 결과를 나타냅니다. 실제로 올바른 주파수의 사운드가 녹음 될 때 생성되는 결과보다 훨씬 긍정적 인 결과를 얻습니다. 그것에서
이-(void)startListeningWithFrequency:(float)frequency;
{
OSStatus status;
//AudioComponentInstance audioUnit;
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
status = AudioComponentInstanceNew(inputComponent, &audioUnit);
checkStatus(status);
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input,kInputBus, &flag, sizeof(flag));
checkStatus(status);
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;//44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
// float
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus,
&audioFormat,
sizeof(audioFormat));
checkStatus(status);
//status = AudioUnitSetProperty(audioUnit,
// kAudioUnitProperty_StreamFormat,
// kAudioUnitScope_Input,
// kOutputBus,
// &audioFormat,
// sizeof(audioFormat));
checkStatus(status);
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = recordingCallback;
callbackStruct.inputProcRefCon = self;
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
kInputBus, &callbackStruct, sizeof(callbackStruct));
checkStatus(status);
/* UInt32 shouldAllocateBuffer = 1;
AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer));
*/
status = AudioOutputUnitStart(audioUnit);
}
static OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
AudioBuffer buffer;
buffer.mNumberChannels = 1;
buffer.mDataByteSize = inNumberFrames * 2;
//NSLog(@"%d",inNumberFrames);
buffer.mData = malloc(inNumberFrames * 2);
// Put buffer in a AudioBufferList
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0] = buffer;
OSStatus status;
status = AudioUnitRender(audioUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
&bufferList);
checkStatus(status);
//double g = calculateGoertzel((const char *)(&bufferList)->mBuffers[0].mData,16789.0,96000.0);
UInt16 *q = (UInt16 *)(&bufferList)->mBuffers[0].mData;
int N = sizeof(q)/sizeof(UInt16);
double Qr,Qi;
double theta = 2.0*M_PI*16780/44100;
double g = goertzel(q,44100,16780,N);
NSLog(@"goertzel:%f", g);
}
이 16780Hz보다 훨씬 낮은 주파수의 수백의 숫자를 반환 관련된 모든 경우에 나는 오디오를 검색하는 방법을
다음double goertzel(unsigned short *sample, int sampleRate, double Freq, int len)
{
double realW = 2.0 * cos(2.0 * M_PI * Freq/sampleRate);
double imagW = 2.0 * sin(2.0 * M_PI * Freq/sampleRate);
double d1 = 0;
double d2 = 0;
int z;
double y;
for (int i = 0; i < len; i++) {
y=(double)(signed short)sample[i] +realW * d1 - d2;
d2 = d1;
d1 = y;
}
double rR = 0.5 * realW *d1-d2;
double rI = 0.5 * imagW *d1-d2;
return (sqrt(pow(rR, 2)+pow(rI,2)))/len;
} /* end function goertzel */
은 다음과 같습니다
는 goertzel의 내 구현 16780Hz의 주파수의 경우 훨씬 더 작은 수를 반환합니다.저는 매우 좌절하고 도움을 주시면 감사하겠습니다.
불행히도, 나는 사인파로만 테스트 해왔다. (더 이상의 제안? 샘플링 속도를 두 배로 늘려 보았습니다. – 123hal321
샘플링 할 수 없다면 샘플 속도를 두 배로 늘리면 iPhone에서 작동하지 않을 수도 있습니다. 샘플링 속도를 다시 읽어야 샘플을 받아 들일 수 있습니다. 또한 세션 속성에서 샘플 속도를 먼저 설정하여 자동으로 그것이 무엇을해야하는지 생각하지 않도록 할 수 있습니다. 기본 샘플링 속도 : – Vagrant
Float64 preferredSampleRate = audioFormat-> mSampleRate, XThrowIfError (AudioSessionSetProperty (kAudioSessionProperty_PreferredHardwareSampleRate이 는 sizeof (preferredSampleRate), preferredSampleRate)); – Vagrant