2017-03-23 12 views
1

PCMオーディオを16kHzから8kHzに変換しようとしましたが、サンプルレートだけでフォーマットは変更されず、フローはシンプルに見えますがkAudioConverterErr_InvalidInputSize( "insz")からAudioConverterFillComplexBuffer 。私の入力オーディオサンプルサイズは320バイトですが、結果は160バイトと思われますが、出力バッファには144バイトしかありません。最後のカップルの時間のために私の髪を引っ張っている。設定が間違っていますか?iOSで16kHzから8kHzにオーディオサンプルレートを変換する

static AudioConverterRef PCM8kTo16kConverterRef; 

- (instancetype)init { 
    self = [super init]; 
    if (self) { 
     [self initConverter]; 
    } 
    return self; 
} 

-(void)initConverter{ 
    AudioStreamBasicDescription PCM8kDescription = {0}; 
    PCM8kDescription.mSampleRate = 8000.0; 
    PCM8kDescription.mFormatID = kAudioFormatLinearPCM; 
    PCM8kDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian; 
    PCM8kDescription.mBitsPerChannel = 8 * sizeof(SInt16); 
    PCM8kDescription.mChannelsPerFrame = 1; 
    PCM8kDescription.mBytesPerFrame = sizeof(SInt16) * PCM8kDescription.mChannelsPerFrame; 
    PCM8kDescription.mFramesPerPacket = 1; 
    PCM8kDescription.mBytesPerPacket = PCM8kDescription.mBytesPerFrame * PCM8kDescription.mFramesPerPacket; 

    AudioStreamBasicDescription PCM16kDescription = {0}; 
    PCM16kDescription.mSampleRate = 16000.0; 
    PCM16kDescription.mFormatID = kAudioFormatLinearPCM; 
    PCM16kDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian; 
    PCM16kDescription.mBitsPerChannel = 8 * sizeof(SInt16); 
    PCM16kDescription.mChannelsPerFrame = 1; 
    PCM16kDescription.mBytesPerFrame = sizeof(SInt16) * PCM16kDescription.mChannelsPerFrame; 
    PCM16kDescription.mFramesPerPacket = 1; 
    PCM16kDescription.mBytesPerPacket = PCM16kDescription.mBytesPerFrame * PCM16kDescription.mFramesPerPacket; 

    OSStatus status = AudioConverterNew(&PCM16kDescription, &PCM8kDescription, &converterRef); 
} 

OSStatus inInputDataProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) 
{ 
    AudioBufferList audioBufferList = *(AudioBufferList *)inUserData; 

    ioData->mBuffers[0].mData = audioBufferList.mBuffers[0].mData; 
    ioData->mBuffers[0].mDataByteSize = audioBufferList.mBuffers[0].mDataByteSize; 

    return noErr; 
} 

- (NSData *)testSample:(NSData *)inAudio { 

    NSMutableData *ddd = [inAudio mutableCopy]; 
    AudioBufferList inAudioBufferList = {0}; 
    inAudioBufferList.mNumberBuffers = 1; 
    inAudioBufferList.mBuffers[0].mNumberChannels = 1; 
    inAudioBufferList.mBuffers[0].mDataByteSize = (UInt32)[ddd length]; 
    inAudioBufferList.mBuffers[0].mData = [ddd mutableBytes]; 

    uint32_t bufferSize = (UInt32)[inAudio length]/2; 
    uint8_t *buffer = (uint8_t *)malloc(bufferSize); 
    memset(buffer, 0, bufferSize); 
    AudioBufferList outAudioBufferList; 
    outAudioBufferList.mNumberBuffers = 1; 
    outAudioBufferList.mBuffers[0].mNumberChannels = 1; 
    outAudioBufferList.mBuffers[0].mDataByteSize = bufferSize; 
    outAudioBufferList.mBuffers[0].mData = buffer; 

    UInt32 ioOutputDataPacketSize = bufferSize; 

    OSStatus ret = AudioConverterFillComplexBuffer(converterRef, inInputDataProc, &inAudioBufferList, &ioOutputDataPacketSize, &outAudioBufferList, NULL) ; 

    NSData *data = [NSData dataWithBytes:outAudioBufferList.mBuffers[0].mData length:outAudioBufferList.mBuffers[0].mDataByteSize]; 
    free(buffer); 
    return data; 
} 

答えて

2

二つの問題があります。

  1. は、あなたのAudioConverterComplexInputDataProcioNumberDataPacketsを設定されていません。

    *ioNumberDataPackets = audioBufferList.mBuffers[0].mDataByteSize/2; 
    
  2. ioOutputDataPacketSizeは、パケット/フレームでの出力バッファ容量ことになっているが、バイトではないので、2で割ってはいけませんか?
+1

ありがとうございました!それはそれだった。これらの変数が正しい意味を持っていなかったので、今度はXDをもう一度感謝します! – Elvin

+0

これを迅速に行う方法は? –