菜鸟教程小白 发表于 2022-12-13 13:00:46

ios - 无法正确反转 AVAsset 音频。唯一的结果是白噪声


                                            <p><p>我正在尝试反转 <code>AVAsset</code> 音频并将其保存到文件中。为了清楚起见,我用问题 <a href="https://github.com/ksenia-lyagusha/AudioReverse.git" rel="noreferrer noopener nofollow">https://github.com/ksenia-lyagusha/AudioReverse.git</a> 做了一个简单的应用程序。 </p>

<p>应用程序从包中获取 <code>mp4</code> 视频文件,将其作为单个 <code>m4a</code> 文件导出到沙箱中的临时文件夹,然后尝试从那里读取它,反转并保存结果文件回来。
临时 <code>m4a</code> 文件没问题。</p>

<p>我反向部分的唯一结果是 <code>Sandbox</code> 中带有白噪声的音频文件。 </p>

<p>下面有一段代码,负责反转<code>AVAsset</code>。它基于相关问题</p>

<ul>
<li> <a href="https://stackoverflow.com/questions/6593118/how-to-reverse-an-audio-file" rel="noreferrer noopener nofollow">How to reverse an audio file?</a> </li>
<li> <a href="https://stackoverflow.com/questions/6707998/ios-audio-manipulation-play-local-caf-file-backwards" rel="noreferrer noopener nofollow">iOS audio manipulation - play local .caf file backwards</a> </li>
</ul>

<p>但是,它对我不起作用。</p>

<pre><code>OSStatus theErr = noErr;
UInt64 fileDataSize = 0;
AudioFileID inputAudioFile;
AudioStreamBasicDescription theFileFormat;
UInt32 thePropertySize = sizeof(theFileFormat);

theErr = AudioFileOpenURL((__bridge CFURLRef), kAudioFileReadPermission, 0, &amp;inputAudioFile);

thePropertySize = sizeof(fileDataSize);
theErr = AudioFileGetProperty(inputAudioFile, kAudioFilePropertyAudioDataByteCount, &amp;thePropertySize, &amp;fileDataSize);

UInt32 ps = sizeof(AudioStreamBasicDescription) ;
AudioFileGetProperty(inputAudioFile, kAudioFilePropertyDataFormat, &amp;ps, &amp;theFileFormat);

UInt64 dataSize = fileDataSize;
void *theData = malloc(dataSize);

// set up output file
AudioFileID outputAudioFile;

AudioStreamBasicDescription myPCMFormat;

myPCMFormat.mSampleRate       = 44100;
myPCMFormat.mFormatID         = kAudioFormatLinearPCM;
// kAudioFormatFlagsCanonical is deprecated
myPCMFormat.mFormatFlags      = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved;
myPCMFormat.mChannelsPerFrame = 1;
myPCMFormat.mFramesPerPacket= 1;
myPCMFormat.mBitsPerChannel   = 32;
myPCMFormat.mBytesPerPacket   = (myPCMFormat.mBitsPerChannel / 8) * myPCMFormat.mChannelsPerFrame;
myPCMFormat.mBytesPerFrame    = myPCMFormat.mBytesPerPacket;



NSString *exportPath = ;
NSURL *outputURL = ;

theErr = AudioFileCreateWithURL((__bridge CFURLRef)outputURL,
                     kAudioFileCAFType,
                     &amp;myPCMFormat,
                     kAudioFileFlags_EraseFile,
                     &amp;outputAudioFile);

//Read data into buffer
//if readPoint= dataSize, then bytesToRead = 0 in while loop and
//it is endless
SInt64 readPoint= dataSize-1;
UInt64 writePoint = 0;

while(readPoint &gt; 0)
{
    UInt32 bytesToRead = 2;
    AudioFileReadBytes(inputAudioFile, false, readPoint, &amp;bytesToRead, theData);
    // bytesToRead is now the amount of data actually read

    UInt32 bytesToWrite = bytesToRead;
    AudioFileWriteBytes(outputAudioFile, false, writePoint, &amp;bytesToWrite, theData);
    // bytesToWrite is now the amount of data actually written

    writePoint += bytesToWrite;
    readPoint -= bytesToRead;
}

free(theData);
AudioFileClose(inputAudioFile);
AudioFileClose(outputAudioFile);
</code></pre>

<p>如果我将 <code>AudioFileCreateWithURL</code> 中的文件类型从 <code>kAudioFileCAFType</code> 更改为另一个,则根本不会在 <code>Sandbox</code> 中创建结果文件。</p >

<p>感谢您的帮助。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您会收到白噪声,因为您的输入和输出文件格式不兼容。您有不同的采样率和 channel ,可能还有其他差异。要完成这项工作,您需要在读取和写入之间使用一种通用 (PCM) 格式。对于新的(ish)<code>AVAudio</code> 框架来说,这是一项合理的工作。我们从文件读取到 PCM,洗牌缓冲区,然后从 PCM 写入到文件。这种方法没有针对大文件进行优化,因为所有数据都一次性读入缓冲区,但足以让您开始使用。</p>

<p>您可以从 <code>getAudioFromVideo</code> 完成 block 中调用此方法。为清楚起见,忽略了错误处理。</p>

<pre><code>- (void)readAudioFromURL:(NSURL*)inURL reverseToURL:(NSURL*)outURL {

//prepare the in and outfiles

AVAudioFile* inFile =
   [ initForReading:inURL error:nil];

AVAudioFormat* format = inFile.processingFormat;
AVAudioFrameCount frameCount =(UInt32)inFile.length;
NSDictionary* outSettings = @{
             AVNumberOfChannelsKey:@(format.channelCount)
            ,AVSampleRateKey:@(format.sampleRate)};

AVAudioFile* outFile =
    [ initForWriting:outURL
                               settings:outSettings
                                  error:nil];

//prepare the forward and reverse buffers
self.forwaredBuffer =
    [ initWithPCMFormat:format
                                  frameCapacity:frameCount];
self.reverseBuffer =
    [ initWithPCMFormat:format
                                  frameCapacity:frameCount];

//read file into forwardBuffer
    ;

//set frameLength of reverseBuffer to forwardBuffer framelength
    AVAudioFrameCount frameLength = self.forwaredBuffer.frameLength;
    self.reverseBuffer.frameLength = frameLength;

//iterate over channels

   //stride is 1 or 2 depending on interleave format
   NSInteger stride = self.forwaredBuffer.stride;

    for (AVAudioChannelCount channelIdx = 0;                  
          channelIdx &lt; self.forwaredBuffer.format.channelCount;
          channelIdx++) {
      float* forwaredChannelData =
          self.forwaredBuffer.floatChannelData;
      float* reverseChannelData =
          self.reverseBuffer.floatChannelData;
      int32_t reverseIdx = 0;

   //iterate over samples, allocate to reverseBuffer in reverse order   
      for (AVAudioFrameCount frameIdx = frameLength;
                  frameIdx &gt;0;
                  frameIdx--) {
         float sample = forwaredChannelData;
         reverseChannelData = sample;
         reverseIdx++;
            }
      }

//write reverseBuffer to outFile
      ;
    }
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 无法正确反转 AVAsset 音频。唯一的结果是白噪声,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35581531/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35581531/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 无法正确反转 AVAsset 音频。唯一的结果是白噪声