码迷,mamicode.com
首页 > 其他好文 > 详细

AudioToolbox--AudioQueue实现流播放接口

时间:2015-05-04 17:38:08      阅读:377      评论:0      收藏:0      [点我收藏+]

标签:

AudioMedia_ios.h

  1. //  
  2. //  AudioMedia_ios.h  
  3. //  mmsplayer  
  4. //  
  5. //  Created by Weiny on 12-4-4.  
  6. //  Copyright (c) 2012年 Weiny Zhou. All rights reserved.  
  7. //  
  8.   
  9. #ifndef mmsplayer_AudioMedia_ios_h  
  10. #define mmsplayer_AudioMedia_ios_h  
  11. #include "wdef.h"  
  12.   
  13. typedef void* wAudio;  
  14.   
  15. #ifdef __cplusplus  
  16. extern "C"  
  17. {  
  18. #endif  
  19.     wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize);//初始化声音接口  
  20.     int audio_play(wAudio audio);//播放  
  21.     int audio_pause(wAudio audio);  
  22.     int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dts);//写入音频数据  
  23.     int audio_stop(wAudio audio);//停止  
  24.     int audio_close(wAudio audio);//关闭  
  25. #ifdef __cplusplus  
  26. };  
  27. #endif      
  28.       
  29. #endif  


AudioMedia_ios.c

    1. //  
    2. //  AudioMedia_ios.cpp  
    3. //  mmsplayer  
    4. //  
    5. //  Created by Weiny on 12-4-4.  
    6. //  Copyright (c) 2012年 Weiny Zhou. All rights reserved.  
    7. //  
    8.   
    9. #include "AudioMedia_ios.h"  
    10. #include <AudioToolbox/AudioQueue.h>  
    11. #include "system/thread.h"  
    12. #include "base/wlist.h"  
    13. #include "system/lx_lock.h"  
    14. #define AUDIO_LIST_COUNT 3  
    15. #define AUDIO_BUFFER_SECONDS  1  
    16. typedef struct WAudio_Ios  
    17. {  
    18.   
    19.     int playRequested;  
    20.     int framesize;  
    21.     Wlock mlock,mdecdonelock,mqueuelock;  
    22.     wlist_t mAudiolist;//声音队列  
    23.     wlist_func mlistfunc;  
    24.   
    25.     AudioQueueRef queue;//player list  
    26.     AudioQueueBufferRef mBuffers[AUDIO_LIST_COUNT];  
    27.     AudioStreamBasicDescription mDataFormat;  
    28.     AudioQueueBufferRef emptyAudioBuffer;//空音频队列  
    29.       
    30. }WAudio_Ios;  
    31. typedef struct    
    32. {  
    33.     void* data;  
    34.     size_t size;  
    35.     int64_t dst;  
    36. }WAudio_item;  
    37.   
    38. void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef outQB);  
    39. void wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer);  
    40. static inline void waudio_free_back(void* lpvoid,wlist_item_ptr data)  
    41. {  
    42.     WAudio_item* item;  
    43.     INTOFUNC();  
    44.     if(!data){PRINTF_ERROR_VALUE(ERROR_INITPARAM);goto error_lab;}  
    45.     item=(WAudio_item*)data;  
    46.     SAFE_FREE(item->data);  
    47.     SAFE_FREE(item);  
    48. error_lab:  
    49.     EXITFUNC();  
    50. }  
    51. wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize)  
    52. {  
    53.     WAudio_Ios* ptr=NULL;  
    54.     uint32_t err=0;  
    55.     int i=0;  
    56.     INTOFUNC();  
    57.     ptr=WOS_MALLOC_(WAudio_Ios, 1);  
    58.     if(!ptr){  
    59.         PRINTF_ERROR_VALUE(ERROR_NEWMEM);  
    60.         goto error_lab;  
    61.     }  
    62.     memset(ptr,0,sizeof(WAudio_Ios));  
    63.     ptr->mDataFormat.mSampleRate=sample;//设置采样率  
    64.     ptr->mDataFormat.mChannelsPerFrame=nchannles;  
    65.     ptr->mDataFormat.mBitsPerChannel=bits;  
    66.     ptr->mDataFormat.mFormatID=kAudioFormatLinearPCM;//设置数据格式  
    67.     ptr->mDataFormat.mFormatFlags=kLinearPCMFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;  
    68.      
    69.     ptr->mDataFormat.mFramesPerPacket=1;  
    70.     ptr->mDataFormat.mBytesPerFrame=  
    71.         ptr->mDataFormat.mBitsPerChannel/  
    72.         ptr->mDataFormat.mChannelsPerFrame;  
    73.      ptr->mDataFormat.mBytesPerPacket=  
    74.          ptr->mDataFormat.mBytesPerFrame*ptr->mDataFormat.  
    75.          mFramesPerPacket;  
    76.       
    77.     err=AudioQueueNewOutput(&ptr->mDataFormat,wAudio_CallBack, ptr, NULL,   
    78.                             NULL/*kCFRunLoopCommonModes*/, 0  
    79.                             , &ptr->queue);  
    80.     if(err){  
    81.         WERROR_A("init audio output error,sample=%d,channles=%d,bits=%d.\n",sample,nchannles,bits);  
    82.         goto error_lab;  
    83.     }  
    84.     for (i=0;i<AUDIO_LIST_COUNT;++i)  
    85.     {  
    86.         err=AudioQueueAllocateBufferWithPacketDescriptions(ptr->queue,  
    87.             bits*AUDIO_BUFFER_SECONDS/8,  
    88.             sample*AUDIO_BUFFER_SECONDS/nFrameSize+1,ptr->mBuffers+i);  
    89.         if(err){  
    90.             WERROR_A("can‘t allocate audio queue buffer: %d",err);  
    91.               
    92.             goto error_lab;  
    93.         }  
    94.     }  
    95.     ptr->mlock=lx_lock_init();  
    96.     ptr->mdecdonelock=lx_lock_init();  
    97.     ptr->mqueuelock=lx_lock_init();  
    98.     ptr->mlistfunc=wlist_getfunc();  
    99.     ptr->mAudiolist.free=waudio_free_back;  
    100.     ptr->framesize=nFrameSize;  
    101. #if 1  
    102.     err=AudioQueueStart(ptr->queue,NULL);  
    103.     if(err){  
    104.         WERROR_A("Error: Audio queue failed to start: %d", err);  
    105.         goto error_lab;  
    106.     }  
    107.     ptr->playRequested=1;  
    108.     WDEBUG_OUT("Started Audio queue.",NULL);  
    109. #endif  
    110. #if 0  
    111.     agc.FrameCount = FRAME_COUNT;    
    112.     bufferSize = agc.FrameCount * agc.mDataFormat.mBytesPerFrame;    
    113.     for (i=0; i<AUDIO_BUFFERS; i++)    
    114.     {    
    115.         err = AudioQueueAllocateBuffer(agc.queue,bufferSize,&agc.mBuffers[i]);    
    116.         if(err) return err;    
    117.         AQBufferCallback(&agc,agc.queue,agc.mBuffers[i]);    
    118.     }    
    119.     err = AudioQueueStart(agc.queue,NULL);    
    120.     if(err) return err;    
    121.     while (agc.playPtr<agc.sampleLen)    
    122.     {    
    123.         select(NULL,NULL,NULL,NULL,1.0);    
    124.     }    
    125. #endif  
    126. error_lab:  
    127.     if(err){  
    128.         audio_close(ptr);  
    129.         SAFE_FREE(ptr);  
    130.     }  
    131.     EXITFUNC();  
    132.     return (wAudio)ptr;  
    133. }  
    134. int audio_play(wAudio audio)  
    135. {  
    136.     int nResult=0;  
    137.     WAudio_Ios* ptr=NULL;  
    138.     INTOFUNC();  
    139.     if(!audio){  
    140.         WERROR_A("input audio is null",NULL);  
    141.         nResult=ERROR_INITPARAM;  
    142.         goto error_lab;  
    143.     }  
    144.     ptr=(WAudio_Ios*)audio;  
    145.     if(ptr->playRequested==0||ptr->playRequested==2)  
    146.     {WERROR_A("state is %d",ptr->playRequested);goto error_lab;}  
    147.     ptr->playRequested=1;  
    148.     AudioQueueStart(ptr->queue,NULL);  
    149. error_lab:  
    150.     EXITFUNC();  
    151.     return nResult;  
    152. }  
    153. int audio_pause(wAudio audio)  
    154. {  
    155.     int nResult=0;  
    156.     WAudio_Ios* ptr=NULL;  
    157.     INTOFUNC();  
    158.     if(!audio){  
    159.         WERROR_A("input audio is null",NULL);  
    160.         nResult=ERROR_INITPARAM;  
    161.         goto error_lab;  
    162.     }  
    163.     ptr=(WAudio_Ios*)audio;  
    164.     if(1!=ptr->playRequested)  
    165.     {WERROR_A("state is %d",ptr->playRequested);goto error_lab;}  
    166.     ptr->playRequested=2;  
    167.     AudioQueuePause(ptr->queue);  
    168. error_lab:  
    169.     EXITFUNC();  
    170.     return nResult;  
    171. }  
    172. int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dst)  
    173. {  
    174.     int nResult=0;  
    175.     WAudio_Ios* ptr=NULL;  
    176.     WAudio_item* item=NULL;  
    177.     INTOFUNC();  
    178.     if(!audio){  
    179.         WERROR_A("input audio is null",NULL);  
    180.         nResult=ERROR_INITPARAM;  
    181.         goto error_lab;  
    182.     }  
    183.     ptr=(WAudio_Ios*)audio;  
    184.     item=WOS_MALLOC_(WAudio_item,1);  
    185.     if(!item){  
    186.         nResult=ERROR_NEWMEM;PRINTF_ERROR_VALUE(nResult);goto error_lab;  
    187.     }  
    188.     item->data=pcm;  
    189.     item->size=count;  
    190.     item->dst=dst;  
    191.     lx_lock(ptr->mqueuelock);  
    192.     //先加入队列  
    193.     ptr->mlistfunc.push_back(&ptr->mAudiolist,item);  
    194.     //  
    195.     if(ptr->emptyAudioBuffer)  
    196.         wAudtio_fillAudioBuffer(ptr,ptr->emptyAudioBuffer);//填充空buffer  
    197.     lx_unlock(ptr->mqueuelock);  
    198. error_lab:  
    199.     EXITFUNC();  
    200.     return nResult;  
    201. }  
    202. int audio_stop(wAudio audio)  
    203. {  
    204.     int nResult=0;  
    205.     WAudio_Ios* ptr=NULL;  
    206.     INTOFUNC();  
    207.     if(!audio){  
    208.         WERROR_A("input audio is null",NULL);  
    209.         nResult=ERROR_INITPARAM;  
    210.         goto error_lab;  
    211.     }  
    212.     ptr=(WAudio_Ios*)audio;  
    213.     AudioQueueStop(ptr->queue,false);  
    214.     ptr->playRequested=0;  
    215. error_lab:  
    216.     EXITFUNC();  
    217.     return nResult;  
    218. }  
    219. int audio_close(wAudio audio)  
    220. {  
    221.     int nResult=0;  
    222.     WAudio_Ios* ptr=NULL;  
    223.     INTOFUNC();  
    224.     if(!audio){  
    225.         WERROR_A("input audio is null.",NULL);  
    226.         nResult=ERROR_INITPARAM;  
    227.         goto error_lab;  
    228.     }  
    229.     ptr=(WAudio_Ios*)audio;  
    230.     ptr->mlistfunc.clear(&ptr->mAudiolist);//清空播放队列  
    231.     lx_lock_free(ptr->mqueuelock);  
    232.     lx_lock_free(ptr->mdecdonelock);  
    233.     lx_lock_free(ptr->mlock);  
    234.     AudioQueueDispose(ptr->queue,false);  
    235.     SAFE_FREE(ptr);  
    236. error_lab:  
    237.     EXITFUNC();  
    238.     return nResult;  
    239. }  
    240. #if 0  
    241. void AQBufferCallback( void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)    
    242. {    
    243.     AQCallbackStruct *agc;    
    244.     short *coreAudiobuffer;    
    245.     short sample;    
    246.     int i;    
    247.     agc=(AQCallbackStruct *) in;    
    248.     coreAudiobuffer =(short*) outQB->mAudioData;    
    249.     printf("Sync:%i / %i \n",agc->playPtr,agc->sampleLen);    
    250.     if (agc->FrameCount >0)     
    251.     {    
    252.         outQB->mAudioDataByteSize = 4*agc->FrameCount;    
    253.         for (i=0; i<agc->FrameCount*2; i++)     
    254.         {    
    255.             if(agc->playPtr > agc->sampleLen || agc->playPtr<0)    
    256.             {    
    257.                 sample =0;    
    258.             }    
    259.             else    
    260.             {    
    261.                 sample = (agc->pcmBuffer[agc->playPtr]);    
    262.             }    
    263.             coreAudiobuffer[i] = sample;    
    264.             coreAudiobuffer[i+1] = sample;    
    265.             agc->playPtr++;    
    266.         }    
    267.         AudioQueueEnqueueBuffer(inQ,outQB,0,NULL);    
    268.     }   
    269. }  
    270. #endif  
    271. void wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer)  
    272. {  
    273.     AudioTimeStamp bufferStartTime;  
    274.     uint32_t err;  
    275.     INTOFUNC();  
    276.     buffer->mAudioDataByteSize=0;  
    277.     buffer->mPacketDescriptionCount=0;  
    278.     if(audio->mAudiolist.size<=0){  
    279.         WERROR_A("Warning: No audio packets in queue.",NULL);  
    280.         audio->emptyAudioBuffer=buffer;  
    281.         goto error_lab;  
    282.     }  
    283.     audio->emptyAudioBuffer=NULL;  
    284.     while(audio->mAudiolist.size&&buffer->mPacketDescriptionCount <  
    285.         buffer->mPacketDescriptionCapacity)  
    286.     {  
    287.         wlist_item* item=audio->mlistfunc.pop_front(&audio->mAudiolist);  
    288.         WAudio_item* data=(WAudio_item*)item->data;  
    289.         if(buffer->mAudioDataBytesCapacity -  
    290.             buffer->mAudioDataByteSize >=data->size)  
    291.         {  
    292.             if(buffer->mAudioDataBytesCapacity==0)  
    293.             {  
    294.                 bufferStartTime.mSampleTime=data->dst*audio->framesize;  
    295.                 bufferStartTime.mFlags=kAudioTimeStampSampleTimeValid;  
    296.             }  
    297.              memcpy((uint8_t *)buffer->mAudioData + buffer->mAudioDataByteSize, data->data, data->size);  
    298.              buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mStartOffset = buffer->mAudioDataByteSize;  
    299.              buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mDataByteSize = data->size;  
    300.              buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mVariableFramesInPacket = audio->framesize;  
    301.   
    302.              buffer->mAudioDataByteSize += data->size;  
    303.              ++buffer->mPacketDescriptionCount;  
    304.              lx_lock(audio->mqueuelock);  
    305.              audio->mlistfunc.remove(&audio->mAudiolist,0);  
    306.              lx_unlock(audio->mqueuelock);  
    307.         }  
    308.         else  
    309.             break;  
    310.     }  
    311.     if(buffer->mPacketDescriptionCount>0)  
    312.     {  
    313.         if(err=AudioQueueEnqueueBufferWithParameters(audio->queue,  
    314.             buffer,0,NULL,0,0,0,NULL,&bufferStartTime,NULL))  
    315.             WERROR_A("Error enqueuing audio buffer: %d", err);  
    316.         //decodelock  
    317.         lx_lock(audio->mdecdonelock);  
    318.         if(!audio->playRequested&&audio->mAudiolist.size==0){  
    319.             if(err=AudioQueueStop(audio->queue,false))  
    320.                 WERROR_A("Error: Failed to stop audio queue: %d", err);  
    321.             else  
    322.                 WERROR_A("Stopped audio queue",NULL);  
    323.         }  
    324.         lx_unlock(audio->mdecdonelock);  
    325.         //decodeunlock  
    326.     }  
    327. error_lab:  
    328.     EXITFUNC();  
    329. }  
    330. void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef buffer)  
    331. {  
    332.     wAudtio_fillAudioBuffer((WAudio_Ios*)in,buffer);  

来源:http://blog.csdn.net/tigerleap/article/details/7628105

AudioToolbox--AudioQueue实现流播放接口

标签:

原文地址:http://www.cnblogs.com/sunminmin/p/4476607.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!