From 22cb116b4dc7a5f871ce7c36fe8f4b577c6da461 Mon Sep 17 00:00:00 2001 From: tobias <tobias.ullerich@icloud.com> Date: Thu, 8 Sep 2016 10:10:52 +0200 Subject: [PATCH] Start adding peak meter --- .../playpad/action/cartaction/CartAction.java | 4 +- .../playpad/pad/content/AudioContent.java | 4 + .../pad/content/AudioContentConnect.java | 17 +++- .../src/de/tobias/playpad/audio/Peakable.java | 15 ++++ .../de/tobias/playpad/pad/view/PeakMeter.java | 45 ++++++++++ .../src/de/tobias/playpad/NativeAudio.java | 16 ++++ .../tobias/playpad/NativeAudioMacHandler.java | 86 ++++++------------- .../playpad/NativeAudioMacHandlerConnect.java | 19 ++++ 8 files changed, 142 insertions(+), 64 deletions(-) create mode 100644 PlayWallCore/src/de/tobias/playpad/audio/Peakable.java create mode 100644 PlayWallCore/src/de/tobias/playpad/pad/view/PeakMeter.java diff --git a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java index b6cc56cd..15796b6f 100644 --- a/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java +++ b/PlayWall/src/de/tobias/playpad/action/cartaction/CartAction.java @@ -22,9 +22,7 @@ import javafx.beans.property.StringProperty; public class CartAction extends Action implements ColorAdjustable { public enum ControlMode { - PLAY_PAUSE, - PLAY_STOP, - PLAY_HOLD; + PLAY_PAUSE, PLAY_STOP, PLAY_HOLD; } private int x; diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java index 2d9b2200..24b4e838 100644 --- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java +++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContent.java @@ -63,6 +63,10 @@ public class AudioContent extends PadContent implements Pauseable, Durationable, }; } + public AudioHandler getAudioHandler() { + return audioHandler; + } + @Override public Path getPath() { return path; diff --git a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java index 538d4d41..ae3ea494 100644 --- a/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java +++ b/PlayWall/src/de/tobias/playpad/pad/content/AudioContentConnect.java @@ -1,10 +1,12 @@ package de.tobias.playpad.pad.content; import de.tobias.playpad.Strings; +import de.tobias.playpad.audio.Peakable; import de.tobias.playpad.pad.Pad; import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.pad.conntent.PadContentConnect; import de.tobias.playpad.pad.view.IPadContentView; +import de.tobias.playpad.pad.view.PeakMeter; import de.tobias.playpad.viewcontroller.option.ProfileSettingsTabViewController; import de.tobias.playpad.viewcontroller.option.profile.AudioTabViewController; import de.tobias.utils.ui.icon.FontAwesomeType; @@ -66,15 +68,22 @@ public class AudioContentConnect extends PadContentConnect { private class AudioContentView implements IPadContentView { private Label nameLabel; + private PeakMeter meter; public AudioContentView(Pad pad, Pane parentNode) { nameLabel = new Label(); nameLabel.textProperty().bind(pad.nameProperty()); - + nameLabel.setWrapText(true); nameLabel.setAlignment(Pos.CENTER); nameLabel.setTextAlignment(TextAlignment.CENTER); + AudioContent content = (AudioContent) pad.getContent(); + if (content.getAudioHandler() instanceof Peakable) { + Peakable peakable = (Peakable) content.getAudioHandler(); + meter = new PeakMeter(peakable); + } + nameLabel.prefWidthProperty().bind(parentNode.widthProperty()); nameLabel.setMaxHeight(Double.MAX_VALUE); VBox.setVgrow(nameLabel, Priority.ALWAYS); @@ -82,7 +91,11 @@ public class AudioContentConnect extends PadContentConnect { @Override public Node getNode() { - return nameLabel; + if (meter != null) { + return new VBox(7, nameLabel, meter); + } else { + return new VBox(7, nameLabel); + } } @Override diff --git a/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java b/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java new file mode 100644 index 00000000..c4633e92 --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java @@ -0,0 +1,15 @@ +package de.tobias.playpad.audio; + +import javafx.beans.property.DoubleProperty; + +public interface Peakable { + + public enum Channel { + LEFT, + RIGHT; + } + + public double getAudioLevel(Channel channel); + + public DoubleProperty audioLevelProperty(Channel channel); +} diff --git a/PlayWallCore/src/de/tobias/playpad/pad/view/PeakMeter.java b/PlayWallCore/src/de/tobias/playpad/pad/view/PeakMeter.java new file mode 100644 index 00000000..01f694bb --- /dev/null +++ b/PlayWallCore/src/de/tobias/playpad/pad/view/PeakMeter.java @@ -0,0 +1,45 @@ +package de.tobias.playpad.pad.view; + +import de.tobias.playpad.audio.Peakable; +import de.tobias.playpad.audio.Peakable.Channel; +import javafx.beans.value.ChangeListener; +import javafx.scene.control.ProgressBar; +import javafx.scene.layout.VBox; + +public class PeakMeter extends VBox { + + private ProgressBar progressbarLeft; + private ProgressBar progressbarRight; + + private ChangeListener<Number> leftListener; + private ChangeListener<Number> rightListener; + + public PeakMeter(Peakable peakable) { + progressbarLeft = new ProgressBar(0); + progressbarRight = new ProgressBar(0); + + leftListener = (a, b, c) -> { + double value = (c.doubleValue() + 60) * 1 / 60; + if (value < 0) + value = 0; + progressbarLeft.setProgress(value); + }; + rightListener = (a, b, c) -> { + double value = (c.doubleValue() + 60) * 1 / 60; + if (value < 0) + value = 0; + progressbarRight.setProgress(value); + }; + + progressbarLeft.getStyleClass().add("pad-playbar"); + progressbarRight.getStyleClass().add("pad-playbar"); + + progressbarLeft.prefWidthProperty().bind(widthProperty()); + progressbarRight.prefWidthProperty().bind(widthProperty()); + + peakable.audioLevelProperty(Channel.LEFT).addListener(leftListener); + peakable.audioLevelProperty(Channel.RIGHT).addListener(rightListener); + + getChildren().addAll(progressbarLeft, progressbarRight); + } +} \ No newline at end of file diff --git a/PlayWallNative/src/de/tobias/playpad/NativeAudio.java b/PlayWallNative/src/de/tobias/playpad/NativeAudio.java index ae297856..cee1d727 100644 --- a/PlayWallNative/src/de/tobias/playpad/NativeAudio.java +++ b/PlayWallNative/src/de/tobias/playpad/NativeAudio.java @@ -23,7 +23,19 @@ public class NativeAudio { public static native double getDuration(int id); public static native double getPosition(int id); + + public static void onPeakMeter(int id, float left, float right) { + if (delegate != null) { + delegate.onPeakMeter(id, left, right); + } + } + public static void onPositionChanged(int id, double position) { + if (delegate != null) { + delegate.onPositionChanged(id, position); + } + } + public static void onFinish(int id) { if (delegate != null) { delegate.onFinish(id); @@ -38,5 +50,9 @@ public class NativeAudio { public interface NativeAudioDelegate { public void onFinish(int id); + + public void onPeakMeter(int id, float left, float right); + + public void onPositionChanged(int id, double position); } } diff --git a/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java index 2ff8be3a..d418b132 100644 --- a/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java +++ b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java @@ -1,73 +1,43 @@ package de.tobias.playpad; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; import de.tobias.playpad.audio.AudioHandler; +import de.tobias.playpad.audio.Peakable; import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.utils.util.Worker; import javafx.application.Platform; +import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.util.Duration; -public class NativeAudioMacHandler extends AudioHandler { - - private static final int SLEEP_TIME_POSITION = 100; +public class NativeAudioMacHandler extends AudioHandler implements Peakable { private static int counter = 0; private final int id; - private ObjectProperty<Duration> positionProperty; + ObjectProperty<Duration> positionProperty; private ObjectProperty<Duration> durationProperty; private boolean isLoaded; - private static Thread positionThread; - private static List<NativeAudioMacHandler> playedHandlers = new ArrayList<>(); - - static { - positionThread = new Thread(() -> - { - while (true) { - try { - if (playedHandlers.isEmpty()) { - synchronized (positionThread) { - positionThread.wait(); - } - } - - for (Iterator<NativeAudioMacHandler> iterator = playedHandlers.iterator(); iterator.hasNext();) { - NativeAudioMacHandler handler = iterator.next(); - Duration seconds = Duration.seconds(NativeAudio.getPosition(handler.id)); - - Platform.runLater(() -> handler.positionProperty.set(seconds)); - } + private DoubleProperty leftPeak; + private DoubleProperty rightPeak; - Thread.sleep(SLEEP_TIME_POSITION); - } catch (InterruptedException e) { - } catch (ConcurrentModificationException e) { - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - - positionThread.start(); - } - public NativeAudioMacHandler(PadContent content) { super(content); id = counter++; positionProperty = new SimpleObjectProperty<>(); - durationProperty = new SimpleObjectProperty<>(); + durationProperty = new SimpleObjectProperty<>(); + + leftPeak = new SimpleDoubleProperty(); + rightPeak = new SimpleDoubleProperty(); } - + protected int getId() { return id; } @@ -76,33 +46,16 @@ public class NativeAudioMacHandler extends AudioHandler { public void play() { NativeAudio.setLoop(id, getContent().getPad().getPadSettings().isLoop()); NativeAudio.play(id); - - boolean start = false; - if (playedHandlers.isEmpty()) { - start = true; - } - - if (!playedHandlers.contains(this)) - playedHandlers.add(this); - if (start) { - synchronized (positionThread) { - positionThread.notify(); - } - } } @Override public void pause() { NativeAudio.pause(id); - if (playedHandlers.contains(this)) - playedHandlers.remove(this); } @Override public void stop() { NativeAudio.stop(id); - if (playedHandlers.contains(this)) - playedHandlers.remove(this); } @Override @@ -165,4 +118,19 @@ public class NativeAudioMacHandler extends AudioHandler { public void unloadMedia() { NativeAudio.dispose(id); } + + @Override + public DoubleProperty audioLevelProperty(Channel channel) { + if (channel == Channel.LEFT) { + return leftPeak; + } else if (channel == Channel.RIGHT) { + return rightPeak; + } + return null; + } + + @Override + public double getAudioLevel(Channel channel) { + return audioLevelProperty(channel).get(); + } } diff --git a/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java index 6b70456a..077eb06e 100644 --- a/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java +++ b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java @@ -5,9 +5,11 @@ import java.util.HashMap; import de.tobias.playpad.NativeAudio.NativeAudioDelegate; import de.tobias.playpad.audio.AudioHandler; import de.tobias.playpad.audio.AudioHandlerConnect; +import de.tobias.playpad.audio.Peakable.Channel; import de.tobias.playpad.pad.PadStatus; import de.tobias.playpad.pad.conntent.PadContent; import de.tobias.playpad.viewcontroller.AudioHandlerViewController; +import javafx.util.Duration; public class NativeAudioMacHandlerConnect extends AudioHandlerConnect implements NativeAudioDelegate { @@ -45,4 +47,21 @@ public class NativeAudioMacHandlerConnect extends AudioHandlerConnect implements } } } + + @Override + public void onPositionChanged(int id, double position) { + NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id); + if (nativeAudioMacHandler != null) { + nativeAudioMacHandler.positionProperty.set(Duration.seconds(position)); + } + } + + @Override + public void onPeakMeter(int id, float left, float right) { + NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id); + if (nativeAudioMacHandler != null) { + nativeAudioMacHandler.audioLevelProperty(Channel.LEFT).set(left); + nativeAudioMacHandler.audioLevelProperty(Channel.RIGHT).set(right); + } + } } -- GitLab