From 924f49327513cad83a7e05e1ce32d0b2d0659bf4 Mon Sep 17 00:00:00 2001 From: Vincent Lucas <chenzo@jitsi.org> Date: Thu, 6 Dec 2012 15:07:05 +0000 Subject: [PATCH] Corrects UnsatisfiedLinkError when trying to load nonexistent Windows or MacOSX CoreAudio library. Initializes microphone volume based on system value for MacOSX and Windows Vista/7/8. --- .../AbstractHardwareVolumeControl.java | 49 ++++++++++++++--- .../impl/neomedia/AbstractVolumeControl.java | 54 +++++++++++-------- .../jitsi/impl/neomedia/MediaServiceImpl.java | 43 +++++++++------ .../maccoreaudio/CoreAudioVolumeControl.java | 22 ++++++++ .../wincoreaudio/CoreAudioVolumeControl.java | 35 +++++++++++- 5 files changed, 157 insertions(+), 46 deletions(-) diff --git a/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java b/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java index 8e3216bd..c1e5d1c0 100644 --- a/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java +++ b/src/org/jitsi/impl/neomedia/AbstractHardwareVolumeControl.java @@ -51,7 +51,15 @@ public AbstractHardwareVolumeControl( { super(volumeLevelConfigurationPropertyName); this.mediaServiceImpl = mediaServiceImpl; - updateHardwareVolume(); + + // Gets the device volume (an error use the default volume). + this.volumeLevel = getDefaultVolumeLevel(); + String deviceUID = getCaptureDeviceUID(); + float volume = this.getInputDeviceVolume(deviceUID); + if(volume != -1) + { + this.volumeLevel = volume; + } } /** @@ -85,12 +93,7 @@ protected static float getGainReferenceLevel() protected void updateHardwareVolume() { // Gets the selected input dvice UID. - AudioSystem audioSystem - = mediaServiceImpl.getDeviceConfiguration().getAudioSystem(); - ExtendedCaptureDeviceInfo captureDevice = (audioSystem == null) - ? null - : audioSystem.getDevice(AudioSystem.CAPTURE_INDEX); - String deviceUID = captureDevice.getUID(); + String deviceUID = getCaptureDeviceUID(); // Computes the hardware volume. float jitsiHarwareVolumeFactor = MAX_VOLUME_LEVEL / MAX_HARDWARE_POWER; @@ -109,6 +112,28 @@ protected void updateHardwareVolume() } } + /** + * Returns the selected input device UID. + * + * @return The selected input device UID. Or null if not found. + */ + protected String getCaptureDeviceUID() + { + String deviceUID = null; + + AudioSystem audioSystem + = mediaServiceImpl.getDeviceConfiguration().getAudioSystem(); + ExtendedCaptureDeviceInfo captureDevice = (audioSystem == null) + ? null + : audioSystem.getDevice(AudioSystem.CAPTURE_INDEX); + if(captureDevice != null) + { + deviceUID = captureDevice.getUID(); + } + + return deviceUID; + } + /** * Changes the device volume via the system API. * @@ -118,4 +143,14 @@ protected void updateHardwareVolume() * @return 0 if everything works fine. */ protected abstract int setInputDeviceVolume(String deviceUID, float volume); + + /** + * 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 occured. + */ + protected abstract float getInputDeviceVolume(String deviceUID); } diff --git a/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java b/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java index bc1ff397..1fe139bd 100644 --- a/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java +++ b/src/org/jitsi/impl/neomedia/AbstractVolumeControl.java @@ -127,29 +127,7 @@ public AbstractVolumeControl( = volumeLevelConfigurationPropertyName; // Read the initial volume level from the ConfigurationService. - try - { - ConfigurationService cfg = LibJitsi.getConfigurationService(); - - if (cfg != null) - { - String volumeLevelString - = cfg.getString(this.volumeLevelConfigurationPropertyName); - - if (volumeLevelString != null) - { - this.volumeLevel = Float.parseFloat(volumeLevelString); - if(logger.isDebugEnabled()) - { - logger.debug("Restored volume: " + volumeLevelString); - } - } - } - } - catch (Throwable t) - { - logger.warn("Error restoring volume", t); - } + this.loadVolume(); } /** @@ -589,4 +567,34 @@ protected void updateHardwareVolume() { // Nothing to do. This AbstractVolumeControl only modifies the gain. } + + /** + * Reads the initial volume level from the system. + */ + protected void loadVolume() + { + try + { + ConfigurationService cfg = LibJitsi.getConfigurationService(); + + if (cfg != null) + { + String volumeLevelString + = cfg.getString(this.volumeLevelConfigurationPropertyName); + + if (volumeLevelString != null) + { + this.volumeLevel = Float.parseFloat(volumeLevelString); + if(logger.isDebugEnabled()) + { + logger.debug("Restored volume: " + volumeLevelString); + } + } + } + } + catch (Throwable t) + { + logger.warn("Error restoring volume", t); + } + } } diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java index d84bfd21..641ab4f4 100644 --- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java +++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java @@ -748,25 +748,38 @@ public VolumeControl getInputVolumeControl() { if (inputVolumeControl == null) { - if(OSUtils.IS_MAC) - { - inputVolumeControl - = new + boolean initialized = false; + try{ + if(OSUtils.IS_MAC) + { + inputVolumeControl = new org.jitsi.impl.neomedia.maccoreaudio.CoreAudioVolumeControl( - this, - VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME); + this, + VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME + ); + initialized = true; + } + else if(OSUtils.IS_WINDOWS_VISTA + || OSUtils.IS_WINDOWS_7 + || OSUtils.IS_WINDOWS_8) + { + inputVolumeControl = new + org.jitsi.impl.neomedia.wincoreaudio.CoreAudioVolumeControl( + this, + VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME + ); + initialized = true; + } } - else if(OSUtils.IS_WINDOWS_VISTA - || OSUtils.IS_WINDOWS_7 - || OSUtils.IS_WINDOWS_8) + catch(UnsatisfiedLinkError ule) { - inputVolumeControl - = new - org.jitsi.impl.neomedia.wincoreaudio.CoreAudioVolumeControl( - this, - VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME); + //initialized = false; + logger.info("Can not load system volume control: " + + ule.getMessage() + + ". Loading default software volume control."); } - else + + if(!initialized) { inputVolumeControl = new AbstractVolumeControl( diff --git a/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java b/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java index 2df72ad7..217906ba 100644 --- a/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java +++ b/src/org/jitsi/impl/neomedia/maccoreaudio/CoreAudioVolumeControl.java @@ -61,4 +61,26 @@ protected int setInputDeviceVolume(String deviceUID, float volume) } 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 occured. + */ + protected float getInputDeviceVolume(String deviceUID) + { + float volume; + + if((volume = CoreAudioDevice.getInputDeviceVolume(deviceUID)) + != 0) + { + logger.debug( + "Could not get MacOsX CoreAudio input device level"); + } + + return volume; + } } diff --git a/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java b/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java index a14c77f4..188540b4 100644 --- a/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java +++ b/src/org/jitsi/impl/neomedia/wincoreaudio/CoreAudioVolumeControl.java @@ -59,7 +59,7 @@ protected int setInputDeviceVolume(String deviceUID, float volume) "Could not initialize Windows CoreAudio input devices"); return -1; } - // Changes the input volume of the capture device. + // Change the input volume of the capture device. if(CoreAudioDevice.setInputDeviceVolume(deviceUID, volume) != 0) { CoreAudioDevice.freeDevices(); @@ -71,4 +71,37 @@ protected int setInputDeviceVolume(String deviceUID, float volume) 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 occured. + */ + protected float getInputDeviceVolume(String deviceUID) + { + float volume; + + if(CoreAudioDevice.initDevices() == -1) + { + CoreAudioDevice.freeDevices(); + logger.debug( + "Could not initialize Windows 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 Windows CoreAudio input device level"); + return -1; + } + CoreAudioDevice.freeDevices(); + + return volume; + } } -- GitLab