diff --git a/PlayWall/src/de/tobias/playpad/PlayPadMain.java b/PlayWall/src/de/tobias/playpad/PlayPadMain.java index cdec5baf549e2c510843e47d536acc7d54a639bf..d84ff49f5338c511d3046690a1ba2b97620780f3 100644 --- a/PlayWall/src/de/tobias/playpad/PlayPadMain.java +++ b/PlayWall/src/de/tobias/playpad/PlayPadMain.java @@ -18,6 +18,7 @@ import de.tobias.playpad.audio.TinyAudioHandler; import de.tobias.playpad.design.modern.ModernGlobalDesign; import de.tobias.playpad.midi.device.DeviceRegistry; import de.tobias.playpad.midi.device.PD12; +import de.tobias.playpad.pad.Pad; import de.tobias.playpad.project.Project; import de.tobias.playpad.project.ProjectReference; import de.tobias.playpad.registry.NoSuchComponentException; @@ -29,6 +30,9 @@ import de.tobias.playpad.update.Updates; import de.tobias.playpad.view.MapperOverviewViewController; import de.tobias.playpad.viewcontroller.LaunchDialog; import de.tobias.playpad.viewcontroller.dialog.ChangelogDialog; +import de.tobias.playpad.volume.GlobalVolume; +import de.tobias.playpad.volume.PadVolume; +import de.tobias.playpad.volume.VolumeManager; import de.tobias.utils.application.App; import de.tobias.utils.application.ApplicationUtils; import de.tobias.utils.application.container.PathType; @@ -135,7 +139,8 @@ public class PlayPadMain extends Application implements LocalizationDelegate { try { Image stageIcon = new Image(iconPath); PlayPadMain.stageIcon = Optional.of(stageIcon); - } catch (Exception e) {} + } catch (Exception e) { + } /* * Setup @@ -256,6 +261,11 @@ public class PlayPadMain extends Application implements LocalizationDelegate { GlobalSettings globalSettings = PlayPadPlugin.getImplementation().getGlobalSettings(); globalSettings.getKeyCollection().loadDefaultFromFile("de/tobias/playpad/components/Keys.xml", uiResourceBundle); + // Volume filter + VolumeManager volumeManager = Pad.getVolumeManager(); + volumeManager.addFilter(new GlobalVolume()); + volumeManager.addFilter(new PadVolume()); + // Mapper MapperRegistry.setOverviewViewController(new MapperOverviewViewController()); } diff --git a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java index 64b3de3e6334da309219d164af8d7470afe84c0e..d4c7018f07d3a8122d5f1b89be765d1b56151c91 100644 --- a/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java +++ b/PlayWall/src/de/tobias/playpad/audio/ClipAudioHandler.java @@ -84,7 +84,9 @@ public class ClipAudioHandler extends AudioHandler { } Thread.sleep(SLEEP_TIME_POSITION); - } catch (InterruptedException e) {} catch (ConcurrentModificationException e) {} catch (Exception e) { + } catch (InterruptedException e) { + } catch (ConcurrentModificationException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -174,7 +176,7 @@ public class ClipAudioHandler extends AudioHandler { * @param volume * [0, 1] */ - private void setVolume(double volume) { + public void setVolume(double volume) { if (volumeControl != null) { if (volume == 1.0) { volumeControl.setValue(0); diff --git a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java index 4792e37a92538363d0473e2ffac5a974246d8054..8065db956e7aa6cd0ede19149449201550019c06 100644 --- a/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java +++ b/PlayWall/src/de/tobias/playpad/audio/JavaFXAudioHandler.java @@ -82,6 +82,13 @@ public class JavaFXAudioHandler extends AudioHandler implements Equalizable { if (player != null) player.setVolume(volume * masterVolume * customVolume); } + + @Override + public void setVolume(double volume) { + if (player != null) { + player.setVolume(volume); + } + } @Override public boolean isMediaLoaded() { diff --git a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java index 7bf652f8fa50e2f7dffd0d9bcec260dd2dba41f5..de4b3475cfba00c8f216c82dad1d14302a027550 100644 --- a/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java +++ b/PlayWall/src/de/tobias/playpad/audio/TinyAudioHandler.java @@ -200,6 +200,13 @@ public class TinyAudioHandler extends AudioHandler { music.setVolume(volume * masterVolume * customVolume); } } + + @Override + public void setVolume(double volume) { + if (music != null) { + music.setVolume(volume); + } + } @Override public boolean isMediaLoaded() { diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java index 9f81f3fc39ed13da5aad145204028e75f7ce0933..9bca88f04c31f4c8defc508e9fcd176cb777345e 100644 --- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java +++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java @@ -13,7 +13,6 @@ import de.tobias.playpad.audio.AudioRegistry; import de.tobias.playpad.audio.Equalizable; import de.tobias.playpad.audio.fade.Fading; import de.tobias.playpad.pad.Pad; -import de.tobias.playpad.pad.PadSettings; import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.pad.conntent.path.SinglePathContent; @@ -23,8 +22,7 @@ import de.tobias.playpad.pad.conntent.play.IVolume; import de.tobias.playpad.pad.conntent.play.Pauseable; import de.tobias.playpad.project.ProjectExporter; import de.tobias.playpad.registry.NoSuchComponentException; -import de.tobias.playpad.settings.Profile; -import de.tobias.playpad.settings.ProfileSettings; +import de.tobias.playpad.volume.VolumeManager; import de.tobias.utils.util.ZipFile; import javafx.animation.Transition; import javafx.application.Platform; @@ -47,7 +45,6 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, private ObjectProperty<Duration> positionProperty = new SimpleObjectProperty<>(); private ChangeListener<Number> volumeListener; - private ChangeListener<Number> customVolumeListener; private Fading fading; @@ -57,13 +54,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, super(pad); volumeListener = (a, b, c) -> { - ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); - audioHandler.setVolume(c.doubleValue(), profileSettings.getVolume(), pad.getCustomVolume()); - }; - customVolumeListener = (a, b, c) -> - { - ProfileSettings profileSettings = Profile.currentProfile().getProfileSettings(); - audioHandler.setVolume(pad.getPadSettings().getVolume(), profileSettings.getVolume(), c.doubleValue()); + updateVolume(); }; } @@ -84,10 +75,9 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, } @Override - public void setMasterVolume(double masterVolume) { - if (audioHandler != null) { - audioHandler.setVolume(getPad().getPadSettings().getVolume(), masterVolume, getPad().getCustomVolume()); - } + public void updateVolume() { + double volume = Pad.getVolumeManager().computeVolume(getPad()); + audioHandler.setVolume(volume); } @Override @@ -97,7 +87,6 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, @Override public void play() { - getPad().setCustomVolume(1); getPad().setEof(false); audioHandler.play(); } @@ -132,11 +121,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, fading.fadeOut(getPad().getPadSettings().getFade().getFadeOut(), () -> { onFinish.run(); - - double masterVolume = Profile.currentProfile().getProfileSettings().getVolume(); - PadSettings padSettings = getPad().getPadSettings(); - - audioHandler.setVolume(padSettings.getVolume(), masterVolume, getPad().getCustomVolume()); + updateVolume(); }); } else { onFinish.run(); @@ -154,9 +139,9 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, @Override public void setFadeLevel(double level) { Pad pad = getPad(); - double masterVolume = Profile.currentProfile().getProfileSettings().getVolume(); + VolumeManager manager = Pad.getVolumeManager(); - audioHandler.setVolume(level * pad.getPadSettings().getVolume(), masterVolume, pad.getCustomVolume()); + audioHandler.setVolume(level * manager.computeVolume(pad)); } @Override @@ -197,7 +182,7 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, // init audio implementation AudioRegistry audioRegistry = PlayPadPlugin.getRegistryCollection().getAudioHandlers(); audioHandler = audioRegistry.getCurrentAudioHandler().createAudioHandler(this); - + fading = new Fading(this); if (Files.exists(path)) { @@ -207,7 +192,6 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, positionProperty.bind(audioHandler.positionProperty()); getPad().getPadSettings().volumeProperty().addListener(volumeListener); - getPad().customVolumeProperty().addListener(customVolumeListener); } else { getPad().throwException(path, new FileNotFoundException()); } @@ -219,7 +203,6 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, positionProperty.unbind(); getPad().getPadSettings().volumeProperty().removeListener(volumeListener); - getPad().customVolumeProperty().removeListener(customVolumeListener); if (audioHandler != null) audioHandler.unloadMedia(); diff --git a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java index c9a6ce6b351d09cb7ddc1160ecf40b8d3350768d..709c93acda9177e3cdc09c04cbe3f8bd622aeb37 100644 --- a/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java +++ b/PlayWall/src/de/tobias/playpad/trigger/VolumeTriggerItem.java @@ -56,11 +56,12 @@ public class VolumeTriggerItem extends TriggerItem { protected void interpolate(double frac) { for (Pad p : project.getPads().values()) { if (p.getIndex() != pad.getIndex()) { - if (p.getCustomVolume() > volume) { - p.setCustomVolume(currentValue - frac * (currentValue - volume)); - } else { - p.setCustomVolume(currentValue + frac * (volume - currentValue)); - } + // TODO Volume Trigger Implemeitation + // if (p.getCustomVolume() > volume) { + // p.setCustomVolume(currentValue - frac * (currentValue - volume)); + // } else { + // p.setCustomVolume(currentValue + frac * (volume - currentValue)); + // } } } } diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewControllerV2.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewControllerV2.java index 0025fa6d3f608793ee0a0676261f41577b8d3a46..702768c7ce75a2771fa96a078edae40116042545 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewControllerV2.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/MainViewControllerV2.java @@ -107,7 +107,7 @@ public class MainViewControllerV2 extends ViewController implements IMainViewCon layoutActions = new ArrayList<>(); // Init Listener - volumeChangeListener = new VolumeChangeListener(this); + volumeChangeListener = new VolumeChangeListener(null); lockedListener = new LockedListener(this); layoutChangedListener = new LayoutChangedListener(); @@ -117,8 +117,7 @@ public class MainViewControllerV2 extends ViewController implements IMainViewCon reloadSettings(null, Profile.currentProfile()); // Wenn sich die Toolbar ändert werden die Button neu erstellt. Das ist hier, weil es nur einmal als Listener da - // sein muss. Die - // Methode wird aber an unterschiedlichen stellen mehrmals aufgerufen + // sein muss. Die Methode wird aber an unterschiedlichen stellen mehrmals aufgerufen performLayoutDependendAction((oldToolbar, newToolbar) -> { if (menuToolbarViewController != null) @@ -383,6 +382,7 @@ public class MainViewControllerV2 extends ViewController implements IMainViewCon initMapper(project); + volumeChangeListener.setOpenProject(openProject); midiHandler.setProject(project); keyboardHandler.setProject(project); PadDragListener.setProject(project); @@ -512,16 +512,6 @@ public class MainViewControllerV2 extends ViewController implements IMainViewCon return currentPageShowing; } - @Override - public void setGlobalVolume(double volume) { - if (openProject != null) { - for (Pad pad : openProject.getPads().values()) { - if (pad != null) - pad.setMasterVolume(volume); - } - } - } - private boolean shown = false; @Override @@ -533,7 +523,8 @@ public class MainViewControllerV2 extends ViewController implements IMainViewCon { try { Thread.sleep(PlayPadMain.displayTimeMillis * 2); - } catch (Exception e) {} + } catch (Exception e) { + } Platform.runLater(() -> { if (menuToolbarViewController != null) diff --git a/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java b/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java index 2d017c45054c6cc0a50273085ea55886c5765d3d..708b7e235798f8abfbccc9906609477561e158b5 100644 --- a/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java +++ b/PlayWall/src/de/tobias/playpad/viewcontroller/main/VolumeChangeListener.java @@ -1,18 +1,30 @@ package de.tobias.playpad.viewcontroller.main; +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.pad.PadStatus; +import de.tobias.playpad.project.Project; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; public class VolumeChangeListener implements ChangeListener<Number> { - private IMainViewController mainViewController; + private Project openProject; - public VolumeChangeListener(IMainViewController mainViewController) { - this.mainViewController = mainViewController; + public VolumeChangeListener(Project openProject) { + this.openProject = openProject; + } + + public void setOpenProject(Project openProject) { + this.openProject = openProject; } @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { - mainViewController.setGlobalVolume(newValue.doubleValue()); + if (openProject != null) { + for (Pad pad : openProject.getPads().values()) { + if (pad != null && pad.getStatus() != PadStatus.EMPTY) + pad.getContent().updateVolume(); + } + } } } diff --git a/PlayWall/src/de/tobias/playpad/volume/GlobalVolume.java b/PlayWall/src/de/tobias/playpad/volume/GlobalVolume.java new file mode 100644 index 0000000000000000000000000000000000000000..d416c051002d05176f25dcc67f9c744a48440352 --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/volume/GlobalVolume.java @@ -0,0 +1,16 @@ +package de.tobias.playpad.volume; + +import de.tobias.playpad.pad.Pad; +import de.tobias.playpad.settings.Profile; + +public class GlobalVolume implements VolumeFilter { + + @Override + public double getVolume(Pad pad) { + if (Profile.currentProfile() != null) { + return Profile.currentProfile().getProfileSettings().getVolume(); + } else { + return 1.0; + } + } +} diff --git a/PlayWall/src/de/tobias/playpad/volume/PadVolume.java b/PlayWall/src/de/tobias/playpad/volume/PadVolume.java new file mode 100644 index 0000000000000000000000000000000000000000..4781bd629b4256cef761054a66e063e1e289d244 --- /dev/null +++ b/PlayWall/src/de/tobias/playpad/volume/PadVolume.java @@ -0,0 +1,11 @@ +package de.tobias.playpad.volume; + +import de.tobias.playpad.pad.Pad; + +public class PadVolume implements VolumeFilter { + + @Override + public double getVolume(Pad pad) { + return pad.getPadSettings().getVolume(); + } +} diff --git a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java index 7b0f8aeb949969c2f0e3cb0bbd04cca3faa5e570..bd2f32033110c0d72d1d79659c2e258822fa8cd3 100644 --- a/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java +++ b/PlayWallCore/src/de/tobias/playpad/audio/AudioHandler.java @@ -35,6 +35,9 @@ public abstract class AudioHandler { public abstract ReadOnlyObjectProperty<Duration> durationProperty(); + public abstract void setVolume(double volume); + + @Deprecated public abstract void setVolume(double volume, double masterVolume, double customVolume); public abstract boolean isMediaLoaded(); diff --git a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java index 06cb57b8ae656c046100a24aced0b592c3315dd5..a8115295d69f5f34aa9e79eee8a0f167c777de5b 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/Pad.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/Pad.java @@ -10,11 +10,10 @@ import de.tobias.playpad.pad.listener.trigger.PadTriggerStatusListener; import de.tobias.playpad.pad.viewcontroller.IPadViewControllerV2; import de.tobias.playpad.project.Project; import de.tobias.playpad.registry.NoSuchComponentException; -import javafx.beans.property.DoubleProperty; +import de.tobias.playpad.volume.VolumeManager; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyIntegerProperty; -import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; @@ -22,6 +21,12 @@ import javafx.beans.property.StringProperty; public class Pad { + private static final VolumeManager volumeManager; + + static { + volumeManager = new VolumeManager(); + } + // Verwaltung private IntegerProperty indexProperty = new SimpleIntegerProperty(); private StringProperty nameProperty = new SimpleStringProperty(); @@ -33,9 +38,6 @@ public class Pad { // Settings private PadSettings padSettings; - // Custom Volume - private transient DoubleProperty customVolumeProperty = new SimpleDoubleProperty(1.0); - // Global Listener (unabhängig von der UI), für Core Functions wie Play, Pause private transient PadStatusListener padStatusListener; @@ -167,12 +169,6 @@ public class Pad { return padSettings; } - public void setMasterVolume(double volume) { - if (getContent() != null) { - getContent().setMasterVolume(volume); - } - } - public boolean isEof() { return eof; } @@ -252,16 +248,8 @@ public class Pad { return (indexProperty.get() + 1) + " - " + nameProperty.get(); } - // TODO Reorder - public void setCustomVolume(double volume) { - customVolumeProperty.set(volume); - } - - public double getCustomVolume() { - return customVolumeProperty.get(); - } - - public DoubleProperty customVolumeProperty() { - return customVolumeProperty; + // Volume Manager + public static VolumeManager getVolumeManager() { + return volumeManager; } } diff --git a/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java index 5e8df0ee7a58a6c0beb59751d29896c069b57a64..87d2ec8f6a60976491567afea56bd1618c7bd9d7 100644 --- a/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java +++ b/PlayWallCore/src/de/tobias/playpad/pad/conntent/PadContent.java @@ -60,7 +60,7 @@ public abstract class PadContent { */ public abstract void unloadMedia(); - public abstract void setMasterVolume(double masterVolume); + public abstract void updateVolume(); @Override protected void finalize() throws Throwable { diff --git a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java index 9a39e8f621ae3d2d0e4b71fe59139025a68b3bd7..3191b3f18f0cef774406762d44ef9d2ecad5db85 100644 --- a/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java +++ b/PlayWallCore/src/de/tobias/playpad/viewcontroller/main/IMainViewController.java @@ -126,14 +126,6 @@ public interface IMainViewController extends NotificationHandler { */ public MidiListener getMidiHandler(); - /** - * Setzt das Globale Volume bei den Kacheln des aktuellen Projekts. - * - * @param doubleValue - * [0..1] - */ - public void setGlobalVolume(double doubleValue); - /** * Setzt das MainLayout des Hauptfensters. * diff --git a/PlayWallCore/src/de/tobias/playpad/volume/VolumeFilter.java b/PlayWallCore/src/de/tobias/playpad/volume/VolumeFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..805fc4387578b4f6601b8beb2a73d58a7970e470 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/volume/VolumeFilter.java @@ -0,0 +1,19 @@ +package de.tobias.playpad.volume; + +import de.tobias.playpad.pad.Pad; + +/** + * Interface, um das Volume eines Pad zu beeinflussen. Es muss dem VolumeManager hinzugefügt werden. + * + * @author tobias + * + * @sinve 6.0.0 + * + * @see VolumeManager#addFilter(VolumeFilter) + */ +@FunctionalInterface +public interface VolumeFilter { + + double getVolume(Pad pad); + +} diff --git a/PlayWallCore/src/de/tobias/playpad/volume/VolumeManager.java b/PlayWallCore/src/de/tobias/playpad/volume/VolumeManager.java new file mode 100644 index 0000000000000000000000000000000000000000..8a809d40be62223c8fa99ab307f68912547594bf --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/volume/VolumeManager.java @@ -0,0 +1,36 @@ +package de.tobias.playpad.volume; + +import java.util.ArrayList; +import java.util.List; + +import de.tobias.playpad.pad.Pad; + +public class VolumeManager { + + private List<VolumeFilter> filters; + + public VolumeManager() { + this.filters = new ArrayList<>(); + } + + public void addFilter(VolumeFilter filter) { + filters.add(filter); + } + + public void removeFilter(VolumeFilter filter) { + filters.remove(filter); + } + + public double computeVolume(Pad pad) { + double volume = 1; + for (VolumeFilter filter : filters) { + volume *= filter.getVolume(pad); + + if (volume == 0) { + break; + } + } + return volume; + } + +}