这是我的init音频方法:
#define AUdio_QUAliTY 10- (voID) initAudio { try { //SPEEX CONfig speex_bits_init(&bits_in); speex_bits_init(&bits_out); enc_state = speex_encoder_init(&speex_nb_mode); dec_state = speex_decoder_init(&speex_nb_mode); int quality = AUdio_QUAliTY; speex_encoder_ctl(enc_state,SPEEX_SET_QUAliTY,&quality); int tmp=1; speex_decoder_ctl(dec_state,SPEEX_SET_ENH,&tmp); Osstatus status; XThrowIfError(AudioSessionInitialize(NulL,NulL,rioInterruptionListener,self),"Couldn't initialize audio session"); float aBufferLength = 0.02; // In seconds status = AudioSessionSetProperty(kAudioSessionProperty_PreferredHarDWareIOBufferDuration,sizeof(aBufferLength),&aBufferLength); XThrowIfError(status,""); UInt32 audiocategory = kAudioSessioncategory_PlayAndRecord; XThrowIfError(AudioSessionSetProperty(kAudioSessionProperty_Audiocategory,sizeof(audiocategory),&audiocategory),"Couldn't set audio category"); XThrowIfError(AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange,propListener,"Couldn't set property Listener"); // Describe audio component AudioComponentDescription desc; desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_RemoteIO; desc.componentFlags = 0; desc.componentFlagsMask = 0; desc.componentManufacturer = kAudioUnitManufacturer_Apple; // Get component AudioComponent inputComponent = AudioComponentFindNext(NulL,&desc); // Get audio units status = AudioComponentInstanceNew(inputComponent,&rIoUnit); XThrowIfError(status,"1"); // Enable IO for recording UInt32 flag = 1; status = AudioUnitSetProperty(rIoUnit,kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_input,kinputBus,&flag,sizeof(flag)); XThrowIfError(status,"2"); // Enable IO for playback status = AudioUnitSetProperty(rIoUnit,kAudioUnitScope_Output,kOutputBus,"3"); // Describe format AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 8000.00; audioFormat.mFormatID = kAudioFormatlinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = 2; audioFormat.mBytesPerFrame = 2; // Apply format status = AudioUnitSetProperty(rIoUnit,kAudioUnitProperty_StreamFormat,&audioFormat,sizeof(audioFormat)); XThrowIfError(status,""); status = AudioUnitSetProperty(rIoUnit,""); // Set input callback AURenderCallbackStruct callbackStruct; callbackStruct.inputProc = recordingCallback; callbackStruct.inputProcRefCon = self; status = AudioUnitSetProperty(rIoUnit,kAudioOutputUnitProperty_SetinputCallback,kAudioUnitScope_Global,&callbackStruct,sizeof(callbackStruct)); XThrowIfError(status,""); // Set output callback callbackStruct.inputProc = playingCallback; callbackStruct.inputProcRefCon = self; status = AudioUnitSetProperty(rIoUnit,kAudioUnitProperty_SetRenderCallback,""); // disable buffer allocation for the recorder (optional - do this if we want to pass in our own) flag = 0; status = AudioUnitSetProperty(rIoUnit,kAudioUnitProperty_ShouldAllocateBuffer,sizeof(flag)); // Allocate our own buffers (1 channel,16 bits per sample,thus 16 bits per frame,thus 2 bytes per frame). // Practice learns the buffers used contain 512 frames,if this changes it will be fixed in processAudio. tempBuffer.mNumberChannels = 1; tempBuffer.mDataByteSize = FRAME_SIZE * 2; tempBuffer.mData = malloc( FRAME_SIZE * 2 ); XThrowIfError(AudioSessionSetActive(true),"Couldn't set audio session active\n"); // Initialise status = AudioUnitinitialize(rIoUnit); XThrowIfError(status,""); status = AudioOutputUnitStart(rIoUnit); XThrowIfError(status,""); } catch (CAXException &e) { NSLog(@"CAXException..."); } catch (...) { fprintf(stderr,"An unkNown error occurred\n"); }}
我的speex编码&解码功能:
#define FRAME_SIZE 160#define COMP_FRAME_SIZE 62char* encodeSpeex(spx_int16_t *buffer,UInt32 inSize,int *encodedSize) { char *outputBuffer = (char *)malloc(COMP_FRAME_SIZE); speex_bits_reset(&bits_in); speex_encode_int(enc_state,buffer,&bits_in); *encodedSize = speex_bits_write(&bits_in,outputBuffer,FRAME_SIZE * 2); return outputBuffer;}short* decodeSpeex(char* buffer,int encodedSize,int decodedSize) { short *outTemp = (short *)calloc(1,FRAME_SIZE * 2); speex_bits_read_from(&bits_out,encodedSize * FRAME_SIZE * *2); speex_decode_int(dec_state,&bits_out,outTemp); return outTemp;}
最后,调用speex编码的功能&解码并将其复制到将由特定回调播放的缓冲区:
- (voID) processAudio: (audiobufferlist*) bufferList{ AudioBuffer sourceBuffer = bufferList->mBuffers[0]; NSLog(@"Origin size: %lu",sourceBuffer.mDataByteSize); int size = 0; char *encodedAudio = encodeSpeex((spx_int16_t*) sourceBuffer.mData,sourceBuffer.mDataByteSize,&size); NSLog(@"Encoded size: %i",size); short* decodedAudio = decodeSpeex(encodedAudio,size,sourceBuffer.mDataByteSize); free(encodedAudio); memcpy(tempBuffer.mData,decodedAudio,FRAME_SIZE * 2); free(decodedAudio); }
任何人都知道我为什么会这么差的质量?根据网站上的speex示例,它不应该像那样……
解决方法 我也偶然发现了这个问题.我通过检查我的缓冲区是否实际填充正确来解决它.否则,您将获得播放的空数据,从而产生机器人声音. 总结以上是内存溢出为你收集整理的Speex(在ios中)声音质量很差(和机器人)全部内容,希望文章能够帮你解决Speex(在ios中)声音质量很差(和机器人)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)