2010-09-18 3 views
1

Я пытаюсь получить необработанные аудиоданные из файла (я привык видеть значения с плавающей запятой между -1 и 1).Core Audio AudioFIleReadPackets ... поиск необработанного звука

Я пытаюсь вытащить эти данные из буферов в реальном времени, чтобы я мог обеспечить некоторый тип измерения для приложения.

Я в основном читаю весь файл в памяти с помощью AudioFileReadPackets. Я создаю аудиоустройство RemoteIO для воспроизведения и внутри проигрывателя playbackCallback, я поставляю mData в AudioBuffer, чтобы его можно было отправить на оборудование.

Большая проблема, с которой я сталкиваюсь, заключается в том, что данные, отправляемые буферам из моего массива данных (из AudioFileReadPackets), являются UInt32 ... Я действительно смущен. Похоже, что это 32-битные, и я установил пакеты/фреймы на 4 байта каждый. Как черт возьми, я получаю свои исходные звуковые данные (от -1 до 1) из этого?

Это мое описание Формат

// Describe format 
audioFormat.mSampleRate   = 44100.00; 
audioFormat.mFormatID   = kAudioFormatLinearPCM; 
audioFormat.mFormatFlags  = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
audioFormat.mFramesPerPacket = 1; 
audioFormat.mChannelsPerFrame = 2; 
audioFormat.mBitsPerChannel  = 16; 
audioFormat.mBytesPerPacket  = 4; 
audioFormat.mBytesPerFrame  = 4; 

Я чтение файла волны в данный момент.

Спасибо!

ответ

0

Посмотрите на эту функцию ... Данные SInt16.

static void recordingCallback (
    void        *inUserData, 
    AudioQueueRef      inAudioQueue, 
    AudioQueueBufferRef     inBuffer, 
    const AudioTimeStamp    *inStartTime, 
    UInt32        inNumPackets, 
    const AudioStreamPacketDescription *inPacketDesc 
) { 


    // This callback, being outside the implementation block, needs a reference to the AudioRecorder object 
    AudioRecorder *recorder = (AudioRecorder *) inUserData; 

    // if there is audio data, write it to the file 
    if (inNumPackets > 0) { 

     SInt16 *frameBuffer = inBuffer->mAudioData; 
     //NSLog(@"byte size %i, number of packets %i, starging packetnumber %i", inBuffer->mAudioDataByteSize, inNumPackets,recorder.startingPacketNumber); 

     //int totalSlices = 1; 
     //int framesPerSlice = inNumPackets/totalSlices; 
     float total = 0; 
     for (UInt32 frame=0; frame<inNumPackets; frame+=20) { 
      total += (float)abs((SInt16)frameBuffer[frame]) ; 
     } 
1

Я не знаю точно, почему вы получаете данные UInt32 назад от этого обратного вызова, хотя я подозреваю, что это на самом деле два переплетенных UInt16 пакеты, по одному на каждый канал. В любом случае, если вы хотите получать данные с плавающей запятой из файла, его нужно преобразовать, и я не уверен, что метод @John Ballinger рекомендует правильно. Мое предложение было бы:

// Get buffer in render/read callback 
SInt16 *frames = inBuffer->mAudioData; 
for(int i = 0; i < inNumPackets; i++) { 
    Float32 currentFrame = frames[i]/32768.0f; 
    // Do stuff with currentFrame (add it to your buffer, etc.) 
} 

Вы не можете просто выделить кадры в желаемый формат. Если вам нужны данные с плавающей запятой, вам необходимо разделить на 32768, что является максимально возможным значением для 16-битных выборок. Это даст правильные данные с плавающей запятой в диапазоне {-1.0 .. 1.0}.

+0

Итак, я взял UInt32 и потянул бит младшего порядка в 1 SInt16, а другой в другой SInt16, и кажется, что каждый из них довольно хорошо представлен двумя отдельными каналами. Я использовал образец кода Арана, который был отредактирован из примерного кода Майкла Болтона о том, как использовать аудиоустройства RemoteIO на iphone, и похоже, что Аран просто передавал оба перемеженных канала в модуль remoteIO как UInt32, потому что он не делал никаких измерений/рисунок волны. После взлома UInt32 в два SInt16, похоже, что все так, как должно быть. – Corey

+0

Кроме того, не обязательно, чтобы данные находились в плавающей запятой. Я создал класс рисования осциллограмм, который ожидает, что данные будут в плавании, и фактически разблокирует аудиофайл и использует функцию AudioFileRead(), чтобы вытащить данные (которые находятся в плавающей точке). Итак, мое приложение делает следующее: По завершении записи вычертите форму волны, открыв записанный файл, прочитав каждый x-образный образец и добавив его в массив, перейдя через результирующий массив и используя графику ядра, чтобы нарисовать Форма волны. Затем, когда пользователь нажимает кнопку воспроизведения, он инициализирует AU. – Corey

+0

А, ок. Так вам удалось решить проблему? –

Смежные вопросы