2011-12-26 33 views
14

Tôi muốn có hai tệp âm thanh và trộn và phát nó theo cách lập trình. Khi tôi đang phát tệp âm thanh đầu tiên, sau một thời gian (thời gian động), tôi cần thêm tệp âm thanh nhỏ thứ hai với tệp âm thanh đầu tiên khi ở giữa tệp âm thanh đầu tiên đang phát, sau đó tôi cần lưu dưới dạng một âm thanh trên thiết bị. Nó sẽ chơi các tập tin âm thanh với âm thanh trộn tôi bao gồm một thứ hai.iPhone: Trộn hai tệp âm thanh theo lập trình?

Tôi đã trải qua nhiều diễn đàn, nhưng không thể có được manh mối chính xác làm thế nào để đạt được điều này?

Ai đó có thể làm rõ những nghi ngờ dưới đây của tôi không?

  1. Trong trường hợp này, tôi nên sử dụng định dạng/định dạng âm thanh nào? Tôi có thể sử dụng các tệp .avi không?
  2. Cách thêm âm thanh thứ hai sau khi đặt thời gian động vào tệp âm thanh đầu tiên theo lập trình? Ví dụ: Nếu tổng thời gian âm thanh đầu tiên là 2 phút, tôi có thể cần phải trộn tệp âm thanh thứ hai (âm thanh 3 giây) ở đâu đó trong 1 phút hoặc 1,5 phút hoặc 55 giây của tệp đầu tiên. Năng động của nó.
  3. Làm thế nào để lưu tệp âm thanh đầu ra cuối cùng trên thiết bị? Nếu tôi lưu tệp âm thanh theo chương trình ở đâu đó, tôi có thể phát lại không?

Tôi không biết cách đạt được điều này. Hãy gợi ý suy nghĩ của bạn!

+0

không bạn không thể lưu nó dưới dạng .avi vì một avi chỉ là một container (và có thể chứa video cũng). Tôi không chắc chắn những gì bạn phải sử dụng trên thiết bị iOS nhưng tôi đoán bạn sẽ phải viết một tài liệu wav (nói cách khác là đỉnh âm thanh tinh khiết/sóng). Để kết hợp những thứ bạn cần một kiến ​​thức nâng cao về làm việc với âm thanh mà tôi không có. Và vì vậy tôi không thể nói một số thông tin về điều đó. –

+0

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

Trả lời

0

Nếu bạn định phát nhiều âm thanh cùng một lúc, hãy sử dụng định dạng * .caf. Apple khuyên bạn nên chơi nhiều âm thanh cùng một lúc. Xét về việc trộn chúng theo lập trình, tôi giả sử bạn chỉ muốn chúng chơi cùng một lúc. Trong khi một âm thanh đang phát, chỉ cần nói âm thanh khác để phát bất cứ lúc nào bạn muốn. Để đặt thời gian cụ thể, hãy sử dụng NSTimer (NSTimer Class Reference) và tạo phương thức để phát âm thanh khi bộ hẹn giờ kích hoạt.

6
  • mở từng file audio
  • đọc các thông tin tiêu đề
  • Nhận âm thanh không nén liệu vào bộ nhớ như một mảng ints cho mỗi tập tin
  • Bắt đầu từ điểm trong mảng tập 1 của nơi bạn muốn kết hợp trong tệp 2, lặp lại, thêm giá trị int của tệp2 vào tệp1, hãy chắc chắn 'clip' bất kỳ giá trị nào ở trên hoặc dưới mức tối đa (đây là cách bạn trộn âm thanh ... vâng, nó là đơn giản). Nếu tệp 2 dài hơn, bạn sẽ phải tạo mảng đầu tiên đủ lâu để giữ phần còn lại của tệp2 hoàn toàn.
  • Viết thông tin tiêu đề mới và sau đó là âm thanh từ mảng mà bạn đã thêm tệp2.
  • Nếu có nén liên quan hoặc các tệp sẽ không phù hợp với bộ nhớ, bạn có thể phải triển khai lược đồ đệm phức tạp hơn.
+0

Đơn giản chỉ cần thêm hai luồng với nhau và cắt bớt ở các giá trị cực kỳ không âm thanh (không có ý định chơi chữ) giống như nó sẽ dẫn đến rất đầu ra hữu ích. Hai "đầu vào" cần được thu nhỏ một cách thích hợp để không cần cắt xén. –

+0

Đúng, đó là cơ bản. Hy vọng rằng hai tệp có cùng định dạng, với cùng tốc độ lấy mẫu và không được nén, do đó, việc thêm mảng đơn giản (lưu ý rằng có thể có hai kênh). Lần quét đầu tiên trên dữ liệu sẽ tiết lộ liệu việc cắt có xảy ra hay không và sau đó mở rộng quy mô có thể được áp dụng để duy trì âm lượng tối ưu trong khi tránh cắt bớt. –

+0

@Sedate - Bạn hoàn toàn chính xác! Nhưng nếu bạn nghĩ về ngày ban nhạc trong nhà để xe của bạn với một máy trộn tương tự, bạn sẽ nhớ sự thật không may - đó là cách nó đang ở trong thế giới thực. Âm thanh được trộn lẫn mà không co giãn; khi mức độ quá nhiều, sự biến dạng kết quả thực sự được gọi là 'cắt!' Kỹ thuật Hot Licks đề cập đến được gọi là 'nén' (mặc dù một thực hiện niave) và cho tương tự, đó là một hộp để ném vào rack. Thông thường, tuy nhiên, đáng ngạc nhiên, kết quả không clip. Hãy thử nó trong Audacity (bạn làm bạn một bản sao được cài đặt, không bạn ;-) – FastAl

2

Trong trường hợp này, tôi nên sử dụng định dạng/định dạng âm thanh nào? Tôi có thể sử dụng các tệp .avi không?

Bạn có thể chọn định dạng nén hoặc không nén. Các định dạng không nén phổ biến bao gồm Wav và AIFF. CAF có thể đại diện cho dữ liệu nén và không nén. .avi không phải là một tùy chọn (được cung cấp bởi hệ điều hành).

Nếu các tệp lớn và không gian lưu trữ (trên đĩa) là mối quan ngại, bạn có thể xem xét định dạng AAC được lưu trong CAF (hoặc đơn giản là .m4a).Đối với hầu hết các ứng dụng, các mẫu 16 bit sẽ là đủ và bạn cũng có thể tiết kiệm dung lượng, bộ nhớ và cpu bằng cách lưu các tệp này với tốc độ mẫu thích hợp (ref: CD là 44.1kHz).

Vì giao diện ExtAudioFile trừu tượng quá trình chuyển đổi, bạn không cần phải thay đổi chương trình để so sánh kích thước và tốc độ khác nhau của định dạng nén và không nén cho bản phân phối của bạn (AAC trong CAF sẽ tốt cho các ứng dụng thông thường).

Âm thanh chất lượng CD không nén sẽ tiêu thụ khoảng 5,3 MB mỗi phút, mỗi kênh. Vì vậy, nếu bạn có 2 tệp âm thanh nổi, mỗi 3 phút dài và bộ đệm đích 3 phút, yêu cầu bộ nhớ của bạn sẽ vào khoảng 50 MB.

Vì bạn có 'phút' của âm thanh, bạn có thể cần xem xét việc tránh tải tất cả dữ liệu âm thanh vào bộ nhớ cùng một lúc. Để đọc, thao tác, và kết hợp âm thanh, bạn sẽ cần một đại diện không nén để làm việc với trong bộ nhớ, do đó các định dạng nén sẽ không giúp ích gì ở đây. Đồng thời, việc chuyển đổi một biểu diễn nén thành pcm chiếm một lượng lớn tài nguyên; đọc một tệp nén, mặc dù ít byte hơn, có thể mất nhiều thời gian hơn (hoặc ít hơn).

Cách thêm âm thanh thứ hai sau khi đặt thời gian động vào tệp âm thanh đầu tiên theo chương trình? Ví dụ: Nếu tổng thời gian âm thanh đầu tiên là 2 phút, tôi có thể cần phải trộn tệp âm thanh thứ hai (âm thanh 3 giây) ở đâu đó trong 1 phút hoặc 1,5 phút hoặc 55 giây của tệp đầu tiên. Năng động của nó.

Để đọc tệp và chuyển đổi chúng sang định dạng bạn muốn sử dụng, hãy sử dụng API ExtAudioFile - điều này sẽ chuyển đổi sang định dạng mẫu đích cho bạn. Các biểu diễn mẫu PCM chung trong bộ nhớ bao gồm SInt32, SInt16float, nhưng điều này có thể khác nhau tùy theo ứng dụng và phần cứng (ngoài iOS). ExtAudioFile API cũng sẽ chuyển đổi định dạng nén sang PCM, nếu cần.

Tệp âm thanh đầu vào của bạn phải có cùng tốc độ lấy mẫu. Nếu không, bạn sẽ phải định lại mẫu âm thanh, một quá trình phức tạp cũng mất rất nhiều tài nguyên (nếu được thực hiện đúng/chính xác). Nếu bạn cần hỗ trợ resampling, hãy tăng gấp đôi thời gian bạn đã phân bổ để hoàn thành nhiệm vụ này (không nêu chi tiết quá trình ở đây).

Để thêm âm thanh, bạn sẽ yêu cầu mẫu PCM từ các tệp, xử lý và ghi vào tệp đầu ra (hoặc bộ đệm trong bộ nhớ).

Để xác định thời điểm thêm các âm thanh khác, bạn sẽ cần nhận được tốc độ lấy mẫu cho các tệp đầu vào (qua ExtAudioFileGetProperty). Nếu bạn muốn ghi âm thứ hai vào bộ đệm đích ở 55s, thì bạn sẽ bắt đầu thêm âm thanh ở số mẫu SampleRate * 55, trong đó SampleRate là tốc độ lấy mẫu của các tệp bạn đang đọc.

Để trộn âm thanh, bạn sẽ chỉ dùng biểu mẫu này (giả):

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

nhưng bạn phải chắc chắn rằng bạn tránh trên/underflow và các lỗi số học khác. Thông thường, bạn sẽ thực hiện quá trình này bằng cách sử dụng một số giá trị số nguyên, vì các tính toán dấu phẩy động có thể mất một thời gian dài (khi có quá nhiều). Đối với một số ứng dụng, bạn chỉ có thể thay đổi và thêm vào mà không phải lo lắng về tràn - điều này sẽ làm giảm hiệu quả từng đầu vào một nửa trước khi thêm chúng. Biên độ của kết quả sẽ là một nửa. Nếu bạn có quyền kiểm soát nội dung của tệp (ví dụ: chúng được đóng gói dưới dạng tài nguyên) thì bạn có thể đơn giản đảm bảo không có mẫu đỉnh nào trong các tệp vượt quá một nửa giá trị quy mô đầy đủ (khoảng -6dBFS). Tất nhiên, tiết kiệm như phao sẽ giải quyết vấn đề này tại các chi phí giới thiệu cao hơn CPU, bộ nhớ, và tập tin i/o nhu cầu.

Tại thời điểm này, bạn có 2 tệp đang mở để đọc và một tệp để mở, sau đó một vài bộ đệm tạm thời nhỏ để xử lý và trộn các đầu vào trước khi ghi vào tệp đầu ra. Bạn nên thực hiện các yêu cầu này trong các khối để có hiệu quả (ví dụ: đọc 1024 mẫu từ mỗi tệp, xử lý mẫu, viết 1024 mẫu). Các API không đảm bảo nhiều về bộ nhớ đệm và đệm cho hiệu quả.

Làm cách nào để lưu tệp âm thanh đầu ra cuối cùng trên thiết bị? Nếu tôi lưu tệp âm thanh theo chương trình ở đâu đó, tôi có thể phát lại không?

API ExtAudioFile sẽ hoạt động cho nhu cầu đọc và viết của bạn. Có, bạn có thể đọc/phát sau.

2

Xin chào Bạn có thể làm điều này bằng cách sử dụng nền tảng 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; 


} 
Các vấn đề liên quan