从RemoteIO记录:所得的.caf是音高移位较慢+扭曲(Recording from Remot

2019-06-23 11:08发布

所以,我鹅卵石基于这里一些帖子录制音频的一些例程在一起。 我引用的职位是在这里 ,并在这里 ,与他们阅读参考网站一起。

我的设置:我有一个现有的AUGraph:(几个AUSamplers - >混合 - > 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; 
}

Answer 1:

好吧 - 发现一些代码,解决了这个 - 虽然我不完全理解为什么。

我已经设定mBitsPerChannel到16两个RemoteIO输出流和ExtFileRef。 结果减慢和沙哑声音。 设置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;


文章来源: Recording from RemoteIO: resulting .caf is pitch shifted slower + distorted