Я пытаюсь преобразовать AudioBufferList
что я получаю от блока Audio в CMSampleBuffer
, что я могу передать в AVAssetWriter
, чтобы сохранить звук с микрофона. Это преобразование работает, поскольку вызовы, которые я делаю для выполнения преобразования, не терпят неудачу, но запись в конечном итоге не выполняется, и я вижу некоторый вывод в журналах, которые, как представляется, вызывают беспокойство.Преобразование AudioBufferList к CMSampleBuffer Производит Неожиданные результаты
код я использую, выглядит так:
- (void)handleAudioSamples:(AudioBufferList*)samples numSamples:(UInt32)numSamples hostTime:(UInt64)hostTime {
// Create a CMSampleBufferRef from the list of samples, which we'll own
AudioStreamBasicDescription monoStreamFormat;
memset(&monoStreamFormat, 0, sizeof(monoStreamFormat));
monoStreamFormat.mSampleRate = 48000;
monoStreamFormat.mFormatID = kAudioFormatLinearPCM;
monoStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
monoStreamFormat.mBytesPerPacket = 2;
monoStreamFormat.mFramesPerPacket = 1;
monoStreamFormat.mBytesPerFrame = 2;
monoStreamFormat.mChannelsPerFrame = 1;
monoStreamFormat.mBitsPerChannel = 16;
CMFormatDescriptionRef format = NULL;
OSStatus status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &monoStreamFormat, 0, NULL, 0, NULL, NULL, &format);
if (status != noErr) {
// really shouldn't happen
return;
}
CMSampleTimingInfo timing = { CMTimeMake(1, 48000), kCMTimeZero, kCMTimeInvalid };
CMSampleBufferRef sampleBuffer = NULL;
status = CMSampleBufferCreate(kCFAllocatorDefault, NULL, false, NULL, NULL, format, numSamples, 1, &timing, 0, NULL, &sampleBuffer);
if (status != noErr) {
// couldn't create the sample buffer
PTKLogError(@"Failed to create sample buffer");
CFRelease(format);
return;
}
// add the samples to the buffer
status = CMSampleBufferSetDataBufferFromAudioBufferList(sampleBuffer,
kCFAllocatorDefault,
kCFAllocatorDefault,
0,
samples);
if (status != noErr) {
PTKLogError(@"Failed to add samples to sample buffer");
CFRelease(sampleBuffer);
CFRelease(format);
return;
}
NSLog(@"Original sample buf size: %ld for %d samples from %d buffers, first buffer has size %d", CMSampleBufferGetTotalSampleSize(sampleBuffer), numSamples, samples->mNumberBuffers, samples->mBuffers[0].mDataByteSize);
NSLog(@"Original sample buf has %ld samples", CMSampleBufferGetNumSamples(sampleBuffer));
Как я уже говорил, не кажется такой код, терпит неудачу, сама по себе, но AVAssetWriter
не нравится, и CMSampleBuffer
что Я создаю, кажется, размер 0, основываясь на том факте, что следующие записи журнала в настоящее время вошли:
2015-07-09 19:34:00.710 xxxx[1481:271334] Original sample buf size: 0 for 1024 samples from 1 buffers, first buffer has size 2048
2015-07-09 19:34:00.710 xxxx[1481:271334] Original sample buf has 1024 samples
как ни странно, буфер выборки сообщает, что он имеет 1024 выборок, но размер 0. Оригинальный AudioBufferList имеет 2048 байт данных, что я ожидаю от 1024 2-байтовых выборки.
Я делаю что-то неправильно с точки зрения того, как я инициализирую и заселяю CMSampleBuffer
?
Что такое _hostTimeToNSFactor? спасибо –
@PabloMartinez Мы вычислили его, вызвав 'mach_timebase_info' и эту математику:' _hostTimeToNSFactor = (double) tinfo.numer/tinfo.denom'. Однако может быть лучший подход: https://developer.apple.com/library/ios/qa/qa1643/_index.html –
Спасибо Джим, и какое значение вы передаете функции в hostTime? –