• AudioToolbox--AudioQueue实现流播放接口


    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. ",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  ",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

  • 相关阅读:
    2020.04.11补提
    UCF Local Programming Contest 2017(2020-04-06)
    AtCoder Beginner Contest 161
    UCF Local Programming Contest 2016(2020-03-28)
    Benelux Algorithm Programming Contest 2019(2020.03.21)
    Preliminaries for Benelux Algorithm Programming Contest 2019(2020.03.14)
    AtCoder Beginner Contest 158
    A-Leftbest
    强迫症
    不大想更了……
  • 原文地址:https://www.cnblogs.com/sunminmin/p/4476607.html
Copyright © 2020-2023  润新知