我正在将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
,或者我是否需要采用另一种方式?
答案 0 :(得分:0)
extended audio file services
框架不支持" raw" PCM格式。
对于理解PCM格式的应用程序,它需要知道如下数据:
实际上,在iOS
和OS X
上,AudioStreamBasicDescription
是一个结构,它告诉您解释PCM流所需的内容。因此,原始PCM"格式并没有真正起作用,它至少需要一些元数据。与原始PCM最接近的格式是WAV
,AIFF
和CAF
。如果这些不符合您的目的,则您必须创建自定义文件格式。但这并不困难。
extended audio file services
API非常易于配置。打开要读取的音频文件(ExtAudioFileOpenURL
)后,您可以在ExtAudioFileRef
句柄上设置各种属性。
在您的情况下,请考虑设置kExtAudioFileProperty_ClientDataFormat
。此属性控制从文件读取的PCM数据的格式。当ExtAudioFileRead
解码输入文件时,它会将发送的数据转换回您指定的格式。这种方法有一些限制。 IIRC,它不支持进行采样率转换等等。
当您阅读正确解码的数据时,您可以使用类似NSOutputStream
的内容来编写"原始PCM"您选择的格式直接到没有元数据的文件。