Reverse an audio file Swift/Objective-C

后端 未结 1 910
面向向阳花
面向向阳花 2021-01-19 06:00

Is there a way that I could reverse and export .m4a audio file? I found a solution to reverse an audio track here, but it only seems to be working on .caf file formats. If t

相关标签:
1条回答
  • 2021-01-19 06:58

    Yes, there is a way you can process, then export, any of the audio files for which there is iOS support.

    However, most of these formats (mp3 to name one) are lossy and compressed. You must first decompress the data, apply the transformation, and recompress. Most transformation you will apply to the audio information should likely be done at the raw, PCM level.

    Combining these two statements, you do this in a few passes:

    1. convert original file to a kAudioFormatLinearPCM compliant audio file, like AIFF
    2. process that temporary file (reverse its content)
    3. convert the temporary file back to the original format

    Just like if you were applying a transformation to, say, a compressed jpeg image, there will be degradation in the process. The final audio will have, at best, suffered one more compression cycle.

    So the true mathematical answer to this approach is actually no.


    Just for reference, here is some starter code in swift 3. It needs further refinement to skip the file headers.

    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);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题