2017-03-10 1 views
1

外部からオーディオデータとサイズを受信すると、オーディオはリニアPCMで署名されたint16と表示されますが、AssetWriterを使用してこれを記録すると、歪んだ、より高いピッチ。Raw PCM 16000サンプルレートストリームのCMSampleTimingInfo、CMSampleBuffer、AudioBufferListを使用

#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; 
} 

答えて

1

ないのはなぜあなたは2によってlenを分割していることを確認、しかし、あなたのtimeはまだ同じ問題 するUInt32 framesAlreadyWritten = 0、一定である代わりに、私はこれを追加

CMTime time = CMTimeMake(framesAlreadyWritten , kSamplingRate); 
+0

のようなものを進めるべきです。 CMTime time = CMTimeMake(framesAlreadyWritten、kSamplingRate); CMSampleTimingInfoタイミング= {CMTimeMake(1、kSamplingRate)、時間、kCMTimeInvalid}; error = CMSampleBufferCreate(kCFAllocatorDefault、NULL、false、NULL、NULL、フォーマット、len/2、1、タイミング、0、NULL、&buff); framesAlreadyWritten + = len; – crossle

+0

なぜlen/2ですか? 'len'? –

+0

これはバグ、時間はptsです、進行時間を生成する必要があります – crossle

関連する問題