bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc)
{
    if (!pDesc || !m_StreamId)
        return false;

    std::string formatString;

    if (!m_OriginalPhysicalFormat.mFormatID)
    {
        // Store the original format (as we found it) so that it can be restored later
        if (!GetPhysicalFormat(&m_OriginalPhysicalFormat))
        {
            CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
                      "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
            return false;
        }
    }
    m_physical_format_event.Reset();
    OSStatus ret = AudioStreamSetProperty(m_StreamId,
                                          NULL, 0, kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), pDesc);
    if (ret)
    {
        CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
                  "Unable to set physical format for stream 0x%04x. Error = %s",
                  (uint)m_StreamId, GetError(ret).c_str());
        return false;
    }

    // The AudioStreamSetProperty is not only asynchronious,
    // it is also not Atomic, in its behaviour.
    // Therefore we check 5 times before we really give up.
    // FIXME: failing isn't actually implemented yet.
    for(int i = 0; i < 10; ++i)
    {
        AudioStreamBasicDescription checkPhysicalFormat;
        if (!GetPhysicalFormat(&checkPhysicalFormat))
        {
            CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
                      "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
            return false;
        }
        if (checkPhysicalFormat.mSampleRate == pDesc->mSampleRate &&
                checkPhysicalFormat.mFormatID   == pDesc->mFormatID   &&
                checkPhysicalFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
        {
            // The right format is now active.
            CLog::Log(LOGDEBUG, "CCoreAudioStream::SetPhysicalFormat: "
                      "Physical format for stream 0x%04x. now active (%s)",
                      (uint)m_StreamId, StreamDescriptionToString(checkPhysicalFormat, formatString));
            break;
        }
        m_physical_format_event.WaitMSec(100);
    }

    return true;
}
Esempio n. 2
0
/*****************************************************************************
 * AudioStreamChangeFormat: Change i_stream_id to change_format
 *****************************************************************************/
int CoreAudioAUHAL::AudioStreamChangeFormat(CoreAudioDeviceParameters *deviceParameters, AudioStreamID i_stream_id, AudioStreamBasicDescription change_format)
{
    OSStatus            err = noErr;
    UInt32              i_param_size = 0;
    int i;

    CLog::Log(LOGINFO, STREAM_FORMAT_MSG( "setting stream format: ", change_format ));
	
	CSingleLock lock(m_cs); // acquire lock

    /* change the format */
    err = AudioStreamSetProperty( i_stream_id, 0, 0,
								 kAudioStreamPropertyPhysicalFormat,
								 sizeof( AudioStreamBasicDescription ),
								 &change_format );
    if( err != noErr )
    {
        CLog::Log(LOGERROR, "could not set the stream format: [%4.4s]", (char *)&err );
        return false;
    }

    /* The AudioStreamSetProperty is not only asynchronious (requiring the locks)
     * it is also not atomic in its behaviour.
     * Therefore we check 5 times before we really give up.*/
    for( i = 0; i < 5; i++ )
    {
        AudioStreamBasicDescription actual_format;
		usleep(20);
        i_param_size = sizeof( AudioStreamBasicDescription );
        err = AudioStreamGetProperty( i_stream_id, 0,
									 kAudioStreamPropertyPhysicalFormat,
									 &i_param_size,
									 &actual_format );

        CLog::Log(LOGDEBUG, STREAM_FORMAT_MSG( "actual format in use: ", actual_format ) );
        if( actual_format.mSampleRate == change_format.mSampleRate &&
		   actual_format.mFormatID == change_format.mFormatID &&
		   actual_format.mFramesPerPacket == change_format.mFramesPerPacket )
        {
            /* The right format is now active */
            break;
        }
        /* We need to check again */
    }

    return true;
}
Esempio n. 3
0
bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc)
{
  if (!pDesc || !m_StreamId)
    return false;
  if (!m_OriginalPhysicalFormat.mFormatID)
  {
    if (!GetPhysicalFormat(m_StreamId, &m_OriginalPhysicalFormat)) // Store the original format (as we found it) so that it can be restored later
    {
      CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: Unable to retrieve current physical format for stream 0x%04x.", m_StreamId);
      return false;
    }
  }  
  OSStatus ret = AudioStreamSetProperty(m_StreamId, NULL, 0, kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), pDesc);
  if (ret)
  {
    CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: Unable to set physical format for stream 0x%04x. Error = 0x%08x (%4.4s)", m_StreamId, ret, CONVERT_OSSTATUS(ret));
    return false;
  }
  return true;   
}
Esempio n. 4
0
void CCoreAudioHardware::ResetStream(AudioStreamID stream)
{
  // Find the streams current physical format
  AudioStreamBasicDescription currentFormat;
  UInt32 paramSize = sizeof(currentFormat);
  AudioStreamGetProperty(stream, 0, kAudioStreamPropertyPhysicalFormat,
    &paramSize, &currentFormat);

  // If it's currently AC-3/SPDIF then reset it to some mixable format
  if (currentFormat.mFormatID == 'IAC3' ||
      currentFormat.mFormatID == kAudioFormat60958AC3)
  {
    AudioStreamBasicDescription *formats = CCoreAudioHardware::FormatsList(stream);
    bool streamReset = false;

    if (!formats)
      return;

    for (int i = 0; !streamReset && formats[i].mFormatID != 0; i++)
    {
      if (formats[i].mFormatID == kAudioFormatLinearPCM)
      {
        OSStatus ret = AudioStreamSetProperty(stream, NULL, 0, kAudioStreamPropertyPhysicalFormat, sizeof(formats[i]), &(formats[i]));
        if (ret != noErr)
        {
          CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetStream: "
            "Unable to retrieve the list of available devices. Error = %s", GetError(ret).c_str());
          continue;
        }
        else
        {
          streamReset = true;
          Sleep(10);
        }
      }
    }
    free(formats);
  }
}
Esempio n. 5
0
void PlexAudioDevice::reset()
{
  OSStatus err = noErr;
  UInt32   paramSize = 0;
  AudioStreamBasicDescription deviceFormat;

  // Set up the basic default format.
  deviceFormat.mSampleRate = 48000.0;
  deviceFormat.mFormatID = kAudioFormatLinearPCM;
  deviceFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
  deviceFormat.mBitsPerChannel = 16;
  deviceFormat.mChannelsPerFrame = 2;
  deviceFormat.mFramesPerPacket = 1;
  deviceFormat.mBytesPerFrame = 4;
  deviceFormat.mBytesPerPacket = 4;
  deviceFormat.mReserved = 0;
  
  // Retrieve all the output streams.
  SAFELY(AudioDeviceGetPropertyInfo(m_deviceID, 0, FALSE, kAudioDevicePropertyStreams, &paramSize, NULL));
  if (err == noErr)
  {
    int numStreams = paramSize / sizeof(AudioStreamID);
    AudioStreamID* pStreams = (AudioStreamID *)malloc(paramSize);

    SAFELY(AudioDeviceGetProperty(m_deviceID, 0, FALSE, kAudioDevicePropertyStreams, &paramSize, pStreams));
    if (err == noErr)
    {
      for (int i=0; i<numStreams; i++)
      {
        // Change the format.
        SAFELY(AudioStreamSetProperty(pStreams[i], 0, 0, kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), &deviceFormat));
      }
    }

    free(pStreams);
  }
}
void	CAAudioHardwareStream::SetPropertyData(UInt32 inChannel, AudioHardwarePropertyID inPropertyID, UInt32 inDataSize, const void* inData, const AudioTimeStamp* inWhen)
{
	OSStatus theError = AudioStreamSetProperty(GetAudioStreamID(), inWhen, inChannel, inPropertyID, inDataSize, inData);
	ThrowIfError(theError, CAException(theError), "CAAudioHardwareStream::SetPropertyData: got an error setting the value of a property");
}