r678 - in trunk: sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util
Author: sbavencoff Date: 2014-05-26 11:22:15 +0200 (Mon, 26 May 2014) New Revision: 678 Url: http://forge.codelutin.com/projects/sammoa/repository/revisions/678 Log: refs #4762 : add vu-metre in onBoardBar (and audio test) for feedback audio Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioLevel.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/SoundMeter.java Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.css trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.jaxx trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanel.jaxx Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioLevel.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioLevel.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioLevel.java 2014-05-26 09:22:15 UTC (rev 678) @@ -0,0 +1,76 @@ +package fr.ulr.sammoa.application.device.audio; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.TargetDataLine; + +/** + * @author Sylvain Bavencoff <bavencoff@codelutin.com> + */ +public class AudioLevel { + + private static final Log log = LogFactory.getLog(AudioLevel.class); + + protected static final AudioFormat AUDIO_FORMAT = new AudioFormat(8000.0f, 8, 1, true, true); + + protected static final int SAMPLE_LENGTH = 1000; + + protected static final float ATTENUATION = 90; + + protected TargetDataLine line; + + byte[] audioData; + + public AudioLevel () throws LineUnavailableException { + + DataLine.Info dataLineInfo = new DataLine.Info( + TargetDataLine.class, AUDIO_FORMAT); + + audioData = new byte[SAMPLE_LENGTH]; + + + line = (TargetDataLine) AudioSystem.getLine(dataLineInfo); + + line.open(); + line.start(); + + } + + public float getLevel() { + line.read(audioData, 0, audioData.length); + long lSum = 0; + + for(byte sample : audioData) { + lSum = lSum + sample; + } + + double dAvg = lSum / audioData.length; + + double sumMeanSquare = 0d; + + for(byte sample : audioData) { + sumMeanSquare = sumMeanSquare + Math.pow(sample - dAvg, 2d); + } + + double averageMeanSquare = sumMeanSquare / audioData.length; + + float level = (float) Math.pow(averageMeanSquare,0.5d) / ATTENUATION; + + if (log.isDebugEnabled()) { + log.debug("level : " + level /*+ " | audioData : " + Arrays.toString(audioData)*/); + } + + return level; + } + + public void stop() { + line.stop(); + line.close(); + } + +} Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java 2014-05-23 06:46:55 UTC (rev 677) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java 2014-05-26 09:22:15 UTC (rev 678) @@ -28,6 +28,7 @@ import fr.ulr.sammoa.application.device.audio.SammoaAudioRecorder; import fr.ulr.sammoa.ui.swing.flight.bar.validation.SoundPlayer; import fr.ulr.sammoa.ui.swing.util.SammoaUtil; +import fr.ulr.sammoa.ui.swing.util.SoundMeter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,6 +83,8 @@ /** delay par defaut de chevauchement d'enregistrement */ protected int delay = 0; + protected SoundMeter audioMeter = new SoundMeter(); + protected JTextField filenameField = new JTextField("Test.wav"); protected JTextArea informationArea = new JTextArea(); @@ -119,7 +122,10 @@ Box buttons = Box.createHorizontalBox(); buttons.add(captureBtn); buttons.add(stopBtn); + buttons.add(audioMeter); + audioMeter.start(); + Box box = Box.createVerticalBox(); box.add(filenameField); box.add(buttons); @@ -227,6 +233,7 @@ if (recorder != null) { recorder.close(); } + audioMeter.stop(); } }); } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2014-05-23 06:46:55 UTC (rev 677) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2014-05-26 09:22:15 UTC (rev 678) @@ -709,6 +709,10 @@ initMap(); timeLog.log(startTime, "afterInitUI", "map is initialized"); + + if (ui.getFlightBar() instanceof OnBoardBar) { + ((OnBoardBar)ui.getFlightBar()).getAudioMeter().start(); + } } @Override @@ -716,6 +720,10 @@ transectUi.removeComponentListener(transectUIListener); flightController.close(); + if (ui.getFlightBar() instanceof OnBoardBar) { + ((OnBoardBar)ui.getFlightBar()).getAudioMeter().stop(); + } + try { context.closeService(flightController); } catch (IOException e) { Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.css =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.css 2014-05-23 06:46:55 UTC (rev 677) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.css 2014-05-26 09:22:15 UTC (rev 678) @@ -76,6 +76,10 @@ background: {model.getEffortPanelColor()}; } +#audioPanel { + background: {model.getEffortPanelColor()}; +} + #gpsLED { text: "sammoa.statusBar.gps"; } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.jaxx =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.jaxx 2014-05-23 06:46:55 UTC (rev 677) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/onBoard/OnBoardBar.jaxx 2014-05-26 09:22:15 UTC (rev 678) @@ -30,6 +30,7 @@ jaxx.runtime.swing.ClockWidget fr.ulr.sammoa.ui.swing.flight.FlightUIModel + fr.ulr.sammoa.ui.swing.util.SoundMeter </import> <script><![CDATA[ @@ -87,7 +88,11 @@ <cell fill='horizontal' weightx='0.2' anchor='center'> <JPanel id='cbPanel' layout='{new BoxLayout(cbPanel, BoxLayout.Y_AXIS)}'> <DeviceStateLED id='gpsLED' /> - <DeviceStateLED id='audioLED' /> + <JPanel id='audioPanel' layout='{new BoxLayout(audioPanel, BoxLayout.X_AXIS)}'> + <DeviceStateLED id='audioLED' /> + <SoundMeter id='audioMeter' /> + </JPanel> + </JPanel> </cell> <cell fill='vertical'> Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanel.jaxx =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanel.jaxx 2014-05-23 06:46:55 UTC (rev 677) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanel.jaxx 2014-05-26 09:22:15 UTC (rev 678) @@ -168,28 +168,24 @@ </row> <row> <cell fill='both' weightx='1.0' weighty='1.0' columns='4'> - <JSplitPane> - <JScrollPane id='observationTableScroll'> - <JXTable id='observationTable' /> - </JScrollPane> - <JScrollPane id='geoPointTableScroll'> - <JXTable id='geoPointTable'/> - </JScrollPane> - </JSplitPane> + <JScrollPane id='observationTableScroll'> + <JXTable id='observationTable' /> + </JScrollPane> </cell> </row> </Table> </cell> </row> </Table> - - <JPanel id='validationTable' layout='{new BorderLayout()}'> - - <JScrollPane id='scrollPanel' constraints='BorderLayout.CENTER'> - - <JXTable id='errorTable'/> + <JSplitPane> + <JScrollPane id='geoPointTableScroll'> + <JXTable id='geoPointTable'/> </JScrollPane> + <JPanel id='validationTable' layout='{new BorderLayout()}'> + <JScrollPane id='scrollPanel' constraints='BorderLayout.CENTER'> + <JXTable id='errorTable'/> + </JScrollPane> + </JPanel> + </JSplitPane> - </JPanel> - </JSplitPane> \ No newline at end of file Added: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/SoundMeter.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/SoundMeter.java (rev 0) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/SoundMeter.java 2014-05-26 09:22:15 UTC (rev 678) @@ -0,0 +1,104 @@ +package fr.ulr.sammoa.ui.swing.util; + +import fr.ulr.sammoa.application.SammoaTechnicalException; +import fr.ulr.sammoa.application.device.audio.AudioLevel; + +import javax.sound.sampled.LineUnavailableException; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Sylvain Bavencoff <bavencoff@codelutin.com> + */ +public class SoundMeter extends JPanel { + + protected static final Color LEVEL_COLOR = new Color(0, 228, 0); + + protected static final Color WARNING_COLOR = new Color(253, 253, 0); + + protected static final Color SATURATE_COLOR = new Color(228, 0, 0); + + protected static final float WARNING_LEVEL = 0.85f; + + protected static final float SATURATE_LEVEL = 0.92f; + + protected static final int REFRESH_TIME = 100; + + protected AudioLevel audioLevel; + + protected float level; + + protected Timer timer; + + public SoundMeter() { + try { + audioLevel = new AudioLevel(); + } catch (LineUnavailableException e) { + throw new SammoaTechnicalException(e); + } + + timer = new Timer (REFRESH_TIME, new ActionListener(){ + public void actionPerformed (ActionEvent e) { + if (audioLevel != null) { + level = audioLevel.getLevel(); + } + repaint(); + } + }); + + setBorder(BorderFactory.createLoweredBevelBorder()); + } + + public void start() { + timer.start(); + } + + public void stop() { + audioLevel.stop(); + timer.stop(); + level = 0; + repaint(); + } + + public void paint (Graphics g) { + super.paint(g); + + Dimension d = getSize(); + + int borderThickness = 2; + + int height = d.height - (borderThickness * 2); + int width = d.width - (borderThickness * 2); + + if (level > 0) { + if (level >= SATURATE_LEVEL) { + g.setColor(SATURATE_COLOR); + } else if (level >= WARNING_LEVEL) { + g.setColor(WARNING_COLOR); + } else { + g.setColor(LEVEL_COLOR); + } + + int widthLevel = (int) (level * (float) width); + g.fillRect(borderThickness, borderThickness, widthLevel, height); + } + + // echele + g.setColor(Color.black); + for (int step = 1; step < 10; step++) { + int x = borderThickness + step * width / 10; + g.drawLine(x, borderThickness + height * 3 / 4, x, borderThickness + height); + } + + g.setColor(WARNING_COLOR); + int x = borderThickness + (int) (WARNING_LEVEL * width); + g.drawLine(x, borderThickness, x, borderThickness + height); + + g.setColor(SATURATE_COLOR); + x = borderThickness + (int) (SATURATE_LEVEL * width); + g.drawLine(x, borderThickness, x, borderThickness + height); + } + +}
participants (1)
-
sbavencoffļ¼ users.forge.codelutin.com