就在这里a您可以通过这种方式处理并导出 iOS 支持的任何音频文件。
然而,大多数这些格式(mp3
仅举一例)是有损和压缩的。您必须首先解压缩数据,应用转换,然后重新压缩。您将应用于音频信息的大多数转换可能应该在原始 PCM 级别完成。
结合这两个语句,您可以通过几遍来完成此操作:
- 将原始文件转换为
kAudioFormatLinearPCM
兼容的音频文件,例如AIFF
- 处理该临时文件(反转其内容)
- 将临时文件转换回原始格式
就像您将转换应用于压缩的文件一样jpeg
图像,在此过程中会出现退化。最终的音频至多会再经历一个压缩周期。
因此,这种方法的真正数学答案实际上是否定的。
仅供参考,这里是 swift 3 中的一些起始代码。它需要进一步细化以跳过文件头。
var outAudioFile:AudioFileID?
var pcm = AudioStreamBasicDescription(mSampleRate: 44100.0,
mFormatID: kAudioFormatLinearPCM,
mFormatFlags: kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger,
mBytesPerPacket: 2,
mFramesPerPacket: 1,
mBytesPerFrame: 2,
mChannelsPerFrame: 1,
mBitsPerChannel: 16,
mReserved: 0)
var theErr = AudioFileCreateWithURL(destUrl as CFURL!,
kAudioFileAIFFType,
&pcm,
.eraseFile,
&outAudioFile)
if noErr == theErr, let outAudioFile = outAudioFile {
var inAudioFile:AudioFileID?
theErr = AudioFileOpenURL(sourceUrl as! CFURL, .readPermission, 0, &inAudioFile)
if noErr == theErr, let inAudioFile = inAudioFile {
var fileDataSize:UInt64 = 0
var thePropertySize:UInt32 = UInt32(MemoryLayout<UInt64>.stride)
theErr = AudioFileGetProperty(inAudioFile,
kAudioFilePropertyAudioDataByteCount,
&thePropertySize,
&fileDataSize)
if( noErr == theErr) {
let dataSize:Int64 = Int64(fileDataSize)
let theData = UnsafeMutableRawPointer.allocate(bytes: Int(dataSize),
alignedTo: MemoryLayout<UInt8>.alignment)
var readPoint:Int64 = Int64(dataSize)
var writePoint:Int64 = 0
while( readPoint > 0 )
{
var bytesToRead = UInt32(2)
AudioFileReadBytes( inAudioFile, false, readPoint, &bytesToRead, theData)
AudioFileWriteBytes( outAudioFile, false, writePoint, &bytesToRead, theData)
writePoint += 2
readPoint -= 2
}
theData.deallocate(bytes: Int(dataSize), alignedTo: MemoryLayout<UInt8>.alignment)
AudioFileClose(inAudioFile);
AudioFileClose(outAudioFile);
}
}
}