2011-12-26 19 views
14

मैं दो ऑडियो फाइलें बनाना चाहता हूं और इसे प्रोग्रामेटिक रूप से मिलाकर खेलना चाहता हूं। जब मैं पहली ऑडियो फ़ाइल खेल रहा हूं, कुछ समय बाद (गतिशील समय) मुझे पहली ऑडियो फ़ाइल के साथ दूसरी छोटी ऑडियो फ़ाइल जोड़ने की आवश्यकता होती है जब पहली ऑडियो फ़ाइल के बीच कहीं भी मध्य होता है, तो आखिरकार मुझे एक ऑडियो के रूप में सहेजने की ज़रूरत होती है डिवाइस पर फ़ाइल करें। इसे मिक्सर ऑडियो के साथ ऑडियो फ़ाइल खेलनी चाहिए जिसमें मैंने दूसरा शामिल किया था।आईफोन: दो ऑडियो फाइलों को प्रोग्रामेटिक रूप से मिलाएं?

मैं कई मंचों से गुज़र चुका हूं, लेकिन यह समझ नहीं पाया कि यह कैसे प्राप्त किया जाए?

क्या कोई मेरे नीचे दिए गए संदेहों को स्पष्ट कर सकता है?

  1. इस मामले में, मुझे किस ऑडियो फ़ाइल/प्रारूप का उपयोग करना चाहिए? क्या मैं .avi फाइलों का उपयोग कर सकता हूं?
  2. प्रोग्रामिंग के पहले ऑडियो फ़ाइल पर गतिशील समय सेट के बाद दूसरा ऑडियो कैसे जोड़ें? पूर्व के लिए: यदि पहला ऑडियो कुल समय 2 मिनट है, तो मुझे दूसरी फ़ाइल फ़ाइल (3 सेकंड ऑडियो) को कहीं भी 1 मिनट या 1.5 मिनट या पहली फ़ाइल के 55 सेकंड में मिश्रण करने की आवश्यकता हो सकती है। इसकी गतिशील
  3. डिवाइस पर अंतिम आउटपुट ऑडियो फ़ाइल को कैसे सहेजना है? अगर मैं प्रोग्राम फ़ाइल को प्रोग्रामेटिक रूप से कहीं सेव करता हूं, तो क्या मैं फिर से खेल सकता हूं?

मुझे नहीं पता कि इसे कैसे प्राप्त किया जाए। कृपया अपने विचारों का सुझाव दें!

+0

कोई आप क्योंकि एक avi केवल एक कंटेनर है .avi के रूप में यह नहीं बचा सकता है (और वीडियो के रूप में अच्छी तरह से शामिल कर सकते हैं) ऐसा कर सकते हैं। मुझे यकीन नहीं है कि आपको आईओएस डिवाइस पर क्या उपयोग करना है, लेकिन मुझे लगता है कि आपको एक वैव दस्तावेज़ लिखना होगा (दूसरे शब्दों में शुद्ध ऑडियो चोटियों/तरंगें)। उन लोगों के संयोजन के लिए आपको ऑडियो के साथ काम करने का एक उन्नत ज्ञान चाहिए जो मेरे पास नहीं है। और इसलिए मैं इसके बारे में कुछ जानकारीपूर्ण नहीं कहूंगा। –

+0

http://developer.apple.com/library/ios/#codinghowtos/AudioAndVideo/_index.html –

उत्तर

0

यदि आप एक साथ कई ध्वनियां चलाने जा रहे हैं, तो निश्चित रूप से * .caf प्रारूप का उपयोग करें। ऐप्पल एक बार में कई ध्वनियों को चलाने के लिए सिफारिश करता है। उन्हें प्रोग्रामेटिक रूप से मिश्रण करने के मामले में, मुझे लगता है कि आप उन्हें एक ही समय में खेलना चाहते हैं। जबकि एक आवाज चल रही है, बस जब भी आप चाहें तो दूसरी आवाज़ खेलने के लिए कहें। एक विशिष्ट समय निर्धारित करने के लिए, एनएसटीमर (NSTimer Class Reference) का उपयोग करें और टाइमर आग लगने पर ध्वनि चलाने के लिए एक विधि बनाएं।

6
  • ओपन प्रत्येक ऑडियो फ़ाइल
  • हैडर जानकारी पढ़ें
  • प्रत्येक फ़ाइल
  • फ़ाइल 1 के सरणी में बिंदु जहाँ आप मिश्रण करना चाहते हैं पर प्रारंभ के लिए ints की एक सरणी के रूप में स्मृति में कच्चे असम्पीडित ऑडियो जाओ फ़ाइल 2 में, फ़ाइल 1 के लिए फ़ाइल 2 का int मान जोड़कर, लूप को अधिकतम, ऊपर या नीचे किसी भी मान को 'क्लिप' करना सुनिश्चित करें (इस प्रकार आप ऑडियो को मिश्रित करते हैं ... हाँ, यह है कि सरल)। यदि फ़ाइल 2 लंबा है, तो आपको फ़ाइल की शेष राशि को पूरी तरह से पकड़ने के लिए पर्याप्त पहली सरणी बनाना होगा।
  • नई शीर्षलेख जानकारी लिखें और उसके बाद सरणी से ऑडियो जिसे आपने फ़ाइल 2 जोड़ा है।
  • यदि संपीड़न शामिल है या फ़ाइलें स्मृति में फिट नहीं होंगी, तो आपको अधिक जटिल बफरिंग योजना लागू करनी पड़ सकती है।
+0

बस दो धाराओं को एक साथ जोड़ना और चरम मूल्यों पर क्लिपिंग करना ध्वनि नहीं है (कोई इरादा नहीं है) जैसे परिणामस्वरूप उपयोगी आउटपुट दो "इनपुट" को उचित तरीके से स्केल किया जाना चाहिए ताकि कोई छंटनी न हो। –

+0

हाँ, यह अनिवार्य रूप से यह है। उम्मीद है कि दो फाइलें एक ही प्रारूप में हैं, उसी नमूना दर पर, और संपीड़ित नहीं हैं, इसलिए यह सरणी जोड़ का एक "सरल" मामला है (ध्यान में रखते हुए कि दो चैनल होने की संभावना है)। डेटा पर पहला स्कैन यह प्रकट करेगा कि क्लिपिंग होगा या नहीं, और तब क्लिपिंग से बचते समय इष्टतम वॉल्यूम को बनाए रखने के लिए स्केलिंग लागू की जा सकती है। –

+0

@ सेडेट - आप बिल्कुल सही हैं! लेकिन अगर आप अपने गेराज बैंड दिनों में इस्तेमाल किए गए एनालॉग मिक्सर के साथ सोचते हैं, तो आपको दुर्भाग्यपूर्ण सत्य याद आएगा - यही वह असली दुनिया में है। ध्वनि स्केलिंग के बिना मिश्रित होते हैं; जब स्तर बहुत अधिक होते हैं, परिणामी विकृति वास्तव में 'क्लिपिंग' कहा जाता है! हॉट लिक्स उल्लेख तकनीक को 'संपीड़न' कहा जाता है (यद्यपि एक निएव कार्यान्वयन) और एनालॉग के लिए, यह रैक में फेंकने का एक और बॉक्स है। आमतौर पर, हालांकि, आश्चर्यजनक रूप से, परिणाम क्लिप नहीं है। ऑडैसिटी में इसे आज़माएं (आप एक प्रतिलिपि स्थापित करते हैं, आप नहीं ;-) – FastAl

2

इस मामले में, मुझे किस ऑडियो फ़ाइल/प्रारूप का उपयोग करना चाहिए? क्या मैं .avi फाइलों का उपयोग कर सकता हूं?

आप एक संपीड़ित या गैर संपीड़ित प्रारूप चुन सकते हैं। सामान्य गैर संपीड़ित प्रारूपों में वेव और एआईएफएफ शामिल हैं। सीएएफ संपीड़ित और गैर संपीड़ित डेटा का प्रतिनिधित्व कर सकते हैं। .avi एक विकल्प नहीं है (ओएस द्वारा पेश किया गया)।

यदि फ़ाइलें बड़ी हैं और डिस्क स्थान पर (डिस्क पर) एक चिंता है, तो आप एएसी प्रारूप को सीएएफ (या बस .m4a) में सहेज सकते हैं।अधिकांश अनुप्रयोगों के लिए, 16 बिट नमूने पर्याप्त होंगे, और आप इन फ़ाइलों को उचित नमूना दर पर सहेजकर अंतरिक्ष, स्मृति और सीपीयू को भी बचा सकते हैं (रेफरी: सीडी 44.1kHz हैं)।

चूंकि ExtAudioFile इंटरफ़ेस रूपांतरण प्रक्रिया को सारणी देता है, इसलिए आपको अपने वितरण के लिए संपीड़ित और गैर-संपीड़ित प्रारूपों के आकार और गति अंतर की तुलना करने के लिए अपने प्रोग्राम को बदलना नहीं चाहिए (सीएएफ में एएसी सामान्य अनुप्रयोगों के लिए ठीक होगा)।

असंपीड़ित सीडी गुणवत्ता ऑडियो प्रति चैनल लगभग 5.3 एमबी प्रति मिनट का उपभोग करेगा। तो यदि आपके पास 2 स्टीरियो ऑडियो फ़ाइलें हैं, प्रत्येक 3 मिनट लंबी, और एक 3 मिनट का गंतव्य बफर है, तो आपकी मेमोरी आवश्यकता लगभग 50 एमबी होगी।

चूंकि आपके पास ऑडियो का 'मिनट' है, तो आपको एक ही समय में सभी ऑडियो डेटा को स्मृति में लोड करने से बचने की आवश्यकता हो सकती है। ऑडियो को पढ़ने, छेड़छाड़ करने और गठबंधन करने के लिए, आपको मेमोरी में काम करने के लिए एक गैर संपीड़ित प्रतिनिधित्व की आवश्यकता होगी, इसलिए संपीड़न प्रारूप यहां मदद नहीं करेंगे। साथ ही, संकुचित प्रतिनिधित्व को पीसीएम में परिवर्तित करने से संसाधनों की एक अच्छी मात्रा होती है; एक संपीड़ित फ़ाइल को पढ़ना, हालांकि कम बाइट्स, अधिक (या कम) समय ले सकते हैं।

प्रोग्रामिंग के पहले ऑडियो फ़ाइल पर गतिशील समय सेट के बाद दूसरा ऑडियो कैसे जोड़ें? पूर्व के लिए: यदि पहला ऑडियो कुल समय 2 मिनट है, तो मुझे दूसरी फ़ाइल फ़ाइल (3 सेकंड ऑडियो) को कहीं भी 1 मिनट या 1.5 मिनट या पहली फ़ाइल के 55 सेकंड में मिश्रण करने की आवश्यकता हो सकती है। इसकी गतिशील

फ़ाइलों को पढ़ने और उन्हें प्रारूप, जिसका उपयोग आप का उपयोग करने के ExtAudioFile एपीआई चाहते करने के लिए कनवर्ट करने के लिए - यह आपके लिए अपने गंतव्य नमूना प्रारूप करने के लिए परिवर्तित कर देंगे। स्मृति में सामान्य पीसीएम नमूना प्रस्तुतियों में SInt32, SInt16, और float शामिल हैं, लेकिन यह एप्लिकेशन और हार्डवेयर (आईओएस से परे) के आधार पर जंगली रूप से भिन्न हो सकता है। यदि आवश्यक हो तो ExtAudioFile एपीआई संकुचित प्रारूपों को पीसीएम में भी परिवर्तित कर देगा।

आपकी इनपुट ऑडियो फ़ाइलों में एक ही नमूना दर होनी चाहिए। यदि नहीं, तो आपको ऑडियो को एक जटिल प्रक्रिया को दोहराना होगा, जिसमें बहुत सारे संसाधन भी होंगे (यदि सही तरीके से/सही तरीके से किया जाता है)। यदि आपको रीसाम्पलिंग का समर्थन करने की आवश्यकता है, तो इस कार्य को पूरा करने के लिए आवंटित समय को दोगुना करें (यहां प्रक्रिया का विवरण नहीं दे रहा है)।

ध्वनि जोड़ने के लिए, आप फ़ाइलों, प्रक्रियाओं और आउटपुट फ़ाइल (या स्मृति में बफर) को पीसीएम नमूने से अनुरोध करेंगे।

अन्य ध्वनियों को जोड़ने का निर्धारण करने के लिए, आपको इनपुट फ़ाइलों के लिए नमूना दर प्राप्त करने की आवश्यकता होगी (ExtAudioFileGetProperty के माध्यम से)। यदि आप 55 बजे गंतव्य बफर को दूसरी ध्वनि लिखना चाहते हैं, तो आप नमूना संख्या SampleRate * 55 पर ध्वनि जोड़ना शुरू कर देंगे, जहां SampleRate आपके द्वारा पढ़ी जा रही फ़ाइलों की नमूना दर है।

ऑडियो मिश्रण के लिए, आप बस इस फ़ॉर्म (स्यूडोकोड) का उपयोग करेगा:

mixed[i] = fileA[i] + fileB[i]; 

लेकिन क्या आप वाकई/अधःप्रवाह और अन्य अंकगणितीय त्रुटियों से अधिक से बचने रहना होगा। आम तौर पर, आप कुछ पूर्णांक मान का उपयोग करके इस प्रक्रिया को निष्पादित करेंगे, क्योंकि फ़्लोटिंग पॉइंट गणनाओं में काफी समय लग सकता है (जब बहुत सारे होते हैं)। कुछ अनुप्रयोगों के लिए, आप केवल ओवरफ्लो की कोई चिंता नहीं कर सकते हैं और जोड़ सकते हैं - इससे प्रभावी रूप से प्रत्येक इनपुट को एक आधे से कम करने से पहले उन्हें कम कर दिया जाएगा। परिणाम का आयाम एक आधा होगा। यदि आपके पास फाइलों की सामग्री पर नियंत्रण है (उदा। वे सभी संसाधनों के रूप में बंडल किए गए हैं) तो आप बस यह सुनिश्चित कर सकते हैं कि फाइलों में कोई चरम नमूना पूर्ण पैमाने मान (लगभग -6 डीबीएफएस) के आधा से अधिक नहीं है। बेशक, फ्लोट के रूप में बचत उच्च समस्या, स्मृति, और फ़ाइल I/o मांगों को पेश करने के खर्च पर इस मुद्दे को हल करेगी।

इस बिंदु पर, आपके पास पढ़ने के लिए 2 फाइलें खुली होंगी, और लेखन के लिए एक खुली होगी, फिर आउटपुट फ़ाइल में लिखने से पहले इनपुट को प्रोसेस करने और मिश्रण करने के लिए कुछ छोटे अस्थायी बफर होंगे। आपको इन अनुरोधों को दक्षता के लिए ब्लॉक में करना चाहिए (उदाहरण के लिए प्रत्येक फ़ाइल से 1024 नमूने पढ़ें, नमूने को संसाधित करें, 1024 नमूने लिखें)। एपीआई दक्षता के लिए कैशिंग और बफरिंग के बारे में ज्यादा गारंटी नहीं देते हैं।

डिवाइस पर अंतिम आउटपुट ऑडियो फ़ाइल को कैसे सहेजना है? अगर मैं प्रोग्राम फ़ाइल को प्रोग्रामेटिक रूप से कहीं सेव करता हूं, तो क्या मैं फिर से खेल सकता हूं?

ExtAudioFile API आपके पढ़ने और लिखने की ज़रूरतों के लिए काम करेंगे। हां, आप बाद में इसे पढ़/खेल सकते हैं।

2

नमस्ते आप av नींव का उपयोग कर

- (BOOL) combineVoices1 
{ 
    NSError *error = nil; 
    BOOL ok = NO; 


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 


    CMTime nextClipStartTime = kCMTimeZero; 
    //Create AVMutableComposition Object.This object will hold our multiple AVMutableCompositionTrack. 
    AVMutableComposition *composition = [[AVMutableComposition alloc] init]; 

    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack setPreferredVolume:0.8]; 
    NSString *soundOne =[[NSBundle mainBundle]pathForResource:@"test1" ofType:@"caf"]; 
    NSURL *url = [NSURL fileURLWithPath:soundOne]; 
    AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil]; 
    NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeAudio]; 
    AVAssetTrack *clipAudioTrack = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil]; 

    AVMutableCompositionTrack *compositionAudioTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack setPreferredVolume:0.3]; 
    NSString *soundOne1 =[[NSBundle mainBundle]pathForResource:@"test" ofType:@"caf"]; 
    NSURL *url1 = [NSURL fileURLWithPath:soundOne1]; 
    AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:url1 options:nil]; 
    NSArray *tracks1 = [avAsset1 tracksWithMediaType:AVMediaTypeAudio]; 
    AVAssetTrack *clipAudioTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    [compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack1 atTime:kCMTimeZero error:nil]; 


    AVMutableCompositionTrack *compositionAudioTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionAudioTrack2 setPreferredVolume:1.0]; 
    NSString *soundOne2 =[[NSBundle mainBundle]pathForResource:@"song" ofType:@"caf"]; 
    NSURL *url2 = [NSURL fileURLWithPath:soundOne2]; 
    AVAsset *avAsset2 = [AVURLAsset URLAssetWithURL:url2 options:nil]; 
    NSArray *tracks2 = [avAsset2 tracksWithMediaType:AVMediaTypeAudio]; 
    AVAssetTrack *clipAudioTrack2 = [[avAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    [compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset2.duration) ofTrack:clipAudioTrack2 atTime:kCMTimeZero error:nil]; 



    AVAssetExportSession *exportSession = [AVAssetExportSession 
              exportSessionWithAsset:composition 
              presetName:AVAssetExportPresetAppleM4A]; 
    if (nil == exportSession) return NO; 

    NSString *soundOneNew = [documentsDirectory stringByAppendingPathComponent:@"combined10.m4a"]; 
    //NSLog(@"Output file path - %@",soundOneNew); 

    // configure export session output with all our parameters 
    exportSession.outputURL = [NSURL fileURLWithPath:soundOneNew]; // output path 
    exportSession.outputFileType = AVFileTypeAppleM4A; // output file type 

    // perform the export 
    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 

     if (AVAssetExportSessionStatusCompleted == exportSession.status) { 
      NSLog(@"AVAssetExportSessionStatusCompleted"); 
     } else if (AVAssetExportSessionStatusFailed == exportSession.status) { 
      // a failure may happen because of an event out of your control 
      // for example, an interruption like a phone call comming in 
      // make sure and handle this case appropriately 
      NSLog(@"AVAssetExportSessionStatusFailed"); 
     } else { 
      NSLog(@"Export Session Status: %d", exportSession.status); 
     } 
    }]; 


    return YES; 


} 
संबंधित मुद्दे