Unable to convert mp3 into PCM using AudioConverterFillComplexBuffer in AudioFileStreamOpen's AudioFileStream_PacketsProc callback

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

I have a AudioFileStream_PacketsProc callback set during an AudioFileStreamOpen which handles converting audio packets into PCM using AudioConverterFillComplexBuffer. The issue that I am having is that I am getting a -50 OSStatus (paramErr) after AudioConverterFillComplexBuffer is called. Below is a snippet of what parameters were used in AudioConverterFillComplexBuffer and how they were made:

        audioConverterRef = AudioConverterRef()          // AudioConvertInfo is a struct that contains information         // for the converter regarding the number of packets and          // which audiobuffer is being allocated         convertInfo? = AudioConvertInfo(done: false, numberOfPackets: numberPackets, audioBuffer: buffer,             packetDescriptions: packetDescriptions)           var framesToDecode: UInt32 = pcmBufferTotalFrameCount! - end          var localPcmAudioBuffer = AudioBuffer()         localPcmAudioBuffer.mData = pcmAudioBuffer!.mData.advancedBy(Int(end * pcmBufferFrameSizeInBytes!))          var localPcmBufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: AudioBuffer(mNumberChannels: 0, mDataByteSize: 0, mData: nil))         localPcmAudioBuffer = localPcmBufferList.mBuffers         localPcmAudioBuffer.mData = pcmAudioBuffer!.mData.advancedBy(Int(end * pcmBufferFrameSizeInBytes!))         localPcmAudioBuffer.mDataByteSize = framesToDecode * pcmBufferFrameSizeInBytes!;         localPcmAudioBuffer.mNumberChannels = pcmAudioBuffer!.mNumberChannels          var localPcmBufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: AudioBuffer(mNumberChannels: 0, mDataByteSize: 0, mData: nil))         localPcmAudioBuffer = localPcmBufferList.mBuffers          AudioConverterFillComplexBuffer(audioConverterRef, AudioConverter_Callback, &convertInfo, &framesToDecode, &localPcmBufferList, nil) 

Does what could possibly be causing the param error?

Here is the full method for the callback if needed:

func handleAudioPackets(inputData: UnsafePointer<Void>, numberBytes: UInt32, numberPackets: UInt32, packetDescriptions: UnsafeMutablePointer<AudioStreamPacketDescription>) {         if currentlyReadingEntry == nil {             print("currentlyReadingEntry = nil")             return         }         if currentlyReadingEntry.parsedHeader == false {             print("currentlyReadingEntry.parsedHeader == false")             return         }          if disposedWasRequested == true {             print("disposedWasRequested == true")             return         }          guard let audioConverterRef = audioConverterRef else {             return         }          if seekToTimeWasRequested == true && currentlyReadingEntry.calculatedBitRate() > 0.0 {             wakeupPlaybackThread()             print("seekToTimeWasRequested == true && currentlyReadingEntry.calculatedBitRate() > 0.0")             return         }          discontinuous = false          var buffer = AudioBuffer()         buffer.mNumberChannels = audioConverterAudioStreamBasicDescription.mChannelsPerFrame         buffer.mDataByteSize = numberBytes         buffer.mData = UnsafeMutablePointer<Void>(inputData)           convertInfo? = AudioConvertInfo(done: false, numberOfPackets: numberPackets, audioBuffer: buffer,             packetDescriptions: packetDescriptions)           if packetDescriptions != nil && currentlyReadingEntry.processedPacketsCount < maxCompressedBacketsForBitrateCalculation {             let count: Int = min(Int(numberPackets), Int(maxCompressedBacketsForBitrateCalculation - currentlyReadingEntry.processedPacketsCount!))             for var i = 0;i < count;++i{                 let packetSize: Int32 = Int32(packetDescriptions[i].mDataByteSize)                 OSAtomicAdd32(packetSize, &currentlyReadingEntry.processedPacketsSizeTotal!)                 OSAtomicIncrement32(&currentlyReadingEntry.processedPacketsCount!)             }         }         while true {             OSSpinLockLock(&pcmBufferSpinLock)             var used: UInt32 = pcmBufferUsedFrameCount!             var start: UInt32 = pcmBufferFrameStartIndex!             var end = (pcmBufferFrameStartIndex! + pcmBufferUsedFrameCount!) % pcmBufferTotalFrameCount!             var framesLeftInsideBuffer = pcmBufferTotalFrameCount! - used             OSSpinLockUnlock(&pcmBufferSpinLock)              if framesLeftInsideBuffer == 0 {                 pthread_mutex_lock(&playerMutex)                 while true {                     OSSpinLockLock(&pcmBufferSpinLock)                     used = pcmBufferUsedFrameCount!                     start = pcmBufferFrameStartIndex!                     end = (pcmBufferFrameStartIndex! + pcmBufferUsedFrameCount!) % pcmBufferTotalFrameCount!                     framesLeftInsideBuffer = pcmBufferTotalFrameCount! - used                     OSSpinLockUnlock(&pcmBufferSpinLock)                      if framesLeftInsideBuffer > 0 {                         break                     }                      if (disposedWasRequested == true                         || internalState == SSPlayerInternalState.Disposed) {                         pthread_mutex_unlock(&playerMutex)                         return                     }                      if (seekToTimeWasRequested == true && currentlyPlayingEntry.calculatedBitRate() > 0.0)                     {                         pthread_mutex_unlock(&playerMutex)                         wakeupPlaybackThread()                         return;                     }                      waiting = true                     pthread_cond_wait(&playerThreadReadyCondition, &playerMutex)                     waiting = false                 }                 pthread_mutex_unlock(&playerMutex)             }             var localPcmAudioBuffer = AudioBuffer()             var localPcmBufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: AudioBuffer(mNumberChannels: 0, mDataByteSize: 0, mData: nil))             localPcmAudioBuffer = localPcmBufferList.mBuffers              if end >= start {                 var framesAdded: UInt32 = 0                 var framesToDecode: UInt32 = pcmBufferTotalFrameCount! - end                 localPcmAudioBuffer.mData = pcmAudioBuffer!.mData.advancedBy(Int(end * pcmBufferFrameSizeInBytes!))                 localPcmAudioBuffer.mDataByteSize = framesToDecode * pcmBufferFrameSizeInBytes!;                 localPcmAudioBuffer.mNumberChannels = pcmAudioBuffer!.mNumberChannels                  AudioConverterFillComplexBuffer(audioConverterRef, AudioConverter_Callback, &convertInfo, &framesToDecode, &localPcmBufferList, nil)                  framesAdded = framesToDecode                  if status == 100 {                     OSSpinLockLock(&pcmBufferSpinLock)                     let newCount = pcmBufferUsedFrameCount! + framesAdded                     pcmBufferUsedFrameCount = newCount                     OSSpinLockUnlock(&pcmBufferSpinLock);                      OSSpinLockLock(&currentlyReadingEntry!.spinLock!)                     let newFramesAddedCount = currentlyReadingEntry.framesQueued! + Int64(framesAdded)                     currentlyReadingEntry!.framesQueued! = newFramesAddedCount                     OSSpinLockUnlock(&currentlyReadingEntry!.spinLock!)                     return                 } else if status != 0 {                     print("error")                     return                 }                 framesToDecode = start                  if framesToDecode == 0 {                      OSSpinLockLock(&pcmBufferSpinLock)                     let newCount = pcmBufferUsedFrameCount! + framesAdded                     pcmBufferUsedFrameCount = newCount                     OSSpinLockUnlock(&pcmBufferSpinLock);                      OSSpinLockLock(&currentlyReadingEntry!.spinLock!)                     let newFramesAddedCount = currentlyReadingEntry.framesQueued! + Int64(framesAdded)                     currentlyReadingEntry!.framesQueued! = newFramesAddedCount                     OSSpinLockUnlock(&currentlyReadingEntry!.spinLock!)                     continue                 }                  localPcmAudioBuffer.mData = pcmAudioBuffer!.mData                 localPcmAudioBuffer.mDataByteSize = framesToDecode * pcmBufferFrameSizeInBytes!                 localPcmAudioBuffer.mNumberChannels = pcmAudioBuffer!.mNumberChannels                  AudioConverterFillComplexBuffer(audioConverterRef, AudioConverter_Callback, &convertInfo, &framesToDecode, &localPcmBufferList, nil)                 let decodedFramesAdded = framesAdded + framesToDecode                 framesAdded = decodedFramesAdded                  if status == 100 {                     OSSpinLockLock(&pcmBufferSpinLock)                     let newCount = pcmBufferUsedFrameCount! + framesAdded                     pcmBufferUsedFrameCount = newCount                     OSSpinLockUnlock(&pcmBufferSpinLock);                      OSSpinLockLock(&currentlyReadingEntry!.spinLock!)                     let newFramesAddedCount = currentlyReadingEntry.framesQueued! + Int64(framesAdded)                     currentlyReadingEntry!.framesQueued! = newFramesAddedCount                     OSSpinLockUnlock(&currentlyReadingEntry!.spinLock!)                     return                 } else if status == 0 {                     OSSpinLockLock(&pcmBufferSpinLock)                     let newCount = pcmBufferUsedFrameCount! + framesAdded                     pcmBufferUsedFrameCount = newCount                     OSSpinLockUnlock(&pcmBufferSpinLock);                      OSSpinLockLock(&currentlyReadingEntry!.spinLock!)                     let newFramesAddedCount = currentlyReadingEntry.framesQueued! + Int64(framesAdded)                     currentlyReadingEntry!.framesQueued! = newFramesAddedCount                     OSSpinLockUnlock(&currentlyReadingEntry!.spinLock!)                     continue                 } else if status != 0 {                     print("error")                     return                 } else {                     var framesAdded: UInt32 = 0                     var framesToDecode: UInt32 = start - end                     localPcmAudioBuffer.mData = pcmAudioBuffer!.mData.advancedBy(Int(end * pcmBufferFrameSizeInBytes!))                     localPcmAudioBuffer.mDataByteSize = framesToDecode * pcmBufferFrameSizeInBytes!;                     localPcmAudioBuffer.mNumberChannels = pcmAudioBuffer!.mNumberChannels                      var  convertInfoo: UnsafePointer<Void> = unsafeBitCast(convertInfo, UnsafePointer<Void>.self)                      status = AudioConverterFillComplexBuffer(audioConverterRef, AudioConverter_Callback, &convertInfoo, &framesToDecode, &localPcmBufferList, nil)                      framesAdded = framesToDecode                      if status == 100 {                         OSSpinLockLock(&pcmBufferSpinLock)                         let newCount = pcmBufferUsedFrameCount! + framesAdded                         pcmBufferUsedFrameCount = newCount                         OSSpinLockUnlock(&pcmBufferSpinLock);                          OSSpinLockLock(&currentlyReadingEntry!.spinLock!)                         let newFramesAddedCount = currentlyReadingEntry.framesQueued! + Int64(framesAdded)                         currentlyReadingEntry!.framesQueued! = newFramesAddedCount                         OSSpinLockUnlock(&currentlyReadingEntry!.spinLock!)                         return                     } else if status == 0 {                         OSSpinLockLock(&pcmBufferSpinLock)                         let newCount = pcmBufferUsedFrameCount! + framesAdded                         pcmBufferUsedFrameCount = newCount                         OSSpinLockUnlock(&pcmBufferSpinLock);                          OSSpinLockLock(&currentlyReadingEntry!.spinLock!)                         let newFramesAddedCount = currentlyReadingEntry.framesQueued! + Int64(framesAdded)                         currentlyReadingEntry!.framesQueued! = newFramesAddedCount                         OSSpinLockUnlock(&currentlyReadingEntry!.spinLock!)                         continue                     } else if status != 0 {                         print("error")                         return                     }                  }             }         }     } 

回答1:

Hej @3254523, I have some answers with possible solutions for you. I hope to guide you in the right way in spite of I am not expert in this major. So, the problem is for sure the configuration of:

AudioBufferList 

Here the links that probes the hints of this -50 OSStatus related to the AudioBufferList: http://lists.apple.com/archives/coreaudio-api/2012/Apr/msg00041.html https://forums.developer.apple.com/thread/6313

Now, we have to focus in a solutions. Looking through your AudioBufferList, you have no assigned any value but mNumberBuffers which is 1. Try to change the values in the following way(as it shown in the second link):

var localPcmBufferList = AudioBufferList(mNumberBuffers: 2, mBuffers: AudioBuffer(mNumberChannels: 2, mDataByteSize: UInt32(buffer.count), mData: &buffer)) 

If still is not working, we have to focus to correct it properly, hence here you can find the solution to the -50 OSStatus in AudioConverterFillComplexBuffer although not in swift:

AudioConverterFillComplexBuffer return -50 (paramErr)

iPhone: AudioBufferList init and release



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!