2

我在使用设备录制时使用 ExtAudioFileWriteAsync 写入音频文件,但是一旦我完成录制,我尝试使用 ExtAudioFileRead 函数读取它,我得到的样本与我正在编写的样本不同......有人知道为什么会发生这种情况吗?

对于写作:

self.audioManager.inputBlock = ^(float *data, UInt32 numFrames, UInt32 numChannels) {
  for (int i = 0; i < numFrames*numChannels; i++) {
        printf("write*%f\n", data[i]);
  }

  UInt32 numIncomingBytes = numFrames*numChannels*sizeof(float);
  UInt32 *outputBuffer =(UInt32*)malloc(numIncomingBytes);
  memcpy(outputBuffer, recordedData, numIncomingBytes);

  AudioBufferList outgoingAudio;
  outgoingAudio.mNumberBuffers = 1;
  outgoingAudio.mBuffers[0].mNumberChannels = numChannels;
  outgoingAudio.mBuffers[0].mDataByteSize = numIncomingBytes;
  outgoingAudio.mBuffers[0].mData = self.outputBuffer;

  if( 0 == pthread_mutex_trylock( &outputAudioFileLock ) ) 
  {       
      ExtAudioFileWriteAsync(outputFile, numFrames, &outgoingAudio);
  }
  pthread_mutex_unlock( &outputAudioFileLock );    
};
[self.audioManager play];

阅读:

UInt32 *outputBuffer = (UInt32 *)malloc(numFrames*numChannels*sizeof(float));

AudioBufferList convertedData;
convertedData.mNumberBuffers = 1;
convertedData.mBuffers[0].mNumberChannels = numChannels;
convertedData.mBuffers[0].mDataByteSize = numFrames*numChannels*sizeof(float);
convertedData.mBuffers[0].mData = outputBuffer;

NSMutableArray *samplesArray = [[NSMutableArray alloc]init];
while (numFrames > 0) {
    ExtAudioFileRead(inputFile, &numFrames, &convertedData);
    if (numFrames > 0)  {
        AudioBuffer audioBuffer = convertedData.mBuffers[0];
        float *samples = (float *)audioBuffer.mData;
        for (int i = 0; i < frameCount*numChannels; i++) {
            printf("read*%f\n", samples[i]);
        }
    }
}

顺便说一句,我正在使用Novocaine项目来获取设备音频。我可以使用 Novocaine 代码或任何其他播放器重现保存的音频。

编写 ExtAudioFileRef 输出时:

 ExtAudioFileCreateWithURL(audioFileRef, kAudioFileM4AType,   &outputFileDesc, NULL, kAudioFileFlags_EraseFile, &outputFile);

outputFileDesc 在哪里

AudioStreamBasicDescription outputFileDesc = {44100.0, kAudioFormatMPEG4AAC, 0, 0, 1024, 0, thisNumChannels, 0, 0}; outputFileDesc.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;

读取 ExtAudioFileRef 输入文件时:

ExtAudioFileOpenURL(audioFileRef, &inputFile):

在这两种情况下(写作和阅读),它都采用相同的格式:

AudioStreamBasicDescription outputFormat;
_outputFormat.mSampleRate = self.samplingRate;
_outputFormat.mFormatID = kAudioFormatLinearPCM;
_outputFormat.mFormatFlags = kAudioFormatFlagIsFloat;
_outputFormat.mBytesPerPacket = 4*self.numChannels;
_outputFormat.mFramesPerPacket = 1;
_outputFormat.mBytesPerFrame = 4*self.numChannels;
_outputFormat.mChannelsPerFrame = self.numChannels;
_outputFormat.mBitsPerChannel = 32;


ExtAudioFileSetProperty(outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &_outputFormat);


 ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &_outputFormat);

顺便说一句,即使读取样本不等于写入样本,两个信号的平均值也非常相似。但我不完全明白为什么不完全相等!

知道我做错了什么吗?

4

1 回答 1

1

听起来好像从 ExtaudioFileRefs 中的一个或两个进行了隐式格式转换,并且由于转换,您会看到不同的示例。您有三种格式:audio_in_format、file_format 和 audio_out_format。如果 audio_in_format 与 file_format 不同,写入 ExtAudioFileRef 将创建一个音频转换器,以便您在写入磁盘之前将输入音频转换为 file_format。如果 file_format 与 audio_out_format 不同,读取 ExtAudioFileRef 也会创建一个转换器。

意见:令人困惑的是,您将写作 ExtAudioFileRef 命名为“outputFile”,而将阅读 ExtAudioFileRef 命名为“inputFile”。我会使用类似 audioWriter 和 audioReader 的东西。

于 2015-09-21T16:18:14.777 回答