CoreAudio:如何检索原始数据的实际采样率?

时间:2014-08-08 05:44:53

标签: ffmpeg core-audio

尝试在mp4容器中播放AAC-HE内容时,mp4容器中的报告采样率似乎是实际采样率的一半。

例如,它显示为24kHz而不是48kHz。

使用FFmpeg AAC解码器,只需使用

解码音频数据包即可检索实际采样率。
avcodec_decode_audio4

查看AVCodecContext::sample_rate将适当更新的内容。从那以后,它很容易适应输出。

使用CoreAudio解码器,我会使用AudioConverterRef设置输入和输出AudioStreamBasicDescription 并致电AudioConverterFillComplexBuffer

由于转换器执行所有必需的内部转换,包括重新采样它很好。但它在重新采样到24kHz之后播放内容(就像输入AudioStreamBasicDescription包含的内容一样。

是否有办法以与FFmpeg类似的方式检索解码器(而不是解复用器)的实际采样率?

如果可能的话,更愿意避免丢失音频质量,而不是缩混数据

由于

1 个答案:

答案 0 :(得分:0)

发现这个: https://developer.apple.com/library/ios/qa/qa1639/_index.html

解释如何检索更高质量的流..

结果代码如下:

AudioStreamBasicDescription inputFormat;
AudioFormatListItem* formatListPtr = NULL;
UInt32 propertySize;
OSStatus rv = noErr;

rv = AudioFileStreamGetPropertyInfo(mStream,
                                    kAudioFileStreamProperty_FormatList,
                                    &propertySize,
                                    NULL);
if (rv == noErr) {
  // allocate memory for the format list items
  formatListPtr = static_cast<AudioFormatListItem*>(malloc(propertySize));
  if (!formatListPtr) {
    LOG("Error %d constructing AudioConverter", rv);
    mCallback->Error();
    return;
  }

  // get the list of Audio Format List Item's
  rv = AudioFileStreamGetProperty(mStream,
                                  kAudioFileStreamProperty_FormatList,
                                  &propertySize,
                                  formatListPtr);
  if (rv == noErr) {
    UInt32 itemIndex;
    UInt32 indexSize = sizeof(itemIndex);

    // get the index number of the first playable format -- this index number will be for
    // the highest quality layer the platform is capable of playing
    rv = AudioFormatGetProperty(kAudioFormatProperty_FirstPlayableFormatFromList,
                                propertySize,
                                formatListPtr,
                                &indexSize,
                                &itemIndex);
    if (rv != noErr) {
      free(formatListPtr);
      LOG("Error %d retrieving best format for AudioConverter", rv);
      return;
    }
    // copy the format item at index we want returned
    inputFormat =  formatListPtr[itemIndex].mASBD;
  }
  free(formatListPtr);
} else {
  // Fill in the input format description from the stream.
  nsresult rv = AppleUtils::GetProperty(mStream,
                                        kAudioFileStreamProperty_DataFormat,
                                        &inputFormat);
  if (NS_FAILED(rv)) {
    LOG("Error %d retrieving default format for AudioConverter", rv);
    return;
  }
}

// Fill in the output format manually.
PodZero(&mOutputFormat);
mOutputFormat.mFormatID = kAudioFormatLinearPCM;
mOutputFormat.mSampleRate = inputFormat.mSampleRate;
mOutputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;