从原始PCM 16000采样率stream中使用CMSampleTimingInfo,CMSampleBuffer和AudioBufferList

我从外部接收audio数据和大小,audio似乎是线性PCM,签名int16,但是当使用AssetWriter录制时,它保存到audio文件高度失真和更高的音调。

#define kSamplingRate 16000 #define kNumberChannels 1 UInt32 framesAlreadyWritten = 0; -(AudioStreamBasicDescription) getAudioFormat { AudioStreamBasicDescription format; format.mSampleRate = kSamplingRate; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; format.mChannelsPerFrame = 1; // mono format.mBitsPerChannel = 16; format.mBytesPerFrame = sizeof(SInt16); format.mFramesPerPacket = 1; format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket; format.mReserved = 0; return format; } - (CMSampleBufferRef)createAudioSample:(const void *)audioData frames: (UInt32)len { AudioStreamBasicDescription asbd = [self getAudioFormat]; CMSampleBufferRef buff = NULL; static CMFormatDescriptionRef format = NULL; OSStatus error = 0; if(format == NULL) { AudioChannelLayout acl; bzero(&acl, sizeof(acl)); acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; error = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &asbd, sizeof(acl), &acl, 0, NULL, NULL, &format); } CMTime duration = CMTimeMake(1, kSamplingRate); CMTime pts = CMTimeMake(framesAlreadyWritten, kSamplingRate); NSLog(@"-----------pts"); CMTimeShow(pts); CMSampleTimingInfo timing = {duration , pts, kCMTimeInvalid }; error = CMSampleBufferCreate(kCFAllocatorDefault, NULL, false, NULL, NULL, format, len, 1, &timing, 0, NULL, &buff); framesAlreadyWritten += len; if (error) { NSLog(@"CMSampleBufferCreate returned error: %ld", (long)error); return NULL; } AudioBufferList audioBufferList; audioBufferList.mNumberBuffers = 1; audioBufferList.mBuffers[0].mNumberChannels = asbd.mChannelsPerFrame; audioBufferList.mBuffers[0].mDataByteSize = (UInt32)(number_of_frames * audioFormat.mBytesPerFrame); audioBufferList.mBuffers[0].mData = audioData; error = CMSampleBufferSetDataBufferFromAudioBufferList(buff, kCFAllocatorDefault, kCFAllocatorDefault, 0, &audioBufferList); if(error) { NSLog(@"CMSampleBufferSetDataBufferFromAudioBufferList returned error: %ld", (long)error); return NULL; } return buff; } 

不知道你为什么要把lenlen ,但是你的time应该是进步的,而不是一成不变的

 CMTime time = CMTimeMake(framesAlreadyWritten , kSamplingRate);