Exemple #1
0
bool CCoreAudioDevice::SetHogStatus(bool hog)
{
  if (!m_DeviceId)
    return false;
  
  pid_t holder = GetHogStatus();
  pid_t me = getpid();
  
  if (hog)
  {
    if (holder != me)
    {
      CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: Setting 'hog' status on device 0x%04x", m_DeviceId);
      OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyHogMode, sizeof(me), &me);
      if (ret)
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: Unable to set 'hog' status. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret));
        return false;
      }

      pid_t holder = GetHogStatus();
      if (holder != getpid())
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: Unable to set 'hog' status. another process (%x) has it.", holder);
        return false;
      }
      
      CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: Successfully set 'hog' status on device 0x%04x", m_DeviceId);
    }
  }
  else
  {
    if (holder == me) // Currently Set
    {
      CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: Releasing 'hog' status on device 0x%04x", m_DeviceId);
      
      pid_t hogPid = -1;
      OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyHogMode, sizeof(hogPid), &hogPid);
      
      if (ret)
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: Unable to release 'hog' status. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret));
        return false;
      }
      
      pid_t holder = GetHogStatus();
      if (holder == getpid())
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: failed to release. still hogging!");
        return false;
    }
  }
  }
  return true;
}
Exemple #2
0
bool CCoreAudioDevice::SetHogStatus(bool hog)
{
  // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode
  // is a toggle and the only way to tell if you do get hog mode is to compare
  // the returned pid against getpid, if the match, you have hog mode, if not you don't.
  if (!m_DeviceId)
    return false;

  AudioObjectPropertyAddress  propertyAddress;
  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
  propertyAddress.mElement  = 0;
  propertyAddress.mSelector = kAudioDevicePropertyHogMode;

  if (hog)
  {
    // Not already set
    if (m_HogPid == -1)
    {
      CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: "
        "Setting 'hog' status on device 0x%04x", (unsigned int)m_DeviceId);
      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(m_HogPid), &m_HogPid);

      // even if setting hogmode was successfull our PID might not get written
      // into m_HogPid (so it stays -1). Readback hogstatus for judging if we
      // had success on getting hog status
      m_HogPid = GetHogStatus();

      if (ret || m_HogPid != getpid())
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
          "Unable to set 'hog' status. Error = %s", GetError(ret).c_str());
        return false;
      }
      CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: "
                "Successfully set 'hog' status on device 0x%04x", (unsigned int)m_DeviceId);
    }
  }
  else
  {
    // Currently Set
    if (m_HogPid > -1)
    {
      CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: "
                "Releasing 'hog' status on device 0x%04x", (unsigned int)m_DeviceId);
      pid_t hogPid = -1;
      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(hogPid), &hogPid);
      if (ret || hogPid == getpid())
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
          "Unable to release 'hog' status. Error = %s", GetError(ret).c_str());
        return false;
      }
      // Reset internal state
      m_HogPid = hogPid;
    }
  }
  return true;
}
Exemple #3
0
bool CCoreAudioDevice::SetHogStatus(bool hog)
{
  // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode
  // is a toggle and the only way to tell if you do get hog mode is to compare
  // the returned pid against getpid, if the match, you have hog mode, if not you don't.
  if (!m_DeviceId)
    return false;

  AudioObjectPropertyAddress  propertyAddress;
  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
  propertyAddress.mElement  = 0;
  propertyAddress.mSelector = kAudioDevicePropertyHogMode;

  if (hog)
  {
    // Not already set
    if (m_HogPid == -1)
    {
      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(m_HogPid), &m_HogPid);

      // even if setting hogmode was successfull our PID might not get written
      // into m_HogPid (so it stays -1). Readback hogstatus for judging if we
      // had success on getting hog status
      // We do this only when AudioObjectSetPropertyData didn't set m_HogPid because
      // it seems that in the other cases the GetHogStatus could return -1
      // which would overwrite our valid m_HogPid again
      // Man we should never touch this shit again ;)
      if (m_HogPid == -1)
        m_HogPid = GetHogStatus();

      if (ret || m_HogPid != getpid())
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
          "Unable to set 'hog' status. Error = %s", GetError(ret).c_str());
        return false;
      }
    }
  }
  else
  {
    // Currently Set
    if (m_HogPid > -1)
    {
      pid_t hogPid = -1;
      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(hogPid), &hogPid);
      if (ret || hogPid == getpid())
      {
        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
          "Unable to release 'hog' status. Error = %s", GetError(ret).c_str());
        return false;
      }
      // Reset internal state
      m_HogPid = hogPid;
    }
  }
  return true;
}