coreaudiodevice.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // apple core audio device
  2. #include "freeaudio.h"
  3. #ifdef __APPLE__
  4. #include <CoreServices/CoreServices.h>
  5. #include <AudioUnit/AudioUnit.h>
  6. #include <CoreAudio/CoreAudio.h>
  7. #include <AudioToolbox/AudioToolbox.h>
  8. extern "C" audiodevice *OpenCoreAudioDevice();
  9. OSStatus FeedSound(void *ref,AudioUnitRenderActionFlags *flags,const AudioTimeStamp *time,UInt32 bus,UInt32 frames,AudioBufferList *data);
  10. struct coreaudio:audiodevice{
  11. AudioUnit out;
  12. AudioConverterRef conv;
  13. AURenderCallbackStruct callback;
  14. short *buffer;
  15. int tcount;
  16. int reset(){
  17. int res;
  18. mix=new mixer(8192);
  19. mix->freq=44100;
  20. mix->channels=2;
  21. out=0;
  22. res=initoutput();
  23. if (res) return res;
  24. callback.inputProc=FeedSound;
  25. callback.inputProcRefCon=this;
  26. buffer=new short[8192];
  27. res=AudioUnitSetProperty(out,kAudioUnitProperty_SetRenderCallback,kAudioUnitScope_Input,0,&callback,sizeof(callback));
  28. if (res) return res;
  29. res=AudioOutputUnitStart(out);
  30. if (res) return res;
  31. return 0;
  32. }
  33. int close(){
  34. int res;
  35. if (out){
  36. res=AudioOutputUnitStop(out);
  37. if (res) return res;
  38. out=0;
  39. }
  40. return 0;
  41. }
  42. int initoutput(){
  43. ComponentDescription desc;
  44. Component comp;
  45. OSStatus err;
  46. UInt32 size;
  47. Boolean canwrite;
  48. AudioStreamBasicDescription inputdesc,outputdesc;
  49. desc.componentType=kAudioUnitType_Output;
  50. desc.componentSubType=kAudioUnitSubType_DefaultOutput;
  51. desc.componentManufacturer=kAudioUnitManufacturer_Apple;
  52. desc.componentFlags=0;
  53. desc.componentFlagsMask=0;
  54. comp=FindNextComponent(NULL,&desc);if (comp==NULL) return -1;
  55. err=OpenAComponent(comp,&out);if (err) return err;
  56. err=AudioUnitInitialize(out);if (err) return err;
  57. err=AudioUnitGetPropertyInfo(out,kAudioUnitProperty_StreamFormat,kAudioUnitScope_Output,0,&size,&canwrite);
  58. if (err) return err;
  59. err=AudioUnitGetProperty(out,kAudioUnitProperty_StreamFormat,kAudioUnitScope_Input,0,&outputdesc,&size);
  60. if (err) return err;
  61. // dumpdesc(&outputdesc);
  62. inputdesc.mSampleRate=44100.0;
  63. inputdesc.mFormatID='lpcm';
  64. #if __BIG_ENDIAN__
  65. inputdesc.mFormatFlags=0x0e;
  66. #else
  67. inputdesc.mFormatFlags=0x0c;
  68. #endif
  69. inputdesc.mBytesPerPacket=4;
  70. inputdesc.mFramesPerPacket=1;
  71. inputdesc.mBytesPerFrame=4;
  72. inputdesc.mChannelsPerFrame=2;
  73. inputdesc.mBitsPerChannel=16;
  74. inputdesc.mReserved=0;
  75. // dumpdesc(&inputdesc);
  76. err=AudioConverterNew(&inputdesc,&outputdesc,&conv);
  77. if (err) {
  78. // printf("AudioConvertNew failed %.*s\n",4,(char*)&err);
  79. return err;
  80. }
  81. return err;
  82. }
  83. int read(AudioConverterRef conv,UInt32 *count,AudioBufferList *blist,AudioStreamPacketDescription **outdesc){
  84. if (*count>4096) *count=4096;
  85. // printf("ac read count=%d\n",*count);fflush(stdout);
  86. mix->mix16(buffer,*count*2);
  87. blist->mBuffers[0].mData=buffer;
  88. blist->mBuffers[0].mDataByteSize=*count*4;
  89. return 0;
  90. }
  91. };
  92. OSStatus Feed(AudioConverterRef conv,UInt32 *count,AudioBufferList *blist,AudioStreamPacketDescription **outdesc,void *ref){
  93. coreaudio *audio;
  94. audio=(coreaudio*)ref;
  95. return audio->read(conv,count,blist,outdesc);
  96. }
  97. OSStatus FeedSound(void *ref,AudioUnitRenderActionFlags *flags,const AudioTimeStamp *time,UInt32 bus,UInt32 count,AudioBufferList *blist){
  98. coreaudio *audio;
  99. audio=(coreaudio*)ref;
  100. return AudioConverterFillComplexBuffer(audio->conv,Feed,ref,&count,blist,0);
  101. }
  102. audiodevice *OpenCoreAudioDevice(){
  103. return new coreaudio();
  104. }
  105. #endif