Advertisement
Guest User

AudioConverter bug?

a guest
Jun 5th, 2013
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3.     // .....
  4.    
  5.     AudioStreamBasicDescription inputASBD = [AppDelegate interleaved16BitStereoAudioDescription];
  6.     AudioStreamBasicDescription outputASBD = [AppDelegate interleaved16BitStereoAudioDescription];
  7.    
  8.     // Or, to see this work properly:
  9.     //    AudioStreamBasicDescription inputASBD = [AppDelegate nonInterleaved16BitStereoAudioDescription];
  10.     //    AudioStreamBasicDescription outputASBD = [AppDelegate nonInterleaved16BitStereoAudioDescription];
  11.    
  12.     AudioConverterRef converter = NULL;
  13.     checkResult(AudioConverterNew(&inputASBD, &outputASBD, &converter), "AudioConverterNew");
  14.    
  15.     UInt32 channelMap[2] = {0, 0};
  16.     checkResult(AudioConverterSetProperty(converter, kAudioConverterChannelMap, sizeof(channelMap), channelMap), "AudioConverterSetProperty(kAudioConverterChannelMap");
  17.  
  18.     UInt32 frameCount = 64;
  19.    
  20.     AudioBufferList *inputBufferList  = allocateAndInitAudioBufferList(inputASBD, frameCount);
  21.     AudioBufferList *outputBufferList = allocateAndInitAudioBufferList(outputASBD, frameCount);
  22.    
  23.     for ( int i=0; i<frameCount; i++ ) {
  24.         if ( inputASBD.mFormatFlags & kAudioFormatFlagIsNonInterleaved ) {
  25.             ((SInt16*)inputBufferList->mBuffers[0].mData)[i] = 2*i;
  26.             ((SInt16*)inputBufferList->mBuffers[1].mData)[i] = 2*i + 1;
  27.         } else {
  28.             ((SInt16*)inputBufferList->mBuffers[0].mData)[2*i] = 2*i;
  29.             ((SInt16*)inputBufferList->mBuffers[0].mData)[2*i + 1] = 2*i + 1;
  30.         }
  31.     }
  32.    
  33.     OSStatus result = AudioConverterFillComplexBuffer(converter,
  34.                                                       fillComplexBufferInputProc,
  35.                                                       &(struct fillComplexBufferInputProc_t) { .bufferList = inputBufferList, .frames = frameCount },
  36.                                                       &frameCount,
  37.                                                       outputBufferList,
  38.                                                       NULL);
  39.     checkResult(result, "AudioConverterFillComplexBuffer");
  40.    
  41.     printf("Expected\t\tActual\n");
  42.     for ( int i=0; i<frameCount; i++ ) {
  43.         printf("%3d\t%3d\t\t%3d\t%3d\n",
  44.                2*i + (int)channelMap[0],
  45.                2*i + (int)channelMap[1],
  46.                outputASBD.mFormatFlags & kAudioFormatFlagIsNonInterleaved ? ((SInt16*)outputBufferList->mBuffers[0].mData)[i] : ((SInt16*)outputBufferList->mBuffers[0].mData)[2*i],
  47.                outputASBD.mFormatFlags & kAudioFormatFlagIsNonInterleaved ? ((SInt16*)outputBufferList->mBuffers[1].mData)[i] : ((SInt16*)outputBufferList->mBuffers[0].mData)[2*i+1]);
  48.     }
  49.    
  50.     return YES;
  51. }
  52.  
  53. #pragma mark - Helpers
  54.  
  55. + (AudioStreamBasicDescription)interleaved16BitStereoAudioDescription {
  56.     AudioStreamBasicDescription audioDescription;
  57.     memset(&audioDescription, 0, sizeof(audioDescription));
  58.     audioDescription.mFormatID          = kAudioFormatLinearPCM;
  59.     audioDescription.mFormatFlags       = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian;
  60.     audioDescription.mChannelsPerFrame  = 2;
  61.     audioDescription.mBytesPerPacket    = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
  62.     audioDescription.mFramesPerPacket   = 1;
  63.     audioDescription.mBytesPerFrame     = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
  64.     audioDescription.mBitsPerChannel    = 8 * sizeof(SInt16);
  65.     audioDescription.mSampleRate        = 44100.0;
  66.     return audioDescription;
  67. }
  68.  
  69. + (AudioStreamBasicDescription)nonInterleaved16BitStereoAudioDescription {
  70.     AudioStreamBasicDescription audioDescription;
  71.     memset(&audioDescription, 0, sizeof(audioDescription));
  72.     audioDescription.mFormatID          = kAudioFormatLinearPCM;
  73.     audioDescription.mFormatFlags       = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsNonInterleaved;
  74.     audioDescription.mChannelsPerFrame  = 2;
  75.     audioDescription.mBytesPerPacket    = sizeof(SInt16);
  76.     audioDescription.mFramesPerPacket   = 1;
  77.     audioDescription.mBytesPerFrame     = sizeof(SInt16);
  78.     audioDescription.mBitsPerChannel    = 8 * sizeof(SInt16);
  79.     audioDescription.mSampleRate        = 44100.0;
  80.     return audioDescription;
  81. }
  82.  
  83. struct fillComplexBufferInputProc_t { AudioBufferList *bufferList; UInt32 frames;  };
  84. static OSStatus fillComplexBufferInputProc(AudioConverterRef             inAudioConverter,
  85.                                            UInt32                        *ioNumberDataPackets,
  86.                                            AudioBufferList               *ioData,
  87.                                            AudioStreamPacketDescription  **outDataPacketDescription,
  88.                                            void                          *inUserData) {
  89.     struct fillComplexBufferInputProc_t *arg = inUserData;
  90.     for ( int i=0; i<ioData->mNumberBuffers; i++ ) {
  91.         ioData->mBuffers[i].mData = arg->bufferList->mBuffers[i].mData;
  92.         ioData->mBuffers[i].mDataByteSize = arg->bufferList->mBuffers[i].mDataByteSize;
  93.     }
  94.     *ioNumberDataPackets = arg->frames;
  95.     return noErr;
  96. }
  97.  
  98. AudioBufferList *allocateAndInitAudioBufferList(AudioStreamBasicDescription audioFormat, int frameCount) {
  99.     int numberOfBuffers = audioFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved ? audioFormat.mChannelsPerFrame : 1;
  100.     int channelsPerBuffer = audioFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved ? 1 : audioFormat.mChannelsPerFrame;
  101.     int bytesPerBuffer = audioFormat.mBytesPerFrame * frameCount;
  102.    
  103.     AudioBufferList *audio = malloc(sizeof(AudioBufferList) + (numberOfBuffers-1)*sizeof(AudioBuffer));
  104.     if ( !audio ) {
  105.         return NULL;
  106.     }
  107.     audio->mNumberBuffers = numberOfBuffers;
  108.     for ( int i=0; i<numberOfBuffers; i++ ) {
  109.         if ( bytesPerBuffer > 0 ) {
  110.             audio->mBuffers[i].mData = malloc(bytesPerBuffer);
  111.             if ( !audio->mBuffers[i].mData ) {
  112.                 for ( int j=0; j<i; j++ ) free(audio->mBuffers[j].mData);
  113.                 free(audio);
  114.                 return NULL;
  115.             }
  116.         } else {
  117.             audio->mBuffers[i].mData = NULL;
  118.         }
  119.         audio->mBuffers[i].mDataByteSize = bytesPerBuffer;
  120.         audio->mBuffers[i].mNumberChannels = channelsPerBuffer;
  121.     }
  122.     return audio;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement