Несоответствие частоты дискретизации на выходе CoreAudio - PullRequest
0 голосов
/ 29 апреля 2018

Я использую ffmpeg для получения аудио из файлов .mov. Просматривая мои настройки, я не преобразую частоту дискретизации аудио-буферов, которые я генерирую, так что вряд ли я учту возникшие у меня проблемы. Независимо от частоты дискретизации, установленной на моем встроенном выходе, мои аудиофайлы воспроизводятся с частотой 44,1 кГц с правильной частотой. Если я воспроизводю файл 48 кГц, файл воспроизводится медленнее (на 91% от нормальной частоты), что указывает на то, что истинная частота равна 44,1 кГц. Я могу изменить свой встроенный выход на 44,1, 48 или 96 кГц, и такое же явление существует. Я изменяю свою скорость вывода по умолчанию с помощью приложения Audio Midi Setup. Затем я проверяю частоту дискретизации, используя AudioUnitGetProperty на моем ouputAudioUnit. Это соответствует частоте дискретизации в Audio Midi Setup.

Мысли? Я включаю свой код аудиограммы

CheckError(NewAUGraph(&fp.graph), "Couldn't create a new AUGraph");

//varispeednode has an input callback
//the vairspeed node feeds an output node which is running 
//at the frequency of the system default output

AUNode outputNode;
AudioComponentDescription outputcd = [self defaultOutputComponent];
CheckError(AUGraphAddNode(fp.graph, &outputcd, &outputNode),
           "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");

AUNode varispeedNode;
AudioComponentDescription varispeedcd = [self variSpeedComponent];
CheckError(AUGraphAddNode(fp.graph, &varispeedcd, &varispeedNode),
           "AUGraphAddNode[kAudioUnitSubType_Varispeed] failed");

CheckError(AUGraphOpen(fp.graph),
           "Couldn't Open AudioGraph");

CheckError(AUGraphNodeInfo(fp.graph, outputNode, NULL, &fp.outputAudioUnit),
           "Couldn't Retrieve output node");

CheckError(AUGraphNodeInfo(fp.graph, varispeedNode, NULL, &fp.variSpeedAudioUnit),
           "Couldn't Retrieve Varispeed Audio Unit");

AURenderCallbackStruct input;
input.inputProc = CBufferProviderCallback;
input.inputProcRefCon = &playerStruct;
CheckError(AudioUnitSetProperty(fp.variSpeedAudioUnit,
                                kAudioUnitProperty_SetRenderCallback, 
                                kAudioUnitScope_Input,
                                0,
                                &input, 
                                sizeof(input)),
           "AudioUnitSetProperty failed");


CheckError(AUGraphConnectNodeInput(fp.graph, varispeedNode, 0, outputNode, 0),
           "Couldn't Connect varispeed to output");

CheckError(AUGraphInitialize(fp.graph),
           "Couldn't Initialize AUGraph");

// check output sample rate

Float64 outputSampleRate = 48000.0;
UInt32 sizeOfFloat64 = sizeof(Float64);

outputSampleRate = 0.0;
CheckError(AudioUnitGetProperty(fp.outputAudioUnit,
                               kAudioUnitProperty_SampleRate,
                               kAudioUnitScope_Global,
                               0,
                               &outputSampleRate,
                               &sizeOfFloat64), 
          "Couldn't get output sampleRate");

1 Ответ

0 голосов
/ 01 мая 2018

Я решил проблему. При построении звукового графика вам необходимо указать частоту дискретизации входного сигнала аудиоустройства с переменной скоростью, прежде чем подключать его к выходному узлу внутри augraph. Смотрите пример кода на https://developer.apple.com/library/content/samplecode/CAPlayThrough/Listings/ReadMe_txt.html

CheckError(NewAUGraph(&fp.graph), "BuildGraphError");

AUNode outputNode;
AudioComponentDescription outputcd = [self defaultOutputComponent];
CheckError(AUGraphAddNode(fp.graph, &outputcd, &outputNode),
       "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");

AUNode varispeedNode;
AudioComponentDescription varispeedcd = [self variSpeedComponent];
CheckError(AUGraphAddNode(fp.graph, &varispeedcd, &varispeedNode),
       "AUGraphAddNode[kAudioUnitSubType_Varispeed] failed");

CheckError(AUGraphOpen(fp.graph),
       "Couldn't Open AudioGraph");

CheckError(AUGraphNodeInfo(fp.graph, outputNode, NULL, &fp.outputAudioUnit),
       "Couldn't Retrieve File Audio Unit");

CheckError(AUGraphNodeInfo(fp.graph, varispeedNode, NULL, &fp.variSpeedAudioUnit),
       "Couldn't Retrieve Varispeed Audio Unit");

AURenderCallbackStruct input;
  input.inputProc = CBufferProviderCallback;
input.inputProcRefCon = &playerStruct;
CheckError(AudioUnitSetProperty(fp.variSpeedAudioUnit,
                kAudioUnitProperty_SetRenderCallback, 
                kAudioUnitScope_Input,
                0,
                &input, 
                sizeof(input)),
       "AudioUnitSetProperty failed");

  //you have to set the varispeed rate before you connect it
  //see CAPlayThrough

AudioStreamBasicDescription asbd = {0};
UInt32 size;
Boolean outWritable;

//Gets the size of the Stream Format Property and if it is writable
OSStatus result = AudioUnitGetPropertyInfo(fp.variSpeedAudioUnit,
                                           kAudioUnitProperty_StreamFormat,
                                           kAudioUnitScope_Output,
                                           0,
                                           &size,
                                           &outWritable);

//Get the current stream format of the output
result = AudioUnitGetProperty (fp.variSpeedAudioUnit,
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Output,
                               0,
                               &asbd,
                               &size);

asbd.mSampleRate = targetSampleRate;

//Set the stream format of the output to match the input
result = AudioUnitSetProperty (fp.variSpeedAudioUnit,
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Input,
                               0,
                               &asbd,
                               size);

printf("AudioUnitSetProperty result %d %d\n", result, noErr);



CheckError(AUGraphConnectNodeInput(fp.graph, varispeedNode, 0, outputNode, 0),
       "Couldn't Connect varispeed to output");

CheckError(AUGraphInitialize(fp.graph),
       "Couldn't Initialize AUGraph");

Float64 outputSampleRate = 48000.0;
  UInt32 sizeOfFloat64 = sizeof(Float64);

  outputSampleRate = 0.0;
  CheckError(AudioUnitGetProperty(fp.outputAudioUnit,
                                  kAudioUnitProperty_SampleRate,
                                  kAudioUnitScope_Global,
                                  0,
                                  &outputSampleRate,
                                  &sizeOfFloat64), 
             "Couldn't get output sampleRate");

NSLog(@"Output Sample Rate of the ->%f", outputSampleRate);
...