2011-08-03 7 views
10

से इस सवाल का नए सिरे से लिखना थोड़ा और succient किया जाना है।लिखें ऑडियो करने के लिए डिस्क आईओ यूनिट

मेरी समस्या यह है कि मैं रिमोट आईओ यूनिट से डिस्क पर ऑडियो फ़ाइल सफलतापूर्वक लिख नहीं सकता।

चरणों मैं ले लिया

के लिए खुला एक एमपी 3 फ़ाइल थे और बफ़र्स के लिए अपनी ऑडियो निकालें। मैंने ग्राफ के गुणों के आधार पर अपने ग्राफ के साथ उपयोग करने के लिए एक asbd सेट अप किया है। मैं अपने ग्राफ को निकालने और चलाने के लिए एक्स्ट्राक्टेड ऑडियो और ध्वनि सफलतापूर्वक स्पीकर बाहर आता है!

मुझे जो समस्या हो रही है वह दूरस्थ आईओ कॉलबैक से ऑडियो नमूने ले रहा है और उन्हें डिस्क पर एक ऑडियो फ़ाइल में लिख रहा है जिसे मैं ExtAudioFileWriteASync का उपयोग कर रहा हूं।

ऑडियो फ़ाइल लिखी जाती है और मूल एमपी 3 के लिए कुछ श्रव्य समानता भालू होती है लेकिन यह बहुत विकृत लगता है।

मुझे यकीन है कि अगर समस्या

है ए) ExtAudioFileWriteAsync नहीं कर सकते जितनी जल्दी कब इकाई कॉलबैक उन्हें प्रदान करता है नमूने नहीं लिख रहा हूँ।

  • या -

बी) मैं extaudiofile refeference गलत के लिए ASBD की स्थापना की है। मैं एक WAV फ़ाइल को सहेजना शुरू करना चाहता था। मुझे यकीन नहीं है कि मैंने नीचे एएसबीडी में इसे सही तरीके से वर्णित किया है।

दूसरा, मुझे अनिश्चितता है कि ऑडियो फ़ाइल बनाते समय CHannelLayout संपत्ति के लिए कितना मूल्य पारित करना है।

और आखिर में मैं एईबीडी के बारे में बहुत अनिश्चित हूं कि kExtAudioFileProperty_ClientDataFormat के लिए क्या उपयोग करना है। मैं अपने स्टीरियो स्ट्रीम प्रारूप का उपयोग कर रहा था लेकिन दस्तावेज़ों पर एक नज़र डालने का कहना है कि यह पीसीएम होना चाहिए। क्या यह रिमोटियो के आउटपुट के समान प्रारूप होना चाहिए? और यदि मैं रिमोट io से स्टीरियोस्ट्रीमफॉर्मेट के आउटपुट प्रारूप को सेट करना गलत था?

मुझे एहसास है कि इस सवाल में बहुत कुछ है और मुझे बहुत अनिश्चितताएं हैं जिन्हें मैं अपने आप को साफ़ नहीं कर सकता।

सेटअप स्टीरियो स्ट्रीम प्रारूप

- (void) setupStereoStreamFormat 
{ 

    size_t bytesPerSample = sizeof (AudioUnitSampleType); 
    stereoStreamFormat.mFormatID   = kAudioFormatLinearPCM; 
    stereoStreamFormat.mFormatFlags  = kAudioFormatFlagsAudioUnitCanonical; 
    stereoStreamFormat.mBytesPerPacket = bytesPerSample; 
    stereoStreamFormat.mFramesPerPacket = 1; 
    stereoStreamFormat.mBytesPerFrame  = bytesPerSample; 
    stereoStreamFormat.mChannelsPerFrame = 2;     // 2 indicates stereo 
    stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample; 
    stereoStreamFormat.mSampleRate  = engineDescribtion.samplerate; 

    NSLog (@"The stereo stereo format :"); 


} 

सेटअप remoteio कॉलबैक स्टीरियो धारा प्रारूप का उपयोग कर

AudioUnitSetProperty(engineDescribtion.masterChannelMixerUnit, 
          kAudioUnitProperty_StreamFormat, 
          kAudioUnitScope_Output, 
          masterChannelMixerUnitloop, 
          &stereoStreamFormat, 
          sizeof(stereoStreamFormat)); 

     AudioUnitSetProperty(engineDescribtion.masterChannelMixerUnit, 
          kAudioUnitProperty_StreamFormat, 
          kAudioUnitScope_Input, 
          masterChannelMixerUnitloop, 
          &stereoStreamFormat, 
          sizeof(stereoStreamFormat)); 




static OSStatus masterChannelMixerUnitCallback(void *inRefCon, 
           AudioUnitRenderActionFlags *ioActionFlags, 
           const AudioTimeStamp *inTimeStamp, 
           UInt32 inBusNumber, 
           UInt32 inNumberFrames, 
           AudioBufferList *ioData) 

{ 

    // ref.equnit; 
    //AudioUnitRender(engineDescribtion.channelMixers[inBusNumber], ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 
    Engine *engine= (Engine *) inRefCon; 
    AudioUnitRender(engineDescribtion.equnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 

    if(engine->isrecording) 
    { 
     ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData); 

    } 


    return 0; 

} 

** रिकॉर्डिंग सेटअप **

-(void)startrecording 

{ 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    destinationFilePath = [[NSString alloc] initWithFormat: @"%@/testrecording.wav", documentsDirectory]; 
    destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); 

    OSStatus status; 

    // prepare a 16-bit int file format, sample channel count and sample rate 
    AudioStreamBasicDescription dstFormat; 
    dstFormat.mSampleRate=44100.0; 
    dstFormat.mFormatID=kAudioFormatLinearPCM; 
    dstFormat.mFormatFlags=kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; 
    dstFormat.mBytesPerPacket=4; 
    dstFormat.mBytesPerFrame=4; 
    dstFormat.mFramesPerPacket=1; 
    dstFormat.mChannelsPerFrame=2; 
    dstFormat.mBitsPerChannel=16; 
    dstFormat.mReserved=0; 

    // create the capture file 
    status= ExtAudioFileCreateWithURL(destinationURL, kAudioFileWAVEType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &recordingfileref); 
    CheckError(status ,"couldnt create audio file"); 
     // set the capture file's client format to be the canonical format from the queue 
status=ExtAudioFileSetProperty(recordingfileref, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &stereoStreamFormat); 

    CheckError(status ,"couldnt set input format"); 

    ExtAudioFileSeek(recordingfileref, 0); 
isrecording=YES; 

    // [documentsDirectory release]; 


} 

संपादित 1

मैं वास्तव में अंधेरे में अब यहाँ चोट पहुंचा रहा हूँ, लेकिन मैं kExtAudioFileProperty_ClientDataFormat कि की देखभाल करता है एक ऑडियो कनवर्टर का उपयोग करने की जरूरत है या करते हैं?

संपादित 2

इम ऑडियो के 2 नमूने संलग्न। पहले मूल ऑडियो कि इम पाशन और नक़ल करने की कोशिश है। दूसरा उस लूप का रिकॉर्ड किया गया ऑडियो है। उम्मीद है कि यह किसी को क्या गलत हो रहा है के रूप में एक सुराग दे सकता है।

Original mp3

Problem recording of mp3

+0

बेवकूफ सवाल, लेकिन क्या आपने यह देखने के लिए जांच की कि क्या 'sizeof (AudioUnitSampleType);' वही आकार देता है जैसा आप 'myytesPerPacket' को असाइन कर रहे हैं? –

+0

मुझे यकीन है कि होने की जाँच की डबल। वे दोनों एक ही आकार हैं। – dubbeat

+0

@dubbeat एचवी यू रिकॉर्डिंग ऑडियो – Aadil

उत्तर

9

आँसू खींच & बाल मैं एक समाधान है की कुछ दिनों के बाद।

मेरे कोड में और अन्य उदाहरणों में मैंने देखा है कि extaudiofilewriteasync को रिमोटियो यूनिट के लिए कॉलबैक में बुलाया गया था।

** remoteiounit कॉलबैक **

static OSStatus masterChannelMixerUnitCallback(void *inRefCon, 
           AudioUnitRenderActionFlags *ioActionFlags, 
           const AudioTimeStamp *inTimeStamp, 
           UInt32 inBusNumber, 
           UInt32 inNumberFrames, 
           AudioBufferList *ioData) 

{ 


    AudioUnitRender(engineDescribtion.equnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 


    if(isrecording) 
    { 
     ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData); 


    } 



    return 0; 

} 

इस कॉलबैक में मैं EQs लागू होता है और मिक्स ऑडियो है कि एक और ऑडियो इकाई से ऑडियो डेटा खींच रहा हूँ।

मैं इस अन्य कॉलबैक करने remoteio कॉलबैक से extaudiofilewriteasync कॉल हटा दिया कि remoteio खींचती है और फ़ाइल सफलतापूर्वक लिखते हैं !!

* कॉलबैक फ़ंक्शन *

static OSStatus outputCallback(void *inRefCon, 
           AudioUnitRenderActionFlags *ioActionFlags, 
           const AudioTimeStamp *inTimeStamp, 
           UInt32 inBusNumber, 
           UInt32 inNumberFrames, 
           AudioBufferList *ioData) { 


    AudioUnitRender(engineDescribtion.masterChannelMixerUnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData); 

    //process audio here  

    Engine *engine= (Engine *) inRefCon; 


    OSStatus s; 

    if(engine->isrecording) 
    { 
     s=ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData); 


    } 


    return noErr; 

} 

equnits पूरी तरह से समझ क्यों मेरे समाधान काम क्यों डेटा लेखन remoteio की iodata bufferlist से फाइल करने के लिए किसी को मुझे समझा सकता है के हित में विकृत ऑडियो लेकिन लेखन का कारण बनता है डेटा एक और सही श्रृंखला में परिणाम परिणाम नीचे कदम?

+0

साथ यह किया है कि आप अपने समाधान समझा सकते हैं। मुझे एक ही समस्या का सामना करना पड़ रहा है। कॉलबैक में फ़ाइल में लिखा गया ऑडियो डेटा विकृत है। हमें किस कॉलबैक में लिखना चाहिए? – Namratha

+0

यह वास्तव में अपने AUGraph पर निर्भर करता है। अनुभव से मुझे जो मिला है वह है कि रिमोटियो (नोड 0) के आउटपुट कॉलबैक से डिस्क पर ऑडियो लिखने का प्रयास अक्सर काम नहीं करता है। इसके बजाय इसे किसी अन्य नोड के लिए इनपुट कॉलबैक में रखें। यदि आप स्रोत कोड के साथ एक पूर्ण प्रश्न लिखते हैं तो मैं आपको और अधिक मदद करने में सक्षम हो सकता हूं। – dubbeat