Как получить аудио образцы музыки в iPod Library во время ее воспроизведения? - PullRequest
2 голосов
/ 14 марта 2012

Мне нужно, чтобы аудио образцы музыки iPod воспроизводились в режиме реального времени.

Приложение EQu (http://itunes.apple.com/us/app/equ-the-quality-equalizer/id403704212?mt=8) достигло этого или не может применить свои фильтры, я думаю.

Я пробовал некоторые методы, но все тщетно.

Все, что я мог сделать, это использовать AVAssetReader and Writer для сохранения локального преобразованного файла музыки iPod и воспроизведения его с использованием низкоуровневых методов, таких как AudioUnit? Я думаю, этот локальный файл может быть очень большим.

Спасибо, ребята.

1 Ответ

1 голос
/ 26 сентября 2013

Несколько шагов:

I. Создайте свой локальный буфер, как в примере ниже, и вы должны убедиться, что
a: при записи в буфер достаточно свободного места
b: при чтении из буфера достаточно данных
глядя на чтение / запись idx

</p> <pre><code>typedef struct { //suppose non-interleaved LEI16 LPCM format SInt16 data[MUSIC_RING_BUFFER_NUM_CHANNEL][MUSIC_RING_BUFFER_SIZE]; UInt16 readIdx; UInt16 writeIdx; } MyRingBuffer;

II. Каждый раз получайте некоторые необработанные данные из AVAssetTrackOuput, например

</p> <pre><code>CMSampleBufferRef nextBuffer = [self.trackOutput copyNextSampleBuffer]; CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer( nextBuffer ); size_t lengthAtOffset; size_t totalLength; char* data; if( CMBlockBufferGetDataPointer( buffer, 0, &lengthAtOffset, &totalLength, &data ) != noErr ) { NSLog( @"error!" ); return; } //raw audio sample data now in (char*) data

III. Затем скопируйте данные в локальный буфер

Необработанные данные для 16-битного LPCM без чередования будут такими, как


    [2 bytes data x N, from left channel][2 bytes data x N from right channel]

используйте memcpy для копирования в локальный буфер и обновления writeIdx

  • Затем напишите функцию обратного вызова входного рендеринга для EQ AudioUnit, она читает из вашего локального буфера и обновляет readIdx в других потоках. И он вызывает заполнение буфера в другом потоке , если места достаточно, например

</p> <pre><code>[self performSelectorOnMainThread:@selector(fillMusicBuffer:) withObject:Nil waitUntilDone:NO];

Кстати, всегда проверяя настройки аудиоформата одинаковые или нет. Получить информацию ASBD из CMSampleBufferRef и сравнить с настройкой входа AudioUnit </p> <pre><code>const AudioStreamBasicDescription *audioDescription = CMAudioFormatDescriptionGetStreamBasicDescription(CMSampleBufferGetFormatDescription(nextBuffer));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...