如何反转audio文件?

我想在iOS上反转现有的audio文件(例如WAV,CAF,…)。 有关如何实现这一目标的任何build议? 开源库?

我曾经在一个示例应用程序,它logging了用户说,反向播放。 我已经使用CoreAudio来实现这一点。 链接到应用程序代码。

由于每个采样是16位(2字节)(单声道)。 您可以一次加载每个样本,方法是从录制结束开始,向后读取,将其复制到不同的缓冲区中。 当你到达数据的开始时,你已经转换了数据,播放将被颠倒。

// set up output file AudioFileID outputAudioFile; AudioStreamBasicDescription myPCMFormat; myPCMFormat.mSampleRate = 16000.00; myPCMFormat.mFormatID = kAudioFormatLinearPCM ; myPCMFormat.mFormatFlags = kAudioFormatFlagsCanonical; myPCMFormat.mChannelsPerFrame = 1; myPCMFormat.mFramesPerPacket = 1; myPCMFormat.mBitsPerChannel = 16; myPCMFormat.mBytesPerPacket = 2; myPCMFormat.mBytesPerFrame = 2; AudioFileCreateWithURL((__bridge CFURLRef)self.flippedAudioUrl, kAudioFileCAFType, &myPCMFormat, kAudioFileFlags_EraseFile, &outputAudioFile); // set up input file AudioFileID inputAudioFile; OSStatus theErr = noErr; UInt64 fileDataSize = 0; AudioStreamBasicDescription theFileFormat; UInt32 thePropertySize = sizeof(theFileFormat); theErr = AudioFileOpenURL((__bridge CFURLRef)self.recordedAudioUrl, kAudioFileReadPermission, 0, &inputAudioFile); thePropertySize = sizeof(fileDataSize); theErr = AudioFileGetProperty(inputAudioFile, kAudioFilePropertyAudioDataByteCount, &thePropertySize, &fileDataSize); UInt32 dataSize = fileDataSize; void* theData = malloc(dataSize); //Read data into buffer UInt32 readPoint = dataSize; UInt32 writePoint = 0; while( readPoint > 0 ) { UInt32 bytesToRead = 2; AudioFileReadBytes( inputAudioFile, false, readPoint, &bytesToRead, theData ); AudioFileWriteBytes( outputAudioFile, false, writePoint, &bytesToRead, theData ); writePoint += 2; readPoint -= 2; } free(theData); AudioFileClose(inputAudioFile); AudioFileClose(outputAudioFile); 

WAV文件只包含原始PCM样本。 如果按照相反的顺序播放,则会听到相反的声音。 看到这个问题的细节。 (也是这个search )

使用libsndfile ,我能够读取录制的audio样本。 下面的代码片断展示了如何打开input文件,并以相反的顺序写入输出。 你应该注意,所有的数据都是在内存中读取的!

 SF_INFO info_read; info_read.format = 0; SNDFILE* sndfilein = sf_open("my_input_file.caf", SFM_READ, &info_read); SF_INFO info_write; info_write.format = info.format; info_write.channels = info.channels; info_write.frames = info.frames; info_write.samplerate = info.samplerate; info_write.sections = info.sections; info_write.seekable = info.seekable; SNDFILE* sndfileout = sf_open("my_output_file.caf", SFM_RDWR, &info_write); int* buf = new int[8000 * 30]; int framesRead = sf_readf_int(sndfilein, buf, info.frames); for (int i = 0; i < info.frames; i++) sf_writef_int(sndfileout, &buf[info.frames - i], 1); delete[] buf; sf_close(sndfilein); sf_close(sndfileout); 

Kiran在Swift 2.2中的回答:

  let forwardAudioURL: NSURL = ... // wherever your original audio is let reversedAudioURL: NSURL = ... // wherever you want the reversed file to go // Load forward audio into originalAudioFile var originalAudioFile: AudioFileID = nil let possibleError1 = AudioFileOpenURL(forwardAudioURL, AudioFilePermissions.ReadPermission, 0, &originalAudioFile) // Load the size in bytes of the original audio into originalAudioSize variable var originalAudioSize: Int64 = 0 var propertySize: UInt32 = 8 let possibleError2 = AudioFileGetProperty(originalAudioFile, kAudioFilePropertyAudioDataByteCount, &propertySize, &originalAudioSize) if possibleError1 != 0 || possibleError2 != 0 { // Handle errors if you want } // Set up file that the reversed audio will be loaded into var reversedAudioFile: AudioFileID = nil var format = AudioStreamBasicDescription() format.mSampleRate = 16000 format.mFormatID = kAudioFormatLinearPCM format.mChannelsPerFrame = 1 format.mFramesPerPacket = 1 format.mBitsPerChannel = 16 format.mBytesPerPacket = 2 format.mBytesPerFrame = 2 AudioFileCreateWithURL(reversedAudioURL, kAudioFileCAFType, &format, AudioFileFlags.EraseFile, &reversedAudioFile) // Read data into the reversedAudioFile var readPoint: Int64 = originalAudioSize var writePoint: Int64 = 0 var buffer: Int16 = 0 while readPoint > 0 { var bytesToRead: UInt32 = 2; AudioFileReadBytes(originalAudioFile, false, readPoint, &bytesToRead, &buffer) AudioFileWriteBytes(reversedAudioFile, false, writePoint, &bytesToRead, &buffer) writePoint += 2 readPoint -= 2 } AudioFileClose(originalAudioFile) AudioFileClose(reversedAudioFile)