2017-03-23 2 views
1

Ich habe versucht, PCM-Audio von 16kHz auf 8kHz zu konvertieren, nur Sample-Rate, keine Formatänderung, sieht der Fluss einfach, aber ich erhielt kAudioConverterErr_InvalidInputSize ("insz") von Aufruf AudioConverterFillComplexBuffer . Meine Eingabe-Audio-Sample-Größe ist 320 Bytes, das Ergebnis soll 160 Bytes sein, aber ich habe gerade 144 Bytes in meinem Ausgabepuffer. Ich habe mir in den letzten paar Stunden die Haare ausgezogen. Gibt es eine falsche Einstellung?iOS konvertieren Audio-Abtastrate von 16 kHz bis 8 kHz

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

Antwort

2

Es gibt zwei Probleme:

  1. Ihre AudioConverterComplexInputDataProc nicht Einstellung ioNumberDataPackets:

    *ioNumberDataPackets = audioBufferList.mBuffers[0].mDataByteSize/2; 
    
  2. ioOutputDataPacketSize soll die Ausgangspufferkapazität in Pakete/Frames, sein keine Bytes, also solltest du nicht durch 2 teilen?
+1

Vielen Dank! Das war's. Habe die richtige Bedeutung dieser Variablen nicht bekommen, jetzt macht es Sinn XD Danke nochmal! – Elvin

+0

wie geht das in swift? –

Verwandte Themen