所以我根据这里的一些帖子拼凑了一些录制音频的例程。我引用的帖子是 here和 here ,以及阅读他们引用的网站。
我的设置:我有一个现有的 AUGraph:(几个 AUSamplers -> Mixer -> RemoteIO)。 AUSamplers 连接到 MusicPlayer 实例中的轨道。一切正常但是 我想给它添加录音。
录音工作正常,但生成的 .caf 音高/速度移动较慢 + 音质较差。我指定的格式一定有问题吗?
有人可以观察一下并告诉我哪里设置的格式不正确吗?
编辑:这可能是立体声/单声道问题吗?我的意思是用单声道录音。
我将 RemoteIO 实例上的流格式设置为:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
// Apply format
result = AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus,
&audioFormat,
sizeof(audioFormat));
然后我从一个按钮操作创建一个 fileRef 并将一个 renderCallback 附加到 RemoteIO 实例:
- (void)startRecording
{
OSStatus result;
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *destinationFilePath = [[NSString alloc] initWithFormat: @"%@/output.caf", documentsDirectory];
CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(__bridge CFStringRef)destinationFilePath,
kCFURLPOSIXPathStyle,
false);
result = ExtAudioFileCreateWithURL(destinationURL,
kAudioFileWAVEType,
&audioFormat,
NULL,
kAudioFileFlags_EraseFile,
&extAudioFileRef);
CFRelease(destinationURL);
NSAssert(result == noErr, @"Couldn't create file for writing");
result = ExtAudioFileSetProperty(extAudioFileRef,
kExtAudioFileProperty_ClientDataFormat,
sizeof(AudioStreamBasicDescription),
&audioFormat);
NSAssert(result == noErr, @"Couldn't create file for format");
result = ExtAudioFileWriteAsync(extAudioFileRef, 0, NULL);
NSAssert(result == noErr, @"Couldn't initialize write buffers for audio file");
printf("Adding render to remoteIO \n");
result = AudioUnitAddRenderNotify(ioUnit, renderCallback, (__bridge void*)self);
if (result) {[self printErrorMessage: @"AudioUnitAddRenderNotify" withStatus: result]; return;}
}
最后,在我的 rendercallback 中,我写出了 postRender 阶段的数据:
static OSStatus renderCallback (void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
OSStatus result;
if (*ioActionFlags == kAudioUnitRenderAction_PostRender){
double timeInSeconds = inTimeStamp->mSampleTime / kSampleRate;
printf("%fs inBusNumber: %lu inNumberFrames: %lu \n", timeInSeconds, inBusNumber, inNumberFrames);
MusicPlayerController* THIS = (__bridge MusicPlayerController *)inRefCon;
result = ExtAudioFileWriteAsync(THIS->extAudioFileRef, inNumberFrames, ioData);
if(result) printf("ExtAudioFileWriteAsync %ld \n", result);
}
return noErr;
}
最佳答案
好的 - 找到了一些解决这个问题的代码 - 虽然我不完全明白为什么。
我一直将 RemoteIO 输出流和 ExtFileRef 的 mBitsPerChannel
设置为 16。结果是速度变慢且声音沙哑。将 ExtFileRef mBitsPerChannel
设置为 32 并添加 kAudioFormatFlagsNativeEndian
标志可以解决问题:.caf 音频是完美的(同时将 RemoteIO 输出流设置保持原样)。
但随后也可以设置 RemoteIO 输出流设置以匹配我的新设置。所以我很困惑。只要 AudioStreamBasicDescription
设置对于 RemoteIO 实例和 ExtFileRef 是对称的,这不应该起作用吗?
无论如何...工作设置如下。
size_t bytesPerSample = sizeof (AudioUnitSampleType);
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate= graphSampleRate;
audioFormat.mFormatID=kAudioFormatLinearPCM;
audioFormat.mFormatFlags=kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;
audioFormat.mBytesPerPacket=bytesPerSample;
audioFormat.mBytesPerFrame=bytesPerSample;
audioFormat.mFramesPerPacket=1;
audioFormat.mChannelsPerFrame=1;
audioFormat.mBitsPerChannel= 8 * bytesPerSample;
audioFormat.mReserved=0;
关于ios - 来自 RemoteIO : resulting . caf 的录音音高偏移较慢 + 失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10067117/