简体   繁体   English

如何反转音频文件?

[英]How to reverse an audio file?

I'd like to reverse an existing audio file (eg WAV, CAF, ...) on iOS.我想反转 iOS 上的现有音频文件(例如 WAV、CAF、...)。 Any suggestions on how to achieve this?关于如何实现这一目标的任何建议? Open-source libraries?开源库?

I have worked on a sample app, which records what user says and plays them backwards.我开发了一个示例应用程序,它记录用户所说的内容并向后播放。 I have used CoreAudio to achieve this.我已经使用 CoreAudio 来实现这一点。 Link to app code.链接到应用程序代码。

As each sample is 16-bits in size(2 bytes)(mono channel).因为每个样本的大小为 16 位(2 字节)(单通道)。 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);

Kiran's answer in Swift 2.2: 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)

A WAV file just contains raw PCM samples. WAV 文件只包含原始 PCM 样本。 If you play them in the reverse order, you will get the reverse sound.如果您以相反的顺序播放它们,您将获得相反的声音。 See this question for details.有关详细信息,请参阅此问题。 (and also this search ) (还有这个搜索

Using libsndfile , I was able to read in the recorded audio sample.使用libsndfile ,我能够读取录制的音频样本。 The following code snippet then shows how to open the input file, and write the output in reversed order.下面的代码片段然后显示如何打开输入文件,并以相反的顺序写入 output。 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM