重写这个问题要更有效一些。将音频写入磁盘从IO单元
我的问题是,我无法成功地从远程IO单元写入音频文件到磁盘。
我拿着的步骤是
打开一个mp3文件并提取其音频缓冲区。 我根据图的属性设置了一个asbd以与我的图形一起使用。 我安装并运行我的图形循环提取的音频和声音成功地出来扬声器!
我有困难的是从远程IO回调采取音频采样,并将它们写入磁盘上的音频文件,我正在使用ExtAudioFileWriteASync。
音频文件确实被写入,并且与原始mp3有一些可听的相似之处,但听起来非常失真。
我不知道,如果问题是
A)ExtAudioFileWriteAsync不能以最快的速度IO单元的回调提供了他们写的样本。
- 或 -
B)我已成立了ASBD为extaudiofile refeference错误。我想先保存一个wav文件。我不确定我是否在下面的ASBD中正确描述了这一点。
其次,我不确定创建音频文件时传递给inChannelLayout属性的值。
最后我很不确定什么asbd用于kExtAudioFileProperty_ClientDataFormat。 我一直在使用我的立体声流格式,但仔细看看文档说这必须是pcm。这应该与remoteio的输出格式相同吗?如果是的话,我错了将远程io的输出格式设置为stereostreamformat?
我意识到这个问题存在很多,但我有很多不确定因素,我似乎无法自行清理。
设置立体声流格式
- (void) setupStereoStreamFormat
{
size_t bytesPerSample = sizeof (AudioUnitSampleType);
stereoStreamFormat.mFormatID = kAudioFormatLinearPCM;
stereoStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
stereoStreamFormat.mBytesPerPacket = bytesPerSample;
stereoStreamFormat.mFramesPerPacket = 1;
stereoStreamFormat.mBytesPerFrame = bytesPerSample;
stereoStreamFormat.mChannelsPerFrame = 2; // 2 indicates stereo
stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample;
stereoStreamFormat.mSampleRate = engineDescribtion.samplerate;
NSLog (@"The stereo stereo format :");
}
设置remoteio回调使用立体声流格式
AudioUnitSetProperty(engineDescribtion.masterChannelMixerUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
masterChannelMixerUnitloop,
&stereoStreamFormat,
sizeof(stereoStreamFormat));
AudioUnitSetProperty(engineDescribtion.masterChannelMixerUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
masterChannelMixerUnitloop,
&stereoStreamFormat,
sizeof(stereoStreamFormat));
static OSStatus masterChannelMixerUnitCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
// ref.equnit;
//AudioUnitRender(engineDescribtion.channelMixers[inBusNumber], ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData);
Engine *engine= (Engine *) inRefCon;
AudioUnitRender(engineDescribtion.equnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData);
if(engine->isrecording)
{
ExtAudioFileWriteAsync(engine->recordingfileref, inNumberFrames, ioData);
}
return 0;
}
**记录设置**
-(void)startrecording
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
destinationFilePath = [[NSString alloc] initWithFormat: @"%@/testrecording.wav", documentsDirectory];
destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false);
OSStatus status;
// prepare a 16-bit int file format, sample channel count and sample rate
AudioStreamBasicDescription dstFormat;
dstFormat.mSampleRate=44100.0;
dstFormat.mFormatID=kAudioFormatLinearPCM;
dstFormat.mFormatFlags=kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;
dstFormat.mBytesPerPacket=4;
dstFormat.mBytesPerFrame=4;
dstFormat.mFramesPerPacket=1;
dstFormat.mChannelsPerFrame=2;
dstFormat.mBitsPerChannel=16;
dstFormat.mReserved=0;
// create the capture file
status= ExtAudioFileCreateWithURL(destinationURL, kAudioFileWAVEType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &recordingfileref);
CheckError(status ,"couldnt create audio file");
// set the capture file's client format to be the canonical format from the queue
status=ExtAudioFileSetProperty(recordingfileref, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &stereoStreamFormat);
CheckError(status ,"couldnt set input format");
ExtAudioFileSeek(recordingfileref, 0);
isrecording=YES;
// [documentsDirectory release];
}
编辑1
我真的刺伤在黑暗中在这里,但现在我需要使用音频转换器或不kExtAudioFileProperty_ClientDataFormat采取照顾?
编辑2
林附着音频的2个样本。第一个是Im循环和尝试复制的原始音频。第二个是该循环的录制音频。希望这可能会给某些人一些线索,看看哪里出了问题。
愚蠢的问题,但你检查'sizeof(AudioUnitSampleType);'返回相同的大小,你分配给'mBytesPerPacket'? –
我仔细检查确定。他们都是相同的大小。 – dubbeat
@dubbeat hv你用记录音频做了 – Aadil