如何使用iOS SDK(Core Audio)将原始PCM保存到文件?

时间:2016-02-02 18:56:14

标签: ios audio core-audio robovm

我正在将MP3文件转换为原始PCM,我需要将其保存为原始PCM。 (注意,我使用Java / RoboVM移植到iOS。)

我正在使用coreaudio包,我的代码的相关部分如下所示:

// Define the output PCM format.
AudioStreamBasicDescription outputFormat = new AudioStreamBasicDescription();
outputFormat.setFormat(AudioFormat.LinearPCM);
outputFormat.setFormatFlags(AudioFormatFlags.Canonical);
outputFormat.setBitsPerChannel(16);
outputFormat.setChannelsPerFrame(1);
outputFormat.setFramesPerPacket(1);
outputFormat.setBytesPerFrame(2);
outputFormat.setBytesPerPacket(2);
outputFormat.setSampleRate(22050);

// ...

outputFile = ExtAudioFile.create(outputFileURL, AudioFileType.CAF, outputFormat, null, AudioFileFlags.EraseFile);

然后我运行一个循环,从MP3文件中读取并写入输出文件。

将此原始文件导入Audacity时,我注意到它在开始时始终有一个尖峰,表明它实际上不是原始PCM文件,而是在带有标题的包装器内(无论是WAV还是CAF标头,等)。

我知道我可以拿起文件并剥离标题并获取原始PCM数据,但就我应用程序的这一部分的空间/性能而言,如果我能保持简单并保存,我会很高兴原始的PCM数据没有包装,但我不知道如何去做。

问题出现在这里:

outputFile = ExtAudioFile.create(outputFileURL, AudioFileType.CAF, outputFormat, null, AudioFileFlags.EraseFile);

AudioFileType的选择不多,我尝试过 WAVE CAF 。理想情况下会有 PCM RAW 选项,但事实并非如此。是否有我应该选择的特定AudioFileType,或者我是否需要采用另一种方式?

1 个答案:

答案 0 :(得分:0)

extended audio file services框架不支持" raw" PCM格式。

对于理解PCM格式的应用程序,它需要知道如下数据:

  • 有多少个频道
  • 它们是否交错
  • 什么是采样率
  • 数据是浮点数还是
  • 比特深度是什么
  • 等...

实际上,在iOSOS X上,AudioStreamBasicDescription是一个结构,它告诉您解释PCM流所需的内容。因此,原始PCM"格式并没有真正起作用,它至少需要一些元数据。与原始PCM最接近的格式是WAVAIFFCAF。如果这些不符合您的目的,则您必须创建自定义文件格式。但这并不困难。

extended audio file services API非常易于配置。打开要读取的音频文件(ExtAudioFileOpenURL)后,您可以在ExtAudioFileRef句柄上设置各种属性。

在您的情况下,请考虑设置kExtAudioFileProperty_ClientDataFormat。此属性控制从文件读取的PCM数据的格式。当ExtAudioFileRead解码输入文件时,它会将发送的数据转换回您指定的格式。这种方法有一些限制。 IIRC,它不支持进行采样率转换等等。

当您阅读正确解码的数据时,您可以使用类似NSOutputStream的内容来编写"原始PCM"您选择的格式直接到没有元数据的文件。