5

마이크 데이터에 FFT를 실행하는 응용 프로그램을 만들려고합니다. 예를 들면 다음과 같습니다. 입력에서 가장 큰 주파수.AVCaptureAudioDataOutput 데이터를 vDSP/Accelerate.framework에 전달합니다.

오디오 입력 (RemoteIO AudioUnit, AudioQueue 서비스 및 AVFoundation)을 가져 오는 데는 여러 가지 방법이 있지만 AVFoundation이 가장 단순한 것처럼 보입니다. 이 설치 프로그램이 있습니다 :

// Configure the audio session 
AVAudioSession *session = [AVAudioSession sharedInstance]; 
[session setCategory:AVAudioSessionCategoryRecord error:NULL]; 
[session setMode:AVAudioSessionModeMeasurement error:NULL]; 
[session setActive:YES error:NULL]; 

// Optional - default gives 1024 samples at 44.1kHz 
//[session setPreferredIOBufferDuration:samplesPerSlice/session.sampleRate error:NULL]; 

// Configure the capture session (strongly-referenced instance variable, otherwise the capture stops after one slice) 
_captureSession = [[AVCaptureSession alloc] init]; 

// Configure audio device input 
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:NULL]; 
[_captureSession addInput:input]; 

// Configure audio data output 
AVCaptureAudioDataOutput *output = [[AVCaptureAudioDataOutput alloc] init]; 
dispatch_queue_t queue = dispatch_queue_create("My callback", DISPATCH_QUEUE_SERIAL); 
[output setSampleBufferDelegate:self queue:queue]; 
[_captureSession addOutput:output]; 

// Start the capture session. 
[_captureSession startRunning]; 

(오류 검사, 읽기 쉽도록 생략 됨).

그런 다음 나는 다음과 같은 AVCaptureAudioDataOutputSampleBufferDelegate 메소드를 구현 :

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{ 
    NSLog(@"Num samples: %ld", CMSampleBufferGetNumSamples(sampleBuffer)); 
    // Usually gives 1024 (except the first slice) 
} 

내가 다음 단계가 될해야하는지 확실 해요. CMSampleBuffer 형식이 정확히 무엇을 설명합니까? (있을 경우 어떤 가정을 할 수 있습니까?) 가능한 여분의 전처리가 가능한 최소량의 오디오 데이터를 vDSP_fft_zrip으로 어떻게 가져올 수 있습니까? (내가 본 원시 데이터가 정확한지 확인하기 위해 무엇을 권하고 싶습니다.)

답변

6

CMSampleBufferRef은 0 개 이상의 미디어 샘플을 포함하는 불투명 한 유형입니다.

http://developer.apple.com/library/ios/#documentation/CoreMedia/Reference/CMSampleBuffer/Reference/reference.html

그렇게 버퍼에 오디오뿐만 아니라 샘플 형식의 설명 및 타이밍 정보를 포함 할 것이고,이 경우, 다음 문서에 선전의 비트가있다. 정말로 관심이 있다면 위임 콜백에 중단 점을 넣고 살펴보십시오. 16 개 비트 샘플

// get a pointer to the audio bytes 
CMItemCount numSamples = CMSampleBufferGetNumSamples(sampleBuffer); 
CMBlockBufferRef audioBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); 
size_t lengthAtOffset; 
size_t totalLength; 
char *samples; 
CMBlockBufferGetDataPointer(audioBuffer, 0, &lengthAtOffset, &totalLength, &samples); 

아이폰 마이크의 기본 샘플 형식 리니어 PCM이다

첫 단계는 리턴 된 데이터 버퍼에 대한 포인터를 취득하기위한 것이다. 외부 마이크가 있는지 여부에 따라 모노 또는 스테레오 일 수 있습니다. FFT를 계산하려면 float 벡터가 있어야합니다.

// check what sample format we have 
// this should always be linear PCM 
// but may have 1 or 2 channels 
CMAudioFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer); 
const AudioStreamBasicDescription *desc = CMAudioFormatDescriptionGetStreamBasicDescription(format); 
assert(desc->mFormatID == kAudioFormatLinearPCM); 
if (desc->mChannelsPerFrame == 1 && desc->mBitsPerChannel == 16) { 
    float *convertedSamples = malloc(numSamples * sizeof(float)); 
    vDSP_vflt16((short *)samples, 1, convertedSamples, 1, numSamples); 
} else { 
    // handle other cases as required 
} 

지금 당신은 당신이 vDSP_fft_zrip 사용할 수있는 샘플 버퍼의 부동 소수점 벡터가 : 다행히 우리를 위해 변환을 수행하는 기능을 가속화있다. AVFoundation으로 마이크에서 입력 샘플을 부동 샘플로 변경하는 것이 가능하지 않으므로이 마지막 변환 단계가 계속됩니다. 실제로는 버퍼를 계속 유지하면서 더 큰 버퍼가 도착하면 필요에 따라 다시 할당하므로 모든 대리자 콜백을 사용하여 버퍼를 mallocing 및 freeing하지 않습니다.

마지막 질문에 대해 가장 쉬운 방법은 알려진 입력을 주입하고 올바른 응답을 제공하는지 확인하는 것입니다. 사인파를 마이크에 대고 FFT가 정확한 주파수 빈 (bin)에 피크를 가지고 있는지 확인할 수 있습니다. 내가 3 개 이유로 AVFoundation을 사용하지 않는 것이 좋습니다

+0

"iPhone 마이크의 기본 오디오 형식은 16 비트 정수의 단일 채널입니다."-이 정보는 어디에서 유래됩니까? 나는 이와 같은 가정을하는 것이 일반적으로 서로 다른 장치 하드웨어를 통해 안전하지 않을 것이라고 우려하고 있습니다. – jtbandes

+0

맞습니다. 어쨌든 가정은 사실 거짓이었습니다. 오디오 형식을 확인하기 위해 업데이트했습니다. AVCapture 기본값에 대한 일부 의견은 다음과 같습니다. http://developer.apple.com/library/ios/#samplecode/AVCaptureToAudioUnit/Listings/CaptureSessionController_mm.html – Tark

1

:

  1. 난 내 애플 리케이션 (morsedec, irtty)의 일부를 사용, 그것은 그러나 다른 사람에 완전히, 시뮬레이터 및 일부 하드웨어에서 잘 작동 실패했습니다!
  2. 형식 샘플링 속도를 제대로 제어 할 수 없습니다.
  3. 대기 시간이 길어질 수 있습니다.

사과의 샘플 코드 aurioTouch로 시작하는 것이 좋습니다. FFT를 만들려면 순환 버퍼 (I LOVE https://github.com/michaeltyson/TPCircularBuffer)를 사용하여 vDSP 프레임 워크로 이동할 수 있습니다.

희망 FAQ

관련 문제