5

में AVCaptureAudioDataOutput डेटा पास करना मैं माइक्रोफोन डेटा पर एक एफएफटी चलाता हूं जो एक एप्लीकेशन बनाने की कोशिश कर रहा हूं, इसलिए मैं उदाहरण की जांच कर सकता हूं। इनपुट में सबसे तेज आवृत्ति।वीडीएसपी/एक्सीलरेट.फ्रेमवर्क

मुझे लगता है कि ऑडियो इनपुट (रिमोटियो ऑडियो यूनीट, ऑडियोक्यूयू सेवाएं, और 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

इस मामले में यह इतने पर एक ऑडियो बफर, साथ ही नमूना प्रारूप का वर्णन और समय में जानकारी होती है और होगा: वहाँ डॉक्स में blurb का एक सा है। यदि आप वास्तव में रुचि रखते हैं तो प्रतिनिधि कॉलबैक में ब्रेकपॉइंट डालें और एक नज़र डालें। 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); 

iPhone माइक के लिए डिफ़ॉल्ट नमूना प्रारूप, रैखिक पीसीएम है:

पहला कदम डेटा बफर करने के लिए एक सूचक है कि लौटा दिया गया है पाने के लिए है। बाहरी माइक या नहीं होने पर यह मोनो या स्टीरियो हो सकता है। एफएफटी की गणना करने के लिए हमें एक फ्लोट वेक्टर होना चाहिए।

// 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 के साथ नमूने फ्लोट करने के लिए माइक्रोफ़ोन से इनपुट प्रारूप को बदलना संभव नहीं लगता है, इसलिए आप इस अंतिम रूपांतरण चरण से फंस गए हैं। मैं प्रैक्टिस में बफर के आसपास रखता हूं, जब एक बड़ा बफर आता है तो उन्हें फिर से आवंटित करता है, ताकि आप प्रत्येक प्रतिनिधि कॉलबैक के साथ बफर को मॉलोकिंग और फ्री नहीं कर रहे हों।

आपके अंतिम प्रश्न के लिए, मुझे लगता है कि ऐसा करने का सबसे आसान तरीका ज्ञात इनपुट इंजेक्ट करना होगा और जांचें कि यह आपको सही प्रतिक्रिया देता है। आप माइक में साइन लहर चला सकते हैं और जांच सकते हैं कि आपके एफएफटी की सही आवृत्ति बिन में एक चोटी थी, ऐसा कुछ।

+0

"iPhone माइक के लिए डिफ़ॉल्ट ऑडियो प्रारूप 16 बिट पूर्णांकों का एक चैनल है" - जहां इस जानकारी से आता है? मुझे चिंता है कि इस तरह की धारणाएं सामान्य रूप से विभिन्न डिवाइस हार्डवेयर में असुरक्षित होंगी। – jtbandes

+0

आप सही हैं, और वास्तव में धारणा वास्तव में झूठी थी, मैंने ऑडियो प्रारूप की जांच करने के लिए अद्यतन किया है। AVCapture डिफ़ॉल्ट के बारे में यहां कुछ टिप्पणियां: http://developer.apple.com/library/ios/#samplecode/AVCaptureToAudioUnit/Listings/CaptureSessionController_mm.html – Tark

1

मैं 3 कारण के लिए AVFoundation उपयोग करने के लिए सुझाव है कि नहीं है:

  1. मैं मेरा क्षुधा (morsedec, irtty) से कुछ के लिए यह प्रयोग किया जाता है, यह सिम्युलेटर पर और कुछ हार्डवेयर में अच्छी तरह से काम करता है, लेकिन दूसरों में पूरी तरह से अनुत्तीर्ण होना !
  2. आपके पास नमूना दर प्रारूप का अच्छा नियंत्रण नहीं है।
  3. विलंबता उच्च हो सकती है।

मैं सेब के नमूना कोड aurioTouch से शुरू करने का सुझाव देता हूं। एफएफटी बनाने के लिए आप एक परिपत्र बफर (मैं https://github.com/michaeltyson/TPCircularBuffer प्यार) का उपयोग कर वीडीएसपी ढांचे में स्थानांतरित कर सकते हैं।

आशा इस मदद