2015-06-16 4 views
1

В настоящее время я разрабатываю VoIP-приложение, и одна из библиотек, которые я использую, требует от меня отправки кадров во входном обратном вызове. Требования состоят в том, что я должен отправить счетчик выборок, который определяется как количество выборок в кадре. Этот обратный вызов будет вызван каждый раз, когда микрофон берет новые образцы.VoIP, ограничивающий количество кадров в rendercallback

Допустимые номера (частота дискретизации) * (длина аудио)/1000. Если длина аудио может составлять 2,5, 5, 10, 20, 40 или 60 миллисекунд.

Прежде чем использовать kAudioUnitProperty_MaximumFramesPerSlice, чтобы ограничить число в InNumberFrames до 960, он постоянно приближался к 1115 inNumberFrames. Поэтому я решил ограничить это, установив это свойство. Однако, когда я это делаю, это приводит к тому, что число InNumberFrames уменьшается до 512 ??? Подхожу ли я к этой проблеме неправильно?

static OSStatus inputRenderCallBack(void *inRefCon, 
            AudioUnitRenderActionFlags *ioActionFlags, 
            const AudioTimeStamp *inTimeStamp, 
            UInt32 inBusNumber, 
            UInt32 inNumberFrames, //512 
            AudioBufferList *ioData) 
{ 
    AudioBufferList bufferList; 
    bufferList.mNumberBuffers = 1; 
    bufferList.mBuffers[0].mNumberChannels = kNumberOfChannels; 
    bufferList.mBuffers[0].mData = NULL; 
    bufferList.mBuffers[0].mDataByteSize = inNumberFrames * sizeof(SInt16) * kNumberOfChannels; 

    OCTAudioEngine *engine = (__bridge OCTAudioEngine *)(inRefCon); 
    OSStatus status = AudioUnitRender(engine.ioUnit, 
             ioActionFlags, 
             inTimeStamp, 
             inBusNumber, 
             inNumberFrames, 
             &bufferList); 
    NSError *error; 
    [engine.toxav sendAudioFrame:bufferList.mBuffers[0].mData 
        sampleCount:kSampleCount //960 
         channels:kNumberOfChannels //2 
         sampleRate:[engine currentAudioSampleRate] //24000 
         toFriend:engine.friendNumber 
          error:&error]; 

    return status; 
} 
+1

В чем причина, по которой вы пытаетесь ограничить количество кадров? Большинство из этих проблем лучше решать с помощью циклического буфера. Проверьте этот [вопрос] (http://stackoverflow.com/questions/30691684/whats-the-reason-of-using-circular-buffer-in-ios-audio-calling-app/30698791#30698791). – dave234

+0

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

+0

Зачем избегать кругового буфера? Они дешевы и решают вашу проблему. – dave234

ответ

1

Вы можете (и должны) использовать kAudioUnitProperty_MaximumFramesPerSlice для указания максимального числа выборок в кадр, а не предпочтительного числа; обратитесь к техническому руководству Apple Q & A QA1533 и QA1606. Чтобы установить предпочтительное количество выборок на кадр, используйте метод setPreferredIOBufferDuration:error:AVAudioSession. Например, если частота дискретизации составляет 32 000, вы можете использовать:

NSError *error = nil; 
NSTimeInterval bufferDuration = 0.008; 
[session setPreferredIOBufferDuration:bufferDuration error:&error]; 

, чтобы установить длину кадра до 256, потому что 32,000 * 0,008 = 256.

Однако следует отметить, что метод setPreferredIOBufferDuration:error: устанавливает этот предпочитаемый номер, но не точное номер. Вы можете указать длину кадра для операционной системы, но иногда из-за ограничений оборудования вы можете не получить именно то, что хотите, но что-то близкое к нему.