2011-10-24 9 views
12

मैं आईफोन में एक फॉर्म में ऑडियो प्राप्त करने पर काम कर रहा हूं जहां मैं इसे (सी ++) विश्लेषण एल्गोरिदम में पास कर सकता हूं। बेशक, कई विकल्प हैं: ऑडियो क्यू ट्यूटोरियल at trailsinthesand चीजें शुरू हो गईं।आईओएस में AudioQueueRef से फ्लोट ऑडियो डेटा की सरणी कैसे प्राप्त करें?

ऑडियो कॉलबैक, हालांकि, AudioQueueRef देता है, और मुझे चीजों के इस तरफ ऐप्पल के दस्तावेज पतले मिल रहे हैं। फ़ाइल में लिखने के लिए अंतर्निहित विधियां, लेकिन डेटा देखने के लिए वास्तव में पैकेट के अंदर जहां भी आप सहकर्मी नहीं देखते हैं।

मुझे डेटा चाहिए। मैं किसी फ़ाइल में कुछ भी लिखना नहीं चाहता, जो कि सभी ट्यूटोरियल - और यहां तक ​​कि ऐप्पल की सुविधा I/O ऑब्जेक्ट्स भी है - ऐसा लगता है। ऐप्पल का AVAudioRecorder (क्रूरता से) आपको स्तर देगा और डेटा लिख ​​देगा, लेकिन वास्तव में आपको इसका उपयोग नहीं करेगा। जब तक मैं कुछ याद नहीं कर रहा हूं ...

यह कैसे करें? नीचे दिए गए कोड में inBuffer->mAudioData है जो tantalizingly बंद है लेकिन मुझे इस बारे में कोई जानकारी नहीं मिल सकती है कि यह 'डेटा' किस प्रारूप में है या इसे कैसे पहुंचाया जाए।

AudioQueue कॉलबैक:

void AudioInputCallback(void *inUserData, 
    AudioQueueRef inAQ, 
    AudioQueueBufferRef inBuffer, 
    const AudioTimeStamp *inStartTime, 
    UInt32 inNumberPacketDescriptions, 
    const AudioStreamPacketDescription *inPacketDescs) 
{ 
    static int count = 0; 
    RecordState* recordState = (RecordState*)inUserData;  
    AudioQueueEnqueueBuffer(recordState->queue, inBuffer, 0, NULL); 

    ++count; 
    printf("Got buffer %d\n", count); 
} 

और कोड एक फाइल करने के लिए ऑडियो लिखने के लिए:

OSStatus status = AudioFileWritePackets(recordState->audioFile, 
       false, 
       inBuffer->mAudioDataByteSize, 
       inPacketDescs, 
       recordState->currentPacket, 
       &inNumberPacketDescriptions, 
       inBuffer->mAudioData); // THIS! This is what I want to look inside of. 
if(status == 0) 
{ 
    recordState->currentPacket += inNumberPacketDescriptions; 
} 

उत्तर

10
// so you don't have to hunt them all down when you decide to switch to float: 
    #define AUDIO_DATA_TYPE_FORMAT SInt16 

    // the actual sample-grabbing code: 
    int sampleCount = inBuffer->mAudioDataBytesCapacity/sizeof(AUDIO_DATA_TYPE_FORMAT); 
    AUDIO_DATA_TYPE_FORMAT *samples = (AUDIO_DATA_TYPE_FORMAT*)inBuffer->mAudioData; 

तो फिर आप अपने राशि सरणी samples (इस मामले SInt16 में) जो आप कर सकते हैं samples[0] से samples[sampleCount-1] तक पहुंच। ।

+0

यह "नमूने" सरणी, इसमें नमूने के कितने सेकंड शामिल हैं? यह रिकॉर्ड किए गए ऑडियो का यह बाइनरी प्रतिनिधित्व है? –

+0

"नमूने" में एक बफर के नमूने के लायक होते हैं। लंबाई सेकंड बफर आकार और नमूना दर पर निर्भर करता है: 44.1kHz पर 512 नमूने 512/44100 = .011609977 सेकंड है। – buildsucceeded

0

ऊपर समाधान मेरे लिए काम नहीं किया, मैं (एक endian मुद्दा) गलत नमूना डेटा ही हो रही थी जड़ना भविष्य में कोई गलत नमूना डेटा हो रही है, तो मुझे आशा है कि इस मदद करता है:

- (शून्य) feedSamplesToEngine: (UInt32) ऑडियोडेटाइट्स क्षमता ऑडियोडाटा: (शून्य *) ऑडियोडेटा { int sampleCount = audioDataBytesCapacity/sizeof (SAMPLE_TYPE);

SAMPLE_TYPE *samples = (SAMPLE_TYPE*)audioData; 
//SAMPLE_TYPE *sample_le = (SAMPLE_TYPE *)malloc(sizeof(SAMPLE_TYPE)*sampleCount);//for swapping endians 

std::string shorts; 
double power = pow(2,10); 
for(int i = 0; i < sampleCount; i++) 
{ 
    SAMPLE_TYPE sample_le = (0xff00 & (samples[i] << 8)) | (0x00ff & (samples[i] >> 8)) ; //Endianess issue 
    char dataInterim[30]; 
    sprintf(dataInterim,"%f ", sample_le/power); // normalize it. 
    shorts.append(dataInterim); 
} 
संबंधित मुद्दे