org.jitsi.impl.neomedia.HardwareVolumeControl Maven / Gradle / Ivy
/*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.impl.neomedia;
import org.jitsi.impl.neomedia.device.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.utils.logging.*;
/**
* Implementation of VolumeControl which uses system sound architecture (MacOsX
* or Windows CoreAudio) to change input/output hardware volume.
*
* @author Vincent Lucas
*/
public class HardwareVolumeControl
extends BasicVolumeControl
{
/**
* The Logger used by the HarwareVolumeControl
* class and its instances for logging output.
*/
private static final Logger logger
= Logger.getLogger(HardwareVolumeControl.class);
/**
* The media service implementation.
*/
MediaServiceImpl mediaServiceImpl = null;
/**
* The maximal power level used for hardware amplification. Over this value
* software amplification is used.
*/
private static final float MAX_HARDWARE_POWER = 1.0F;
/**
* Creates volume control instance and initializes initial level value
* if stored in the configuration service.
*
* @param mediaServiceImpl The media service implementation.
* @param volumeLevelConfigurationPropertyName the name of the configuration
* property which specifies the value of the volume level of the new
* instance
*/
public HardwareVolumeControl(
MediaServiceImpl mediaServiceImpl,
String volumeLevelConfigurationPropertyName)
{
super(volumeLevelConfigurationPropertyName);
this.mediaServiceImpl = mediaServiceImpl;
// Gets the device volume (an error use the default volume).
this.volumeLevel = getDefaultVolumeLevel();
float volume = this.getVolume();
if(volume != -1)
{
this.volumeLevel = volume;
}
}
/**
* Returns the default volume level.
*
* @return The default volume level.
*/
protected static float getDefaultVolumeLevel()
{
// By default set the microphone at the middle of its hardware
// sensibility range.
return MAX_HARDWARE_POWER / 2;
}
/**
* Returns the reference volume level for computing the gain.
*
* @return The reference volume level for computing the gain.
*/
protected static float getGainReferenceLevel()
{
// Starts to activate the gain (software amplification), only once the
// microphone sensibility is sets to its maximum (hardware
// amplification).
return MAX_HARDWARE_POWER;
}
/**
* Modifies the hardware microphone sensibility (hardware amplification).
*/
@Override
protected void updateHardwareVolume()
{
// Gets the selected input dvice UID.
String deviceUID = getCaptureDeviceUID();
// Computes the hardware volume.
float jitsiHarwareVolumeFactor = MAX_VOLUME_LEVEL / MAX_HARDWARE_POWER;
float hardwareVolumeLevel = this.volumeLevel * jitsiHarwareVolumeFactor;
if(hardwareVolumeLevel > 1.0F)
{
hardwareVolumeLevel = 1.0F;
}
// Changes the input volume of the capture device.
if(this.setInputDeviceVolume(
deviceUID,
hardwareVolumeLevel) != 0)
{
logger.debug("Could not change hardware input device level");
}
}
/**
* Returns the selected input device UID.
*
* @return The selected input device UID. Or null if not found.
*/
protected String getCaptureDeviceUID()
{
AudioSystem audioSystem
= mediaServiceImpl.getDeviceConfiguration().getAudioSystem();
CaptureDeviceInfo2 captureDevice
= (audioSystem == null)
? null
: audioSystem.getSelectedDevice(AudioSystem.DataFlow.CAPTURE);
return (captureDevice == null) ? null : captureDevice.getUID();
}
/**
* Changes the device volume via the system API.
*
* @param deviceUID The device ID.
* @param volume The volume requested.
*
* @return 0 if everything works fine.
*/
protected int setInputDeviceVolume(String deviceUID, float volume)
{
if(deviceUID == null)
{
return -1;
}
if(CoreAudioDevice.initDevices() == -1)
{
CoreAudioDevice.freeDevices();
logger.debug(
"Could not initialize CoreAudio input devices");
return -1;
}
// Change the input volume of the capture device.
if(CoreAudioDevice.setInputDeviceVolume(deviceUID, volume) != 0)
{
CoreAudioDevice.freeDevices();
logger.debug(
"Could not change CoreAudio input device level");
return -1;
}
CoreAudioDevice.freeDevices();
return 0;
}
/**
* Returns the device volume via the system API.
*
* @param deviceUID The device ID.
*
* @return A scalar value between 0 and 1 if everything works fine. -1 if an
* error occurred.
*/
protected float getInputDeviceVolume(String deviceUID)
{
float volume;
if(deviceUID == null)
{
return -1;
}
if(CoreAudioDevice.initDevices() == -1)
{
CoreAudioDevice.freeDevices();
logger.debug(
"Could not initialize CoreAudio input devices");
return -1;
}
// Get the input volume of the capture device.
if((volume = CoreAudioDevice.getInputDeviceVolume(deviceUID))
== -1)
{
CoreAudioDevice.freeDevices();
logger.debug(
"Could not get CoreAudio input device level");
return -1;
}
CoreAudioDevice.freeDevices();
return volume;
}
/**
* Current volume value.
*
* @return the current volume level.
*
* @see org.jitsi.service.neomedia.VolumeControl
*/
@Override
public float getVolume()
{
String deviceUID = getCaptureDeviceUID();
float volume = this.getInputDeviceVolume(deviceUID);
// If the hardware voume for this device is not available, then switch
// to the software volume.
if(volume == -1)
{
volume = super.getVolume();
}
return volume;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy