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

📄 rtaudio.cpp

📁 Mobile STK for Symbian OS V0.1
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    error(RtError::MEMORY_ERROR);  }  // Get the array of AudioDeviceIDs.  err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &dataSize, (void *) deviceList);  if (err != noErr) {    free(deviceList);    sprintf(message_, "RtApiCore: OS-X error getting device properties!");    error(RtError::SYSTEM_ERROR);  }  // Create list of device structures and write device identifiers.  RtApiDevice device;  AudioDeviceID *id;  for (int i=0; i<nDevices_; i++) {    devices_.push_back(device);    id = (AudioDeviceID *) malloc( sizeof(AudioDeviceID) );    *id = deviceList[i];    devices_[i].apiDeviceId = (void *) id;  }  free(deviceList);}int RtApiCore :: getDefaultInputDevice(void){  AudioDeviceID id, *deviceId;  UInt32 dataSize = sizeof( AudioDeviceID );  OSStatus result = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultInputDevice,                                              &dataSize, &id );  if (result != noErr) {    sprintf( message_, "RtApiCore: OS-X error getting default input device." );    error(RtError::WARNING);    return 0;  }  for ( int i=0; i<nDevices_; i++ ) {    deviceId = (AudioDeviceID *) devices_[i].apiDeviceId;    if ( id == *deviceId ) return i;  }  return 0;}int RtApiCore :: getDefaultOutputDevice(void){  AudioDeviceID id, *deviceId;  UInt32 dataSize = sizeof( AudioDeviceID );  OSStatus result = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice,                                              &dataSize, &id );  if (result != noErr) {    sprintf( message_, "RtApiCore: OS-X error getting default output device." );    error(RtError::WARNING);    return 0;  }  for ( int i=0; i<nDevices_; i++ ) {    deviceId = (AudioDeviceID *) devices_[i].apiDeviceId;    if ( id == *deviceId ) return i;  }  return 0;}static bool deviceSupportsFormat( AudioDeviceID id, bool isInput,                                  AudioStreamBasicDescription	*desc, bool isDuplex ){  OSStatus result = noErr;  UInt32 dataSize = sizeof( AudioStreamBasicDescription );  result = AudioDeviceGetProperty( id, 0, isInput,                                   kAudioDevicePropertyStreamFormatSupported,                                   &dataSize, desc );  if (result == kAudioHardwareNoError) {    if ( isDuplex ) {      result = AudioDeviceGetProperty( id, 0, true,                                       kAudioDevicePropertyStreamFormatSupported,                                       &dataSize, desc );      if (result != kAudioHardwareNoError)        return false;    }    return true;  }  return false;}void RtApiCore :: probeDeviceInfo( RtApiDevice *info ){  OSStatus err = noErr;  // Get the device manufacturer and name.  char	name[256];  char	fullname[512];  UInt32 dataSize = 256;  AudioDeviceID *id = (AudioDeviceID *) info->apiDeviceId;  err = AudioDeviceGetProperty( *id, 0, false,                                kAudioDevicePropertyDeviceManufacturer,                                &dataSize, name );  if (err != noErr) {    sprintf( message_, "RtApiCore: OS-X error getting device manufacturer." );    error(RtError::DEBUG_WARNING);    return;  }  strncpy(fullname, name, 256);  strcat(fullname, ": " );  dataSize = 256;  err = AudioDeviceGetProperty( *id, 0, false,                                kAudioDevicePropertyDeviceName,                                &dataSize, name );  if (err != noErr) {    sprintf( message_, "RtApiCore: OS-X error getting device name." );    error(RtError::DEBUG_WARNING);    return;  }  strncat(fullname, name, 254);  info->name.erase();  info->name.append( (const char *)fullname, strlen(fullname)+1);  // Get output channel information.  unsigned int i, minChannels = 0, maxChannels = 0, nStreams = 0;  AudioBufferList	*bufferList = nil;  err = AudioDeviceGetPropertyInfo( *id, 0, false,                                    kAudioDevicePropertyStreamConfiguration,                                    &dataSize, NULL );  if (err == noErr && dataSize > 0) {    bufferList = (AudioBufferList *) malloc( dataSize );    if (bufferList == NULL) {      sprintf(message_, "RtApiCore: memory allocation error!");      error(RtError::DEBUG_WARNING);      return;    }    err = AudioDeviceGetProperty( *id, 0, false,                                  kAudioDevicePropertyStreamConfiguration,                                  &dataSize, bufferList );    if (err == noErr) {      maxChannels = 0;      minChannels = 1000;      nStreams = bufferList->mNumberBuffers;      for ( i=0; i<nStreams; i++ ) {        maxChannels += bufferList->mBuffers[i].mNumberChannels;        if ( bufferList->mBuffers[i].mNumberChannels < minChannels )          minChannels = bufferList->mBuffers[i].mNumberChannels;      }    }  }  free (bufferList);  if (err != noErr || dataSize <= 0) {    sprintf( message_, "RtApiCore: OS-X error getting output channels for device (%s).",             info->name.c_str() );    error(RtError::DEBUG_WARNING);    return;  }  if ( nStreams ) {    if ( maxChannels > 0 )      info->maxOutputChannels = maxChannels;    if ( minChannels > 0 )      info->minOutputChannels = minChannels;  }  // Get input channel information.  bufferList = nil;  err = AudioDeviceGetPropertyInfo( *id, 0, true,                                    kAudioDevicePropertyStreamConfiguration,                                    &dataSize, NULL );  if (err == noErr && dataSize > 0) {    bufferList = (AudioBufferList *) malloc( dataSize );    if (bufferList == NULL) {      sprintf(message_, "RtApiCore: memory allocation error!");      error(RtError::DEBUG_WARNING);      return;    }    err = AudioDeviceGetProperty( *id, 0, true,                                  kAudioDevicePropertyStreamConfiguration,                                  &dataSize, bufferList );    if (err == noErr) {      maxChannels = 0;      minChannels = 1000;      nStreams = bufferList->mNumberBuffers;      for ( i=0; i<nStreams; i++ ) {        if ( bufferList->mBuffers[i].mNumberChannels < minChannels )          minChannels = bufferList->mBuffers[i].mNumberChannels;        maxChannels += bufferList->mBuffers[i].mNumberChannels;      }    }  }  free (bufferList);  if (err != noErr || dataSize <= 0) {    sprintf( message_, "RtApiCore: OS-X error getting input channels for device (%s).",             info->name.c_str() );    error(RtError::DEBUG_WARNING);    return;  }  if ( nStreams ) {    if ( maxChannels > 0 )      info->maxInputChannels = maxChannels;    if ( minChannels > 0 )      info->minInputChannels = minChannels;  }  // If device opens for both playback and capture, we determine the channels.  if (info->maxOutputChannels > 0 && info->maxInputChannels > 0) {    info->hasDuplexSupport = true;    info->maxDuplexChannels = (info->maxOutputChannels > info->maxInputChannels) ?      info->maxInputChannels : info->maxOutputChannels;    info->minDuplexChannels = (info->minOutputChannels > info->minInputChannels) ?      info->minInputChannels : info->minOutputChannels;  }  // Probe the device sample rate and data format parameters.  The  // core audio query mechanism is performed on a "stream"  // description, which can have a variable number of channels and  // apply to input or output only.  // Create a stream description structure.  AudioStreamBasicDescription	description;  dataSize = sizeof( AudioStreamBasicDescription );  memset(&description, 0, sizeof(AudioStreamBasicDescription));  bool isInput = false;  if ( info->maxOutputChannels == 0 ) isInput = true;  bool isDuplex = false;  if ( info->maxDuplexChannels > 0 ) isDuplex = true;  // Determine the supported sample rates.  info->sampleRates.clear();  for (unsigned int k=0; k<MAX_SAMPLE_RATES; k++) {    description.mSampleRate = (double) SAMPLE_RATES[k];    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->sampleRates.push_back( SAMPLE_RATES[k] );  }  if (info->sampleRates.size() == 0) {    sprintf( message_, "RtApiCore: No supported sample rates found for OS-X device (%s).",             info->name.c_str() );    error(RtError::DEBUG_WARNING);    return;  }  // Determine the supported data formats.  info->nativeFormats = 0;  description.mFormatID = kAudioFormatLinearPCM;  description.mBitsPerChannel = 8;  description.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsBigEndian;  if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )    info->nativeFormats |= RTAUDIO_SINT8;  else {    description.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian;    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->nativeFormats |= RTAUDIO_SINT8;  }  description.mBitsPerChannel = 16;  description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;  if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )    info->nativeFormats |= RTAUDIO_SINT16;  else {    description.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian;    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->nativeFormats |= RTAUDIO_SINT16;  }  description.mBitsPerChannel = 32;  description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;  if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )    info->nativeFormats |= RTAUDIO_SINT32;  else {    description.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian;    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->nativeFormats |= RTAUDIO_SINT32;  }  description.mBitsPerChannel = 24;  description.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsAlignedHigh | kLinearPCMFormatFlagIsBigEndian;  if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )    info->nativeFormats |= RTAUDIO_SINT24;  else {    description.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian;    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->nativeFormats |= RTAUDIO_SINT24;  }  description.mBitsPerChannel = 32;  description.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsBigEndian;  if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )    info->nativeFormats |= RTAUDIO_FLOAT32;  else {    description.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian;    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->nativeFormats |= RTAUDIO_FLOAT32;  }  description.mBitsPerChannel = 64;  description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;  if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )    info->nativeFormats |= RTAUDIO_FLOAT64;  else {    description.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian;    if ( deviceSupportsFormat( *id, isInput, &description, isDuplex ) )      info->nativeFormats |= RTAUDIO_FLOAT64;  }  // Check that we have at least one supported format.  if (info->nativeFormats == 0) {    sprintf(message_, "RtApiCore: OS-X device (%s) data format not supported by RtAudio.",            info->name.c_str());    error(RtError::DEBUG_WARNING);    return;  }  info->probed = true;}OSStatus callbackHandler( AudioDeviceID inDevice,                          const AudioTimeStamp* inNow,                          const AudioBufferList* inInputData,                          const AudioTimeStamp* inInputTime,                          AudioBufferList* outOutputData,                          const AudioTimeStamp* inOutputTime,                           void* infoPointer ){  CallbackInfo *info = (CallbackInfo *) infoPointer;  RtApiCore *object = (RtApiCore *) info->object;  try {    object->callbackEvent( inDevice, (void *)inInputData, (void *)outOutputData );  }  catch (RtError &exception) {    fprintf(stderr, "\nRtApiCore: callback handler error (%s)!\n\n", exception.getMessageString());    return kAudioHardwareUnspecifiedError;  }  return kAudioHardwareNoError;}OSStatus deviceListener( AudioDeviceID inDevice,                         UInt32 channel,                         Boolean isInput,                         AudioDevicePropertyID propertyID,                         void* handlePointer ){  CoreHandle *handle = (CoreHandle *) handlePointer;  if ( propertyID == kAudioDeviceProcessorOverload ) {    if ( isInput )      fprintf(stderr, "\nRtApiCore: OS-X audio input overrun detected!\n");    else      fprintf(stderr, "\nRtApiCore: OS-X audio output underrun detected!\n");    handle->xrun = true;  }  return kAudioHardwareNoError;}bool RtApiCore :: probeDeviceOpen( int device, StreamMode mode, int channels,                                    int sampleRate, RtAudioFormat format,                                   int *bufferSize, int numberOfBuffers ){  // Setup for stream mode.  bool isInput = false;  AudioDeviceID id = *((AudioDeviceID *) devices_[device].apiDeviceId);  if ( mode == INPUT ) isInput = true;  // Search for a stream which contains the desired number of channels.  OSStatus err = noErr;  UInt32 dataSize;  unsigned int deviceChannels, nStreams = 0;  UInt32 iChannel = 0, iStream = 0;  AudioBufferList	*bufferList = nil;  err = AudioDeviceGetPropertyInfo( id, 0, isInput,                                    kAudioDevicePropertyStreamConfiguration,                                    &dataSize, NULL );  if (err == noErr && dataSize > 0) {    bufferList = (AudioBufferList *) malloc( dataSize );    if (bufferList == NULL) {      sprintf(message_, "RtApiCore: memory allocation error in probeDeviceOpen()!");      error(RtError::DEBUG_WARNING);      return FAILURE;    }    err = AudioDeviceGetProperty( id, 0, isInput,                                  kAudioDevicePropertyStreamConfiguration,                                  &dataSize, bufferList );    if (err == noErr) {      stream_.deInterleave[mode] = false;      nStreams = bufferList->mNumberBuffers;      for ( iStream=0; iStream<nStreams; iStream++ ) {        if ( bufferList->mBuffers[iStream].mNumberChannels >= (unsigned int) channels ) break;        iChannel += bufferList->mBuffers[iStream].mNumberChannels;      }      // If we didn't find a single stream above, see if we can meet      // the channel specification in mono mode (i.e. using separate      // non-interleaved buffers).  This can only work if there are N      // consecutive one-channel streams, where N is the number of      // desired channels.      iChannel = 0;      if ( iStream >= nStreams && nStreams >= (unsigned int) channels ) {        int counter = 0;        for ( iStream=0; iStream<nStreams; iS

⌨️ 快捷键说明

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