How to reverse an audio file?

后端 未结 4 515
渐次进展
渐次进展 2020-11-29 09:49

I\'d like to reverse an existing audio file (e.g. WAV, CAF, ...) on iOS. Any suggestions on how to achieve this? Open-source libraries?

相关标签:
4条回答
  • 2020-11-29 10:22

    Using libsndfile, I was able to read in the recorded audio sample. The following code snippet then shows how to open the input file, and write the output in reversed order. You should note though that all data is read in memory!

    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);
    
    0 讨论(0)
  • 2020-11-29 10:26

    Kiran's answer in 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)
    
    0 讨论(0)
  • 2020-11-29 10:32

    I have worked on a sample app, which records what user says and plays them backwards. I have used CoreAudio to achieve this. Link to app code.

    As each sample is 16-bits in size(2 bytes)(mono channel). You can load each sample at a time by copying it into a different buffer by starting at the end of the recording and reading backwards. When you get to the start of the data you have reversed the data and playing will be reversed.

        // 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);
    
    0 讨论(0)
  • 2020-11-29 10:32

    A WAV file just contains raw PCM samples. If you play them in the reverse order, you will get the reverse sound. See this question for details. (and also this search)

    0 讨论(0)
提交回复
热议问题