IPhone: Смешать два аудиофайла программно?

Я хочу иметь два аудиофайла и микшировать и воспроизводить их программно. Когда я играю первый аудиофайл, через какое-то время (динамическое время) мне нужно добавить второй небольшой звуковой файл с первым аудиофайлом, когда где-то посередине первого аудиофайла, тогда, наконец, мне нужно сохранить как один звук файл на устройстве. Он должен воспроизводить аудиофайл со звуком микшера, в который я включил второй.

Я прошел через многие форумы, но не мог понять, как это сделать?

Может кто-то прояснить мои сомнения ниже?

  • В этом случае, какой аудиофайл/формат я должен использовать? Могу ли я использовать файлы .avi?
  • Как добавить второй звук после динамического времени, установленного на первый аудиофайл программным путем? Например: если первое общее время аудио составляет 2 минуты, мне может потребоваться соединить второй аудиофайл (3 секунды аудио) где-нибудь через 1 минуту или 1,5 минуты или 55 секунд первого файла. Его динамика.
  • Как сохранить окончательный выходной аудиофайл на устройстве? Если я где-то сохраню аудиофайл, я могу снова воспроизвести его?

Я не знаю, как этого добиться. Предложите свои мысли!

Ответы

Ответ 1

  • Откройте каждый аудиофайл
  • Прочитать информацию заголовка
  • Получить необработанный несжатый звук в память в виде массива int для каждого файла
  • Начиная с точки в массиве файлов 1, где вы хотите смешать в файле2, выполните цикл, добавив значение file2 int в файл1, не забудьте "закрепить" любые значения выше или ниже max (так вы смешиваете звук... да, это так просто). Если file2 длиннее, вам нужно сделать первый массив достаточно длинным, чтобы полностью сохранить остаток файла2.
  • Введите новую информацию заголовка, а затем аудио из массива, к которому вы добавили файл2.
  • Если задействовано сжатие или файлы не помещаются в память, возможно, вам придется реализовать более сложную схему буферизации.

Ответ 2

В этом случае, какой аудиофайл/формат я должен использовать? Могу ли я использовать .avi файлы?

Вы можете выбрать сжатый или несжатый формат. Общие несжатые форматы включают Wav и AIFF. CAF может представлять сжатые и не сжатые данные..avi не является вариантом (предлагаемым ОС).

Если файлы большие, а пространство для хранения (на диске) вызывает беспокойство, вы можете рассмотреть формат AAC, сохраненный в CAF (или просто .m4a). Для большинства приложений 16-разрядных выборок будет достаточно, и вы также можете сэкономить место, память и процессор, сохранив эти файлы с соответствующей частотой дискретизации (ref: CD - 44,1 кГц).

Поскольку интерфейс ExtAudioFile абстрагирует процесс преобразования, вам не нужно менять свою программу, чтобы сравнить различия в размерах и скорости сжатых и несжатых форматов для вашего дистрибутива (AAC в CAF будет отлично подходит для обычных приложений).

Качество звука без сжатия CD будет потреблять около 5,3 МБ в минуту на канал. Поэтому, если у вас есть 2 стерео аудиофайла, каждые 3 минуты и 3-минутный буфер назначения, объем памяти будет около 50 МБ.

Поскольку у вас есть "минуты" аудио, вам может потребоваться избежать одновременной загрузки всех аудиоданных в память. Чтобы читать, манипулировать и комбинировать аудио, вам понадобится не сжатое представление для работы в памяти, поэтому форматы сжатия здесь не помогут. Кроме того, преобразование сжатого представления в pcm требует большого количества ресурсов; чтение сжатого файла, хотя и меньшее количество байтов, может занять больше (или меньше) времени.

Как добавить второй звук после динамического времени, установленного на первый аудиофайл программным путем? Например: если первое общее время аудио составляет 2 минуты, мне может потребоваться соединить второй аудиофайл (3 секунды аудио) где-нибудь через 1 минуту или 1,5 минуты или 55 секунд первого файла. Его динамика.

Чтобы прочитать файлы и преобразовать их в формат, который вы хотите использовать, используйте API-интерфейсы ExtAudioFile - это будет конвертировать в ваш формат выборки для вас. Общие представления образцов PCM в памяти включают SInt32, SInt16 и float, но это может сильно различаться на основе приложения и оборудования (за пределами iOS). API ExtAudioFile также при необходимости конвертирует сжатые форматы в PCM.

Ваши входные аудиофайлы должны иметь одинаковую частоту дискретизации. Если нет, вам придется перепрограммировать звук, сложный процесс, который также требует много ресурсов (если все сделано правильно/точно). Если вам необходимо поддерживать повторную выборку, удвойте время, которое вы выделили для выполнения этой задачи (не описывая процесс здесь).

Чтобы добавить звуки, вы должны запросить образцы PCM из файлов, обработать и записать в выходной файл (или буфер в памяти).

Чтобы определить, когда добавлять другие звуки, вам нужно получить частоту дискретизации для входных файлов (через ExtAudioFileGetProperty). Если вы хотите записать второй звук в буфер назначения в 55 секунд, вы начнете добавлять звуки на номер образца SampleRate * 55, где SampleRate - частота дискретизации файлов, которые вы читаете.

Чтобы смешивать аудио, вы просто используете эту форму (псевдокод):

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

но вы должны быть уверены, что избегаете превышения/недостаточного потока и других арифметических ошибок. Как правило, вы будете выполнять этот процесс, используя некоторое целочисленное значение, потому что вычисления с плавающей запятой могут занять много времени (когда их так много). Для некоторых приложений вы можете просто сменить и добавить, не беспокоясь о переполнении - это позволит эффективно уменьшить каждый вход на одну половину, прежде чем добавлять их. Амплитуда результата будет равна половине. Если у вас есть контроль над содержимым файлов (например, все они включены в качестве ресурсов), вы можете просто убедиться, что пик в файлах не превысил половину полного значения шкалы (около -6dBFS). Конечно, сохранение как float позволило бы решить эту проблему за счет введения более высоких требований к процессору, памяти и файлам.

На этом этапе у вас будет открыто 2 файла для чтения, а один открыт для записи, а затем несколько небольших временных буферов для обработки и микширования входов перед записью в выходной файл. Вы должны выполнять эти запросы в блоках для повышения эффективности (например, читать 1024 образца из каждого файла, обрабатывать образцы, записывать 1024 сэмпла). API не гарантируют значительную эффективность кэширования и буферизации.

Как сохранить окончательный выходной аудиофайл на устройстве? Если я где-то сохраню аудиофайл, можно ли снова воспроизвести?

API-интерфейсы ExtAudioFile будут работать для ваших нужд чтения и записи. Да, вы можете читать/играть позже.

Ответ 3

Здравствуйте, вы можете сделать это, используя av foundation

- (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;


}

Ответ 4

Если вы собираетесь воспроизводить сразу несколько звуков, определенно используйте формат *.caf. Apple рекомендует воспроизводить сразу несколько звуков. С точки зрения их смешения программно, я предполагаю, что вы просто хотите, чтобы они играли одновременно. В то время как один звук играет, просто скажите, чтобы другой звук играл в любое время, которое вы хотели бы. Чтобы установить определенное время, используйте NSTimer (Справочник по классу NSTimer) и создайте способ воспроизведения звука при срабатывании таймера.