⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maccoreaudio.cxx

📁 安装 H323需要的pwlib库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
   if (err) {     return FALSE;   }   PTRACE(2, __func__ <<  " AudioDevice buffer size set to "             << targetSizeBytes);   UInt32 targetSizeFrames = targetSizeBytes / hwASBD.mBytesPerFrame;   if (direction == Player) {      err = AudioDeviceSetProperty( mDeviceID,         0, //&ts, timestruct          0, // output channel          true, // isInput          // kAudioDevicePropertyBufferSize,          kAudioDevicePropertyBufferFrameSize,         sizeof(UInt32),         &targetSizeFrames);   } else {      err = AudioDeviceSetProperty( mDeviceID,         0, //&ts, timestruct          1, // input channel         false, // isInput          kAudioDevicePropertyBufferFrameSize,         sizeof(UInt32),         &targetSizeFrames);   }   checkStatus(err);	*/   /**     * Allocate byte array passed as input to the converter     */   UInt32 bufferSizeFrames, bufferSizeBytes;   UInt32 propertySize = sizeof(UInt32);   err = AudioDeviceGetProperty( mDeviceID,            0,  // output channel,              true,  // isInput             kAudioDevicePropertyBufferFrameSize,            &propertySize,            &bufferSizeFrames);   checkStatus(err);   bufferSizeBytes = bufferSizeFrames * hwASBD.mBytesPerFrame;   //UInt32 bufferSizeBytes = targetSizeBytes;   if (direction == Player) {      UInt32 propertySize = sizeof(UInt32);      err = AudioConverterGetProperty(converter,            kAudioConverterPropertyCalculateInputBufferSize,            &propertySize,            &bufferSizeBytes);      checkStatus(err);      converter_buffer_size = bufferSizeBytes;   } else {      // on each turn the device spits out bufferSizeBytes bytes      // the input ringbuffer has at most MIN_INPUT_FILL frames in it       // all other frames were converter during the last callback      converter_buffer_size = bufferSizeBytes +                   2 * MIN_INPUT_FILL * hwASBD.mBytesPerFrame;   }   converter_buffer = (char*)malloc(converter_buffer_size);   if(converter_buffer == NULL)      PTRACE(1, "Failed to allocate converter_buffer");   else      PTRACE(2, "Allocated converter_buffer of size "             << converter_buffer_size );   /** In case of Recording we need a couple of buffers more */   if(direction == Recorder){      SetupAdditionalRecordBuffers();   }   /*    * AU Setup, allocates necessary buffers...     */   err = AudioUnitInitialize(mAudioUnit);   checkStatus(err);     state = setbuffer_;   return TRUE;}OSStatus PSoundChannelCoreAudio::SetupAdditionalRecordBuffers(){   OSStatus err = noErr;   UInt32 bufferSizeFrames, bufferSizeBytes;      /**     * build buffer list to take over the data from the microphone     */   UInt32 propertySize = sizeof(UInt32);   err = AudioDeviceGetProperty( mDeviceID,      0,  // channel, probably all        true,  // isInput       //false,  // isInput ()      kAudioDevicePropertyBufferFrameSize,      &propertySize,      &bufferSizeFrames);   checkStatus(err);   bufferSizeBytes = bufferSizeFrames * hwASBD.mBytesPerFrame;	bufferSizeBytes += bufferSizeBytes / 10; // +10%   //calculate size of ABL given the last field, assum non-interleaved    UInt32 propsize =       offsetof(AudioBufferList, mBuffers[hwASBD.mChannelsPerFrame]);   //malloc buffer lists   mInputBufferList = (AudioBufferList *)malloc(propsize);   mInputBufferList->mNumberBuffers = hwASBD.mChannelsPerFrame;   //pre-malloc buffers for AudioBufferLists   for(UInt32 i =0; i< mInputBufferList->mNumberBuffers ; i++) {      mInputBufferList->mBuffers[i].mNumberChannels = 1;      mInputBufferList->mBuffers[i].mDataByteSize = bufferSizeBytes;      mInputBufferList->mBuffers[i].mData = malloc(bufferSizeBytes);   }   mRecordInputBufferSize = bufferSizeBytes;   /** allocate ringbuffer to cache data before passing them to the converter */   // take only one buffer -> mono, use double buffering   mInputCircularBuffer = new CircularBuffer(bufferSizeBytes * 2);   /**     * Build buffer list that is passed to the Converter to be filled with     * the converted frames.    */   // given the number of input bytes how many bytes to expect at the output?   bufferSizeBytes += MIN_INPUT_FILL * hwASBD.mBytesPerFrame;   propertySize = sizeof(UInt32);   err = AudioConverterGetProperty(converter,         kAudioConverterPropertyCalculateOutputBufferSize,         &propertySize,         &bufferSizeBytes);   checkStatus(err);   //calculate number of buffers from channels   propsize = offsetof(AudioBufferList, mBuffers[pwlibASBD.mChannelsPerFrame]);   //malloc buffer lists   mOutputBufferList = (AudioBufferList *)malloc(propsize);   mOutputBufferList->mNumberBuffers = pwlibASBD.mChannelsPerFrame;   //pre-malloc buffers for AudioBufferLists   for(UInt32 i =0; i< mOutputBufferList->mNumberBuffers ; i++) {      mOutputBufferList->mBuffers[i].mNumberChannels = 1;      mOutputBufferList->mBuffers[i].mDataByteSize = bufferSizeBytes;      mOutputBufferList->mBuffers[i].mData = malloc(bufferSizeBytes);   }   mRecordOutputBufferSize = bufferSizeBytes;   return err;} BOOL PSoundChannelCoreAudio::GetBuffers(PINDEX & size,                  PINDEX & count){   size = bufferSizeBytes;   count = bufferCount;   return TRUE;}BOOL PSoundChannelCoreAudio::SetVolume(unsigned volume){   OSStatus err = noErr;   Boolean isWritable;   bool isInput = (direction == Player ? false : true);   if(mDeviceID == kAudioDeviceDummy){      PTRACE(1, "Dummy device");      return FALSE;   }   // changing volume can not go through the master channel (0)    err = AudioDeviceGetPropertyInfo(mDeviceID, 1, isInput,                kAudioDevicePropertyVolumeScalar,                NULL, &isWritable);   checkStatus(err);   if ((err == kAudioHardwareNoError) && isWritable) {      // volume is between 0 and 100 ?       float theValue = ((float)volume)/100.0;      err = AudioDeviceSetProperty(mDeviceID, NULL, 1, isInput,                   kAudioDevicePropertyVolumeScalar,                   sizeof(float), &theValue);   }   if (!err)      return TRUE;   else      return FALSE;}BOOL PSoundChannelCoreAudio::GetVolume(unsigned & volume){   OSStatus err = noErr;   UInt32 theSize;   Float32 theValue;   bool isInput = (direction == Player ? false : true);   if(mDeviceID == kAudioDeviceDummy){      PTRACE(1, "Dummy device");      return FALSE;   }   theSize = sizeof(theValue);   // changing volume can not go through the master channel (0)    err = AudioDeviceGetProperty(mDeviceID, 1, isInput,                 kAudioDevicePropertyVolumeScalar,                 &theSize, &theValue);   if (!err) {     // volume is between 0 and 100?      volume = (unsigned) (theValue * 100);     return TRUE;   } else       return FALSE;   }   BOOL PSoundChannelCoreAudio::Write(const void *buf,               PINDEX len){   PTRACE(1, "Write called with len " << len);   if(state < setbuffer_){      PTRACE(1, __func__ << " Please initialize device first");      return FALSE;   }   if (mDeviceID == kAudioDeviceDummy) {      lastWriteCount =  len;         // safe to assume non-interleaved or mono      UInt32 nr_samples = len / pwlibASBD.mBytesPerFrame;       usleep(UInt32(nr_samples/pwlibASBD.mSampleRate * 1000000)); // 10E-6 [s]      return TRUE;  /* Null device */   }   // Write to circular buffer with locking    lastWriteCount = mCircularBuffer->Fill((const char*)buf, len, true);   // Start it after putting the first data into the buffer   // this might cause troubles in case more data are written   // than space is available   if(state == setbuffer_){      PTRACE(1, "Starting " << direction << " device.");      OSStatus err = AudioOutputUnitStart(mAudioUnit);      checkStatus(err);      state = running_;   }   return (TRUE);}BOOL PSoundChannelCoreAudio::PlaySound(const PSound & sound,                  BOOL wait){   if (!Write((const BYTE *)sound, sound.GetSize()))     return FALSE;     if (wait)     return WaitForPlayCompletion();   return TRUE;}BOOL PSoundChannelCoreAudio::PlayFile(const PFilePath & file,                 BOOL wait){   PTRACE(1, __func__ );  PAssert(0, PUnimplementedFunction);  return TRUE; }BOOL PSoundChannelCoreAudio::HasPlayCompleted(){   PTRACE(1, __func__ );  PAssert(0, PUnimplementedFunction);   return false;}BOOL PSoundChannelCoreAudio::WaitForPlayCompletion(){   PTRACE(1, __func__ );  PAssert(0, PUnimplementedFunction);   return false;}BOOL PSoundChannelCoreAudio::Read(void *buf,              PINDEX len){   PTRACE(6, "Read called with len " << len);   if(state < setbuffer_){      PTRACE(1, __func__ << " Please initialize device first");      return FALSE;   }   if (mDeviceID == kAudioDeviceDummy) {      lastReadCount =  len;       bzero(buf, len);        // we are working with non-interleaved or mono      UInt32 nr_samples = len / pwlibASBD.mBytesPerFrame;       usleep(UInt32(nr_samples/pwlibASBD.mSampleRate * 1000000)); // 10E-6 [s]      return TRUE;  /* Null device */   }   if(state == setbuffer_){      PTRACE(1, "Starting " << direction << " device.");      OSStatus err = AudioOutputUnitStart(mAudioUnit);      checkStatus(err);      state = running_;   }   lastReadCount = mCircularBuffer->Drain((char*)buf, len, true);   return (TRUE);}BOOL PSoundChannelCoreAudio::RecordSound(PSound & sound){   PTRACE(1, __func__ );  PAssert(0, PUnimplementedFunction);   return false;}BOOL PSoundChannelCoreAudio::RecordFile(const PFilePath & file){   PTRACE(1, __func__ );  PAssert(0, PUnimplementedFunction);   return false;}BOOL PSoundChannelCoreAudio::StartRecording(){   PTRACE(1, __func__ );   if(state != setbuffer_){      PTRACE(1, __func__ << " Initialize the device first");      return FALSE;   }   if(state == setbuffer_){      PTRACE(1, "Starting " << direction << " device.");      OSStatus err = AudioOutputUnitStart(mAudioUnit);      checkStatus(err);      state = running_;   }   return false;}BOOL PSoundChannelCoreAudio::isRecordBufferFull(){   PAssert(direction == Recorder, PInvalidParameter);   if(state != setbuffer_){      PTRACE(1, __func__ << " Initialize the device first");      return FALSE;   }      return (mCircularBuffer->size() > bufferSizeBytes);}BOOL PSoundChannelCoreAudio::AreAllRecordBuffersFull(){   PAssert(direction == Recorder, PInvalidParameter);   if(state != setbuffer_){      PTRACE(1, __func__ << " Initialize the device first");      return FALSE;   }   return (mCircularBuffer->Full());}BOOL PSoundChannelCoreAudio::WaitForRecordBufferFull(){   PTRACE(1, __func__ );  PAssert(0, PUnimplementedFunction);  if (os_handle < 0) {    return FALSE;  }  return PXSetIOBlock(PXReadBlock, readTimeout);}BOOL PSoundChannelCoreAudio::WaitForAllRecordBuffersFull(){   PTRACE(1, __func__ );   PAssert(0, PUnimplementedFunction);   return false;}// End of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -