Получение значений уровня из необработанных данных PCM с использованием Core Audio - PullRequest
0 голосов
/ 30 октября 2010

Я пытаюсь извлечь данные уровня из аудиофайла PCM с помощью основного звука. Я дошел до (я считаю) получения необработанных данных в байтовый массив (UInt8), но это 16-битные данные PCM, и у меня возникают проблемы с чтением данных. Вход от микрофона iPhone, который я установил как:

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
[recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];

[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

что, очевидно, 16 бит. Затем я пытаюсь просто распечатать несколько значений, чтобы увидеть, выглядят ли они ниже для целей отладки, и не выглядят ли они разумными (многие 0).

ExtAudioFileRef inputFile = NULL; ExtAudioFileOpenURL (track.location, & inputFile);

AudioStreamBasicDescription inputFileFormat;
UInt32 dataSize = (UInt32)sizeof(inputFileFormat);
ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileDataFormat, &dataSize, &inputFileFormat);

UInt8 *buffer = malloc(BUFFER_SIZE);
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = 1;
bufferList.mBuffers[0].mData = buffer; //pointer to buffer of audio data
bufferList.mBuffers[0].mDataByteSize = BUFFER_SIZE; //number of bytes in the buffer

while(true) {

    UInt32 frameCount = (bufferList.mBuffers[0].mDataByteSize / inputFileFormat.mBytesPerFrame);

    // Read a chunk of input
    OSStatus status = ExtAudioFileRead(inputFile, &frameCount, &bufferList);

    // If no frames were returned, conversion is finished
    if(0 == frameCount)
        break;

    NSLog(@"---");

    int16_t *bufferl = &buffer;
    for(int i=0;i<100;i++){
        //const int16_t *bufferl = bufferl[i];
        NSLog(@"%d",bufferl[i]);
    }

}

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

Ответы [ 2 ]

1 голос
/ 30 декабря 2010

Вы выделяете буфер 8-битных целых без знака, а затем преобразуете его адрес в 16-битное целое число без знака.ka-boom.

то, что вы хотите сделать в цикле for, - преобразовать bufferList.mBuffers [0] .mData в SInt16 *, а затем выполнить итерацию по нему, чтобы вывести ваши значения.* вам вообще не нужен ваш буфер var.(для этого)

0 голосов
/ 22 ноября 2010

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

bufferList.mBuffers[0].mData = nil;
bufferList.mBuffers[0].mDataByteSize = 0;

Кроме того, вы должны использовать значения в bufferList после вызова read вместо того, чтобы предполагать, что они те же, что вы передали.

SInt16 *buffer = (SInt16 *)bufferList.mBuffers[0].mData;
for (UInt32 i=0; i< frameCount; i++) {
    NSLog (@"%d", buffer[i]);
}
...