ios audioqueue 流播放接口
来源:互联网 发布:jsonarray 添加数据 编辑:程序博客网 时间:2024/05/16 17:20
AudioMedia_ios.h
//// AudioMedia_ios.h// mmsplayer//// Created by Weiny on 12-4-4.// Copyright (c) 2012年 Weiny Zhou. All rights reserved.//#ifndef mmsplayer_AudioMedia_ios_h#define mmsplayer_AudioMedia_ios_h#include "wdef.h"typedef void* wAudio;#ifdef __cplusplusextern "C"{#endif wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize);//初始化声音接口 int audio_play(wAudio audio);//播放int audio_pause(wAudio audio); int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dts);//写入音频数据 int audio_stop(wAudio audio);//停止 int audio_close(wAudio audio);//关闭#ifdef __cplusplus};#endif #endif
AudioMedia_ios.c
//// AudioMedia_ios.cpp// mmsplayer//// Created by Weiny on 12-4-4.// Copyright (c) 2012年 Weiny Zhou. All rights reserved.//#include "AudioMedia_ios.h"#include <AudioToolbox/AudioQueue.h>#include "system/thread.h"#include "base/wlist.h"#include "system/lx_lock.h"#define AUDIO_LIST_COUNT 3#define AUDIO_BUFFER_SECONDS 1typedef struct WAudio_Ios{int playRequested;int framesize;Wlock mlock,mdecdonelock,mqueuelock;wlist_t mAudiolist;//声音队列wlist_func mlistfunc; AudioQueueRef queue;//player list AudioQueueBufferRef mBuffers[AUDIO_LIST_COUNT]; AudioStreamBasicDescription mDataFormat;AudioQueueBufferRef emptyAudioBuffer;//空音频队列}WAudio_Ios;typedef struct {void* data;size_t size; int64_t dst;}WAudio_item;void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef outQB);void wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer);static inline void waudio_free_back(void* lpvoid,wlist_item_ptr data){WAudio_item* item;INTOFUNC();if(!data){PRINTF_ERROR_VALUE(ERROR_INITPARAM);goto error_lab;}item=(WAudio_item*)data;SAFE_FREE(item->data);SAFE_FREE(item);error_lab:EXITFUNC();}wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize){ WAudio_Ios* ptr=NULL; uint32_t err=0;int i=0; INTOFUNC(); ptr=WOS_MALLOC_(WAudio_Ios, 1); if(!ptr){ PRINTF_ERROR_VALUE(ERROR_NEWMEM); goto error_lab; } memset(ptr,0,sizeof(WAudio_Ios)); ptr->mDataFormat.mSampleRate=sample;//设置采样率ptr->mDataFormat.mChannelsPerFrame=nchannles;ptr->mDataFormat.mBitsPerChannel=bits; ptr->mDataFormat.mFormatID=kAudioFormatLinearPCM;//设置数据格式 ptr->mDataFormat.mFormatFlags=kLinearPCMFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; ptr->mDataFormat.mFramesPerPacket=1; ptr->mDataFormat.mBytesPerFrame=ptr->mDataFormat.mBitsPerChannel/ptr->mDataFormat.mChannelsPerFrame; ptr->mDataFormat.mBytesPerPacket= ptr->mDataFormat.mBytesPerFrame*ptr->mDataFormat. mFramesPerPacket; err=AudioQueueNewOutput(&ptr->mDataFormat,wAudio_CallBack, ptr, NULL, NULL/*kCFRunLoopCommonModes*/, 0 , &ptr->queue); if(err){ WERROR_A("init audio output error,sample=%d,channles=%d,bits=%d.\n",sample,nchannles,bits); goto error_lab; }for (i=0;i<AUDIO_LIST_COUNT;++i){err=AudioQueueAllocateBufferWithPacketDescriptions(ptr->queue,bits*AUDIO_BUFFER_SECONDS/8,sample*AUDIO_BUFFER_SECONDS/nFrameSize+1,ptr->mBuffers+i);if(err){WERROR_A("can't allocate audio queue buffer: %d",err); goto error_lab;}}ptr->mlock=lx_lock_init();ptr->mdecdonelock=lx_lock_init();ptr->mqueuelock=lx_lock_init();ptr->mlistfunc=wlist_getfunc();ptr->mAudiolist.free=waudio_free_back;ptr->framesize=nFrameSize;#if 1err=AudioQueueStart(ptr->queue,NULL);if(err){WERROR_A("Error: Audio queue failed to start: %d", err);goto error_lab;} ptr->playRequested=1;WDEBUG_OUT("Started Audio queue.",NULL);#endif#if 0 agc.FrameCount = FRAME_COUNT; bufferSize = agc.FrameCount * agc.mDataFormat.mBytesPerFrame; for (i=0; i<AUDIO_BUFFERS; i++) { err = AudioQueueAllocateBuffer(agc.queue,bufferSize,&agc.mBuffers[i]); if(err) return err; AQBufferCallback(&agc,agc.queue,agc.mBuffers[i]); } err = AudioQueueStart(agc.queue,NULL); if(err) return err; while (agc.playPtr<agc.sampleLen) { select(NULL,NULL,NULL,NULL,1.0); } #endiferror_lab:if(err){audio_close(ptr);SAFE_FREE(ptr);} EXITFUNC(); return (wAudio)ptr;}int audio_play(wAudio audio){ int nResult=0; WAudio_Ios* ptr=NULL; INTOFUNC(); if(!audio){ WERROR_A("input audio is null",NULL); nResult=ERROR_INITPARAM; goto error_lab; } ptr=(WAudio_Ios*)audio;if(ptr->playRequested==0||ptr->playRequested==2){WERROR_A("state is %d",ptr->playRequested);goto error_lab;}ptr->playRequested=1;AudioQueueStart(ptr->queue,NULL);error_lab: EXITFUNC(); return nResult;}int audio_pause(wAudio audio){int nResult=0;WAudio_Ios* ptr=NULL;INTOFUNC();if(!audio){WERROR_A("input audio is null",NULL);nResult=ERROR_INITPARAM;goto error_lab;}ptr=(WAudio_Ios*)audio;if(1!=ptr->playRequested){WERROR_A("state is %d",ptr->playRequested);goto error_lab;}ptr->playRequested=2;AudioQueuePause(ptr->queue);error_lab:EXITFUNC();return nResult;}int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dst){ int nResult=0; WAudio_Ios* ptr=NULL;WAudio_item* item=NULL; INTOFUNC(); if(!audio){ WERROR_A("input audio is null",NULL); nResult=ERROR_INITPARAM; goto error_lab; } ptr=(WAudio_Ios*)audio;item=WOS_MALLOC_(WAudio_item,1);if(!item){nResult=ERROR_NEWMEM;PRINTF_ERROR_VALUE(nResult);goto error_lab;}item->data=pcm;item->size=count; item->dst=dst;lx_lock(ptr->mqueuelock);//先加入队列ptr->mlistfunc.push_back(&ptr->mAudiolist,item);//if(ptr->emptyAudioBuffer)wAudtio_fillAudioBuffer(ptr,ptr->emptyAudioBuffer);//填充空bufferlx_unlock(ptr->mqueuelock);error_lab: EXITFUNC(); return nResult;}int audio_stop(wAudio audio){ int nResult=0; WAudio_Ios* ptr=NULL; INTOFUNC(); if(!audio){ WERROR_A("input audio is null",NULL); nResult=ERROR_INITPARAM; goto error_lab; } ptr=(WAudio_Ios*)audio; AudioQueueStop(ptr->queue,false);ptr->playRequested=0;error_lab: EXITFUNC(); return nResult;}int audio_close(wAudio audio){ int nResult=0; WAudio_Ios* ptr=NULL; INTOFUNC(); if(!audio){ WERROR_A("input audio is null.",NULL); nResult=ERROR_INITPARAM; goto error_lab; } ptr=(WAudio_Ios*)audio;ptr->mlistfunc.clear(&ptr->mAudiolist);//清空播放队列lx_lock_free(ptr->mqueuelock);lx_lock_free(ptr->mdecdonelock);lx_lock_free(ptr->mlock); AudioQueueDispose(ptr->queue,false); SAFE_FREE(ptr);error_lab: EXITFUNC(); return nResult;}#if 0void AQBufferCallback( void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB) { AQCallbackStruct *agc; short *coreAudiobuffer; short sample; int i; agc=(AQCallbackStruct *) in; coreAudiobuffer =(short*) outQB->mAudioData; printf("Sync:%i / %i \n",agc->playPtr,agc->sampleLen); if (agc->FrameCount >0) { outQB->mAudioDataByteSize = 4*agc->FrameCount; for (i=0; i<agc->FrameCount*2; i++) { if(agc->playPtr > agc->sampleLen || agc->playPtr<0) { sample =0; } else { sample = (agc->pcmBuffer[agc->playPtr]); } coreAudiobuffer[i] = sample; coreAudiobuffer[i+1] = sample; agc->playPtr++; } AudioQueueEnqueueBuffer(inQ,outQB,0,NULL); } }#endifvoid wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer){AudioTimeStamp bufferStartTime;uint32_t err;INTOFUNC();buffer->mAudioDataByteSize=0;buffer->mPacketDescriptionCount=0;if(audio->mAudiolist.size<=0){WERROR_A("Warning: No audio packets in queue.",NULL);audio->emptyAudioBuffer=buffer;goto error_lab;}audio->emptyAudioBuffer=NULL;while(audio->mAudiolist.size&&buffer->mPacketDescriptionCount <buffer->mPacketDescriptionCapacity){wlist_item* item=audio->mlistfunc.pop_front(&audio->mAudiolist);WAudio_item* data=(WAudio_item*)item->data;if(buffer->mAudioDataBytesCapacity -buffer->mAudioDataByteSize >=data->size){ if(buffer->mAudioDataBytesCapacity==0) { bufferStartTime.mSampleTime=data->dst*audio->framesize; bufferStartTime.mFlags=kAudioTimeStampSampleTimeValid; } memcpy((uint8_t *)buffer->mAudioData + buffer->mAudioDataByteSize, data->data, data->size); buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mStartOffset = buffer->mAudioDataByteSize; buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mDataByteSize = data->size; buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mVariableFramesInPacket = audio->framesize; buffer->mAudioDataByteSize += data->size; ++buffer->mPacketDescriptionCount; lx_lock(audio->mqueuelock); audio->mlistfunc.remove(&audio->mAudiolist,0); lx_unlock(audio->mqueuelock);}elsebreak;}if(buffer->mPacketDescriptionCount>0){if(err=AudioQueueEnqueueBufferWithParameters(audio->queue,buffer,0,NULL,0,0,0,NULL,&bufferStartTime,NULL))WERROR_A("Error enqueuing audio buffer: %d", err);//decodelocklx_lock(audio->mdecdonelock);if(!audio->playRequested&&audio->mAudiolist.size==0){if(err=AudioQueueStop(audio->queue,false))WERROR_A("Error: Failed to stop audio queue: %d", err);elseWERROR_A("Stopped audio queue",NULL);}lx_unlock(audio->mdecdonelock);//decodeunlock}error_lab:EXITFUNC();}void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef buffer){ wAudtio_fillAudioBuffer((WAudio_Ios*)in,buffer);}
- ios audioqueue 流播放接口
- iOS AudioQueue
- 流播放音频
- android mms流播放器
- Android 通过流播放声音
- Android通过流播放声音
- Android 通过流播放声音
- goacademic视频流播放技术
- iOS音频AudioQueue
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS音频流播放、后台播放、远程控制、锁屏封面
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS音频流播放、后台播放、远程控制、锁屏封面等总结
- iOS集成ijkplayer支持rtsp流播放并使用播放样例
- KVM虚拟机三大存储模式
- java 集合 list
- KitCore的组成部分之一 ----- LdxprojCore
- 什么是领域驱动设计(Domain Driven Design)?(转自:http://www.aqee.net/2011/05/25/what-is-domain-driven-design/)
- 创建Xcode自定义模板
- ios audioqueue 流播放接口
- xcode快捷键大全
- 内存泄露之 glibc detected错误
- TCL(Tool Command Language)学习笔记1-变量&循环&分支
- ubuntu 编译 /usr/bin/ld: cannot find 问题解决
- Apache Openoffice
- [编程之美]字符串的相似度
- Pidgin插件Hello world的编译和使用
- TCL(Tool Command Language)学习笔记2-过程定义与使用