Sammoa-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- 446 discussions
r525 - in trunk: sammoa-application/src/main/java/fr/ulr/sammoa/application/device sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar sammoa-ui-swing/src/main/resources/i18n
by fdesbois@users.forge.codelutin.com 05 Sep '12
by fdesbois@users.forge.codelutin.com 05 Sep '12
05 Sep '12
Author: fdesbois
Date: 2012-09-05 16:04:06 +0200 (Wed, 05 Sep 2012)
New Revision: 525
Url: http://forge.codelutin.com/repositories/revision/sammoa/525
Log:
refs #1197 : integration of audio reader / recorder
Added:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioPositionListener.java
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/bar/SoundPlayer.java
Removed:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReader.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.css
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.jaxx
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBarHandler.java
trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -29,9 +29,10 @@
import com.google.common.collect.Sets;
import fr.ulr.sammoa.application.SammoaServiceSupport;
import fr.ulr.sammoa.application.device.audio.AudioConfig;
+import fr.ulr.sammoa.application.device.audio.AudioPositionListener;
import fr.ulr.sammoa.application.device.audio.AudioReader;
-import fr.ulr.sammoa.application.device.audio.AudioReaderMock;
import fr.ulr.sammoa.application.device.audio.AudioRecorder;
+import fr.ulr.sammoa.application.device.audio.SammoaAudioReader;
import fr.ulr.sammoa.application.device.audio.SammoaAudioRecorder;
import fr.ulr.sammoa.application.device.gps.GpsConfig;
import fr.ulr.sammoa.application.device.gps.GpsHandler;
@@ -151,7 +152,7 @@
@Override
public AudioRecorder get() {
-// return new AudioRecorderDefault();
+// return new AudioRecorderDefault(config);
return new SammoaAudioRecorder(config);
}
});
@@ -163,13 +164,30 @@
AudioReader oldInstance = getDeviceManager(AudioReader.class);
+ Set<AudioPositionListener> positionListeners;
+ if (oldInstance != null) {
+
+ // Remove all existing listeners and keep them for the new instance
+ positionListeners = Sets.newHashSet(oldInstance.getAudioPositionListeners());
+ for (AudioPositionListener listener : positionListeners) {
+ oldInstance.removeAudioPositionListener(listener);
+ }
+
+ } else {
+ positionListeners = Sets.newHashSet();
+ }
+
AudioReader result = newDeviceManager(oldInstance, new Supplier<AudioReader>() {
@Override
public AudioReader get() {
- return new AudioReaderMock(config);
+ return new SammoaAudioReader();
}
});
+
+ for (AudioPositionListener listener : positionListeners) {
+ result.addAudioPositionListener(listener);
+ }
return result;
}
Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioPositionListener.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioPositionListener.java (rev 0)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioPositionListener.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -0,0 +1,23 @@
+package fr.ulr.sammoa.application.device.audio;
+
+/**
+ * Permet de se mettre listener sur l'avancement de la lecture du fichier
+ * <p/>
+ * Created: 05/09/12
+ *
+ * @author fdesbois <florian.desbois(a)codelutin.com>
+ */
+public interface AudioPositionListener {
+
+ /**
+ * @param source La source de l'evenement
+ * @param audioPosition la nouvelle position en milliseconds
+ */
+ public void positionChanged(AudioReader source, long audioPosition);
+
+ /**
+ * @param source La source de l'evenement
+ * @param audioLength la nouvelle taille en milliseconds
+ */
+ public void audioChanged(AudioReader source, long audioLength);
+}
Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioPositionListener.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReader.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReader.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReader.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -27,6 +27,7 @@
import javax.sound.sampled.AudioFileFormat;
import java.io.File;
+import java.util.Set;
/**
* Created: 21/08/12
@@ -53,4 +54,9 @@
/** @return current audio position in milliseconds */
long getPosition();
+ void addAudioPositionListener(AudioPositionListener listener);
+
+ void removeAudioPositionListener(AudioPositionListener listener);
+
+ Set<AudioPositionListener> getAudioPositionListeners();
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -32,6 +32,7 @@
import javax.sound.sampled.AudioFileFormat;
import java.io.File;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -48,6 +49,7 @@
protected DeviceState state = DeviceState.UNAVAILABLE;
protected Set<DeviceStateListener> listeners = Sets.newHashSet();
+ protected Set<AudioPositionListener> audioPositionListener = new HashSet<AudioPositionListener>();
public AudioReaderMock(AudioConfig config) {
this.config = config;
@@ -140,4 +142,19 @@
public Set<DeviceStateListener> getDeviceStateListeners() {
return listeners;
}
+
+ @Override
+ public void addAudioPositionListener(AudioPositionListener listener) {
+ audioPositionListener.add(listener);
+ }
+
+ @Override
+ public void removeAudioPositionListener(AudioPositionListener listener) {
+ audioPositionListener.remove(listener);
+ }
+
+ @Override
+ public Set<AudioPositionListener> getAudioPositionListeners() {
+ return audioPositionListener;
+ }
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -115,6 +115,7 @@
DEFAULT_BIG_ENDIAN
), DEFAULT_OUTPUT_TYPE);
+ this.config = config;
}
public AudioRecorderDefault(AudioFormat audioFormat,
Deleted: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -1,328 +0,0 @@
-package fr.ulr.sammoa.application.device.audio;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.IOException;
-import javax.sound.sampled.LineUnavailableException;
-import javax.sound.sampled.UnsupportedAudioFileException;
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Petite application de test de l'audio. Elle permet de choisir differente
- * configuration audio. De faire des enregistrements et de relire le fichier
- * enregistre.
- * <p>
- * La configuration choisi est inscrite et permet de la copier dans le fichier
- * de configuration
- * <p>
- * Si la machine ne supporte pas deux enregistrement simultane, delay est mis
- * a 0.
- *
- * Created: 27 aout 2012
- *
- * @author Benjamin POUSSIN <poussin(a)codelutin.com>
- * @version $Revision$
- *
- * Last update: $Date$
- * by : $Author$
- */
-public class AudioTest extends JFrame {
-
- private static final Logger logger = LoggerFactory.getLogger(AudioTest.class);
-
- protected SammoaAudioRecorder recorder;
- /** delay par defaut de chevauchement d'enregistrement */
- protected int delay = 0;
-
- protected JTextField filenameField = new JTextField("/tmp/junkk.wav");
- protected JTextArea informationArea = new JTextArea();
-
- protected JButton captureBtn = new JButton("Capture");
- protected JButton stopBtn = new JButton("Stop");
- protected JButton loadBtn = new JButton("Load");
- protected SoundPlayer playerPanel = new SoundPlayer();
-
- protected JPanel btnPanelSampleRate = new JPanel();
- protected ButtonGroup btnGroupSampleRate = new ButtonGroup();
- JRadioButton[] btnSampleRate = new JRadioButton[]{
- new JRadioButton("8000",true),
- new JRadioButton("11025"),
- new JRadioButton("16000"),
- new JRadioButton("22050"),
- new JRadioButton("44100")
- };
-
- protected JPanel btnPanelSampleSizeInBits = new JPanel();
- protected ButtonGroup btnGroupSampleSizeInBits = new ButtonGroup();
- JRadioButton[] btnSampleSizeInBits = new JRadioButton[]{
- new JRadioButton("8"),
- new JRadioButton("16",true)
- };
-
- public AudioTest(){//constructor
- initUI();
- testMultiRecord();
- }
-
- protected void initUI () {
- Box buttons = Box.createHorizontalBox();
- buttons.add(captureBtn);
- buttons.add(stopBtn);
-
- Box box = Box.createVerticalBox();
- box.add(filenameField);
- box.add(buttons);
-
- for (JRadioButton b : btnSampleRate) {
- //Include the radio buttons in a group
- btnGroupSampleRate.add(b);
- //Add the radio buttons to the JPanel
- btnPanelSampleRate.add(b);
- b.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- updateConfigInfo();
- }
- });
- }
-
- //Put the JPanel in the JFrame
- box.add(btnPanelSampleRate);
-
- for (JRadioButton b : btnSampleSizeInBits) {
- //Include the radio buttons in a group
- btnGroupSampleSizeInBits.add(b);
- //Add the radio buttons to the JPanel
- btnPanelSampleSizeInBits.add(b);
- b.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- updateConfigInfo();
- }
- });
- }
-
- //Put the JPanel in the JFrame
- box.add(btnPanelSampleSizeInBits);
-
- informationArea.setBorder(BorderFactory.createRaisedBevelBorder());
- informationArea.setLineWrap(true);
- box.add(informationArea);
- box.add(loadBtn);
- box.add(playerPanel);
-
- //Finish the GUI and make visible
- setTitle("Sound Test");
- setDefaultCloseOperation(EXIT_ON_CLOSE);
- getContentPane().add(box, "Center");
- pack();
- setVisible(true);
-
- captureBtn.setEnabled(true);
- stopBtn.setEnabled(false);
-
- // ADD LISTENER
-
- //Register anonymous listeners
- captureBtn.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- captureBtn.setEnabled(false);
- stopBtn.setEnabled(true);
- captureAudio();
- }
- });
-
- stopBtn.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- captureBtn.setEnabled(true);
- stopBtn.setEnabled(false);
- recorder.stop();
- }
- });
-
- loadBtn.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- File file = new File(filenameField.getText());
- playerPanel.loadFile(file);
- }
- });
- }
-
- protected void captureAudio(){
- try{
- File file = new File(filenameField.getText());
- recorder = new SammoaAudioRecorder(getSampleRate(), getSampleSizeInBits(), 0);
- recorder.record(file, true);
- }catch (Exception eee) {
- logger.error("Can't capture audio", eee);
- }
- }
-
- protected float getSampleRate() {
- float result = 44100;
- for (JRadioButton b : btnSampleRate) {
- if (b.isSelected()) {
- result = Float.parseFloat(b.getText());
- }
- }
- return result;
- }
-
- protected int getSampleSizeInBits() {
- int result = 44100;
- for (JRadioButton b : btnSampleSizeInBits) {
- if (b.isSelected()) {
- result = Integer.parseInt(b.getText());
- }
- }
- return result;
- }
-
- protected void updateConfigInfo() {
- informationArea.setText(String.format(
- "sammoa.audio.recordDelayInSeconds=%s\n"
- + "sammoa.audio.sampleRate=%s\n"
- + "sammoa.audio.sampleSizeInBits=%s\n",
- delay, getSampleRate(), getSampleSizeInBits()));
- }
-
- protected void testMultiRecord() {
- try {
- File f1 = File.createTempFile("sammoa-test-", ".wav");
- f1.deleteOnExit();
- File f2 = File.createTempFile("sammoa-test-", ".wav");
- f2.deleteOnExit();
-
- SammoaAudioRecorder r1 = new SammoaAudioRecorder(8000, 16, 2);
- r1.record(f1, true);
-
- SammoaAudioRecorder r2 = new SammoaAudioRecorder(8000, 16, 2);
- r2.record(f2, true);
-
- r2.stop();
- r1.stop();
- delay = 5;
- } catch(Exception eee) {
- logger.error("Can't record multiple file in same time", eee);
- delay = 0;
- }
- updateConfigInfo();
- }
-
-
- public static void main( String args[])
- throws LineUnavailableException, UnsupportedAudioFileException, IOException {
- new AudioTest();
-
-// float sampleRate = 8000; // 8000,11025,16000,22050,44100
-// int sampleSizeInBits = 16; // 8,16
-//
-// int channels = 1; // 1,2
-// boolean signed = true; //true,false
-// boolean bigEndian = false; //true,false
-//
-// AudioFormat audioFormat = new AudioFormat(
-// sampleRate,
-// sampleSizeInBits,
-// channels,
-// signed,
-// bigEndian);
-//
-// DataLine.Info dataLineInfo = new DataLine.Info(
-// TargetDataLine.class, audioFormat);
-// {
-// TargetDataLine l1 = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
-// System.out.println("Line: " + l1);
-// System.out.println("Line: " + l1.getLineInfo());
-// l1.open(audioFormat);
-// l1.start();
-//
-// TargetDataLine l2 = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
-// System.out.println("Line: " + l2);
-// System.out.println("Line: " + l2.getLineInfo());
-// l2.open(audioFormat);
-// l1.start();
-// }
-// {
-// AudioFileFormat aff = AudioSystem.getAudioFileFormat(new File("/tmp/junkk.wav"));
-// System.out.println("File: "+ aff.toString());
-// AudioInputStream sourceAis = AudioSystem.getAudioInputStream(new File("/tmp/junkk.wav"));
-//
-// DataLine.Info clipInfo = new DataLine.Info(Clip.class, audioFormat);
-// Clip clip = (Clip)AudioSystem.getLine(clipInfo);
-//
-// AudioInputStream ais = AudioSystem.getAudioInputStream(audioFormat, sourceAis);
-//// clip.open(ais);
-//// clip.start();
-// }
-// {
-// File f = new File("/tmp/junkk.wav");
-// Player p = Manager.createRealizedPlayer(f.toURI().toURL());
-// p.start();
-//// p.set
-// }
-//
-// System.out.println("#############################################");
-// Line.Info[] sources = AudioSystem.getSourceLineInfo(new Line.Info(SourceDataLine.class));
-// Line.Info[] target = AudioSystem.getTargetLineInfo(new Line.Info(TargetDataLine.class));
-//
-// System.out.println("AudioFileTypes:" + Arrays.toString(AudioSystem.getAudioFileTypes()));
-//
-// System.out.println("mixer:" + Arrays.toString(AudioSystem.getMixerInfo()));
-// for(Mixer.Info i : AudioSystem.getMixerInfo()) {
-// Mixer mixer = AudioSystem.getMixer(i);
-// System.out.println("-----");
-// System.out.println("mixer:" + mixer + "("+mixer.isLineSupported(Port.Info.MICROPHONE)+")");
-// try {
-// mixer.open();
-// } catch (LineUnavailableException eee) {
-// System.out.println("Can't open mixer");
-// }
-// System.out.println("mixer:" + mixer + "("+mixer.isLineSupported(Port.Info.MICROPHONE)+")");
-//
-// System.out.println("mixer info: " + mixer.getLineInfo());
-// System.out.println("max line: " + mixer.getMaxLines(mixer.getLineInfo()));
-//
-// for (Line.Info li : mixer.getSourceLineInfo()) {
-// System.out.println("s line info: " + li + "("+mixer.getMaxLines(li)+")");
-// System.out.println("s line info: " + li.getLineClass());
-// }
-//
-// for (Line.Info li : mixer.getTargetLineInfo()) {
-// System.out.println("t line info: " + li + "("+mixer.getMaxLines(li)+")");
-// System.out.println("t line info: " + li.getLineClass());
-// }
-//
-// for (Line l : mixer.getSourceLines()) {
-// System.out.println("s line: " + l);
-// System.out.println("s line info: " + l.getLineInfo());
-// }
-// for (Line l : mixer.getTargetLines()) {
-// System.out.println("t line: " + l);
-// System.out.println("t line info: " + l.getLineInfo());
-// }
-// }
-// System.out.println("sources: " + Arrays.toString(sources));
-// System.out.println("target: " + Arrays.toString(target));
-
- }
-}
\ No newline at end of file
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -28,19 +28,20 @@
import fr.ulr.sammoa.application.device.DeviceStateEvent;
import fr.ulr.sammoa.application.device.DeviceStateListener;
import fr.ulr.sammoa.application.device.DeviceTechnicalException;
-import java.io.File;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
/**
* Classe permettant la lecture d'un fichier audio, et de ce deplace a une
@@ -72,18 +73,6 @@
protected Set<AudioPositionListener> audioPositionListener = new HashSet<AudioPositionListener>();
/**
- * Permet de se mettre listener sur l'avancement de la lecture du fichier
- */
- static public interface AudioPositionListener {
- /**
- *
- * @param source La source de l'evenement
- * @param audioPosition la nouvelle position en milliseconds
- */
- public void positionChange(Object source, long audioPosition);
- }
-
- /**
* Classe servant a surveiller l'avancement de la lecture
* et a prevenir les listeners
*/
@@ -113,7 +102,7 @@
long position = reader.getClip().getMicrosecondPosition()/1000L;
if (old != position) {
reader.audioPosition = position;
- reader.firePositionChange(position);
+ reader.firePositionChanged(position);
}
} else {
reader.stop();
@@ -189,6 +178,7 @@
}
// Get the clip length in microseconds and convert to milliseconds
audioLength = (int)(clip.getMicrosecondLength( )/1000);
+ fireAudioChanged(audioLength);
setState(DeviceState.READY);
logger.debug(String.format("Sound file '%s' loaded", file));
@@ -221,17 +211,23 @@
this.audioPosition = position;
if (old != position ) {
clip.setMicrosecondPosition(position * 1000L);
- firePositionChange(position);
+ firePositionChanged(position);
}
}
}
- protected void firePositionChange(long position) {
+ protected void firePositionChanged(long position) {
for (AudioPositionListener l : audioPositionListener) {
- l.positionChange(this, position);
+ l.positionChanged(this, position);
}
}
+ protected void fireAudioChanged(long length) {
+ for (AudioPositionListener l : audioPositionListener) {
+ l.audioChanged(this, length);
+ }
+ }
+
@Override
public long getPosition() {
return audioPosition;
@@ -302,14 +298,17 @@
return listeners;
}
+ @Override
public void addAudioPositionListener(AudioPositionListener listener) {
audioPositionListener.add(listener);
}
+ @Override
public void removeAudioPositionListener(AudioPositionListener listener) {
audioPositionListener.remove(listener);
}
+ @Override
public Set<AudioPositionListener> getAudioPositionListeners() {
return audioPositionListener;
}
Deleted: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -1,225 +0,0 @@
-package fr.ulr.sammoa.application.device.audio;
-
-import fr.ulr.sammoa.application.device.DeviceState;
-import fr.ulr.sammoa.application.device.DeviceStateEvent;
-import fr.ulr.sammoa.application.device.DeviceStateListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.File;
-import java.io.IOException;
-import javax.sound.sampled.LineUnavailableException;
-import javax.sound.sampled.UnsupportedAudioFileException;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.JButton;
-import javax.swing.JComponent;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JSlider;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-/**
- * Composant qui permet de charge un fichier audio et de le jouer. On peut se
- * placer ou l'on veut dans le fichier audio.
- *
- * usage:
- * <li> SoundPlayer sp = new SoundPlayer();
- * <li> panel.add(sp);
- * <li> sp.load(myFileWav);
- *
- * Created: 03 septembre 2012
- *
- * @author Benjamin POUSSIN <poussin(a)codelutin.com>
- * @version $Revision$
- *
- * Last update: $Date$
- * by : $Author$
- */
-public class SoundPlayer extends JComponent implements DeviceStateListener {
- protected SammoaAudioReader reader;
- protected boolean playing = false; // whether the sound is currently playing
-
- // The following fields are for the GUI
- protected JButton play; // The Play/Stop button
- protected JSlider progress; // Shows and sets current position in sound
- protected JLabel time; // Displays audioPosition as a number
- protected JLabel maxTime;
-
- // Create a SoundPlayer component for the specified file.
- public SoundPlayer() {
- initUI();
- initAudio();
- }
-
- protected void initUI() {
- // Now create the basic GUI
- play = new JButton("Play"); // Play/stop button
- progress = new JSlider(0, 0, 0); // Shows position in sound
- progress.setMajorTickSpacing(60000);
- progress.setMinorTickSpacing(10000);
- progress.setPaintTicks(true);
- progress.setPaintLabels(true);
-
- time = new JLabel("0"); // Shows position as a #
- maxTime = new JLabel("/0"); // Shows position as a #
-
- // put those controls in a row
- Box row = Box.createHorizontalBox( );
- row.add(play);
- row.add(progress);
- row.add(time);
- row.add(maxTime);
-
- // And add them to this component.
- setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
- this.add(row);
-
- // ADD LISTENER
-
- // When clicked, start or stop playing the sound
- play.addActionListener(new ActionListener( ) {
- public void actionPerformed(ActionEvent e) {
- if (playing) {
- stop( );
- } else {
- play( );
- }
- }
- });
-
- progress.addMouseListener(new MouseAdapter() {
- boolean inPlay = false;
-
- @Override
- public void mousePressed(MouseEvent e) {
- inPlay= playing;
- if (inPlay) {
- reader.stop();
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- int value = progress.getValue( );
- // Update the time label
- time.setText(value/1000 + "." + (value%1000)/100);
- // If we're not already there, skip there.
- if (value >= 0 && value <= reader.getLength()) {
- reader.setPosition(value);
- }
-
- if (inPlay) {
- reader.start();
- }
- }
- });
-
- // Whenever the slider value changes, update the time label.
- progress.addChangeListener(new ChangeListener( ) {
- public void stateChanged(ChangeEvent e) {
- int value = progress.getValue( );
- time.setText(value/1000 + "." + (value%1000)/100);
- }
- });
- }
-
- protected void initAudio() {
- reader = new SammoaAudioReader();
- reader.addDeviceStateListener(this);
- // on se met listener de l'avancee de la lecture
- reader.addAudioPositionListener(new SammoaAudioReader.AudioPositionListener() {
- public void positionChange(Object source, long audioPosition) {
- progress.setValue((int)audioPosition);
- }
- });
-
- }
-
- public void stateChanged(DeviceStateEvent event) {
- DeviceState state = event.getNewValue();
- if (state == DeviceState.RUNNING) {
- this.playing = true;
- play.setText("Stop");
- } else {
- this.playing = false;
- play.setText("Play");
- }
- }
-
- /**
- * Charge un nouveau fichier
- * @param f le fichier a charger
- */
- public void loadFile(File f) {
- getAudioReader().load(f);
- long value = getLength();
- progress.setMaximum((int)value);
- maxTime.setText("/" + value/1000 + "." + (value%1000)/100);
- }
-
- /**
- * retourne le lecture utilise par ce composant
- * @return
- */
- public SammoaAudioReader getAudioReader() {
- return reader;
- }
-
- /**
- * Donne la position actuelle de la lecture en milliseconde
- * @return
- */
- public long getPosition() {
- return getAudioReader().getPosition();
- }
-
- /**
- * Donne la longueur total du fichier en milliseconde
- * @return
- */
- public long getLength() {
- return getAudioReader().getLength();
- }
-
- /**
- * Start playing the sound at the current position
- */
- public void play() {
- getAudioReader().start();
- }
-
- /**
- * Stop playing the sound, but retain the current position
- */
- public void stop() {
- getAudioReader().stop();
- }
-
- // The main method just creates a SoundPlayer in a Frame and displays it
- public static void main(String[] args)
- throws IOException, UnsupportedAudioFileException, LineUnavailableException {
- SoundPlayer player;
-
- File file;
- if (args.length == 0) {
- file = new File("/tmp/junkk1.wav");
- } else {
- file = new File(args[0]);
- }
-
- // Create a SoundPlayer object to play the sound.
- player = new SoundPlayer();
- player.loadFile(file);
-
- // Put it in a window and play it
- JFrame f = new JFrame("SoundPlayer");
- f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- f.getContentPane().add(player, "Center");
- f.pack();
- f.setVisible(true);
- }
-
-}
\ No newline at end of file
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -87,17 +87,18 @@
DateTime previousTime = Dates.toDateTime(currentRoute.getBeginTime());
+ int position = (int) getAudioReader().getPosition() / 1000;
+
if (logger.isDebugEnabled()) {
- logger.debug(String.format("Get location after previousTime %1$tH:%1$tM:%1$tS.%1$tL",
- previousTime.toDate())
+ logger.debug(String.format("Get location after previousTime %1$tH:%1$tM:%1$tS.%1$tL (audio position = %2$d)",
+ previousTime.toDate(),
+ position)
);
}
- long position = getAudioReader().getPosition();
-
DateTime newTime;
if (position > 0) {
- newTime = previousTime.plus(position);
+ newTime = previousTime.plusSeconds(position);
} else {
newTime = new DateTime(previousTime);
Copied: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java (from rev 524, trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java)
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java (rev 0)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -0,0 +1,258 @@
+package fr.ulr.sammoa.ui.swing;
+
+import com.google.common.base.Throwables;
+import fr.ulr.sammoa.application.device.audio.SammoaAudioRecorder;
+import fr.ulr.sammoa.ui.swing.flight.bar.SoundPlayer;
+import fr.ulr.sammoa.ui.swing.util.SammoaUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+//import javax.media.CannotRealizeException;
+//import javax.media.NoPlayerException;
+
+/**
+ * Petite application de test de l'audio. Elle permet de choisir differente
+ * configuration audio. De faire des enregistrements et de relire le fichier
+ * enregistre.
+ * <p>
+ * La configuration choisi est inscrite et permet de la copier dans le fichier
+ * de configuration
+ * <p>
+ * Si la machine ne supporte pas deux enregistrement simultane, delay est mis
+ * a 0.
+ *
+ * Created: 27 aout 2012
+ *
+ * @author Benjamin POUSSIN <poussin(a)codelutin.com>
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class AudioCheck extends JFrame {
+
+ private static final Logger logger = LoggerFactory.getLogger(AudioCheck.class);
+
+ protected SammoaAudioRecorder recorder;
+ /** delay par defaut de chevauchement d'enregistrement */
+ protected int delay = 0;
+
+ protected JTextField filenameField = new JTextField("/tmp/junkk.wav");
+ protected JTextArea informationArea = new JTextArea();
+
+ protected JButton captureBtn = new JButton("Capture");
+ protected JButton stopBtn = new JButton("Stop");
+ protected JButton loadBtn = new JButton("Load");
+ protected SoundPlayer playerPanel = new SoundPlayer();
+
+ protected JPanel btnPanelSampleRate = new JPanel();
+ protected ButtonGroup btnGroupSampleRate = new ButtonGroup();
+ JRadioButton[] btnSampleRate = new JRadioButton[]{
+ new JRadioButton("8000",true),
+ new JRadioButton("11025"),
+ new JRadioButton("16000"),
+ new JRadioButton("22050"),
+ new JRadioButton("44100")
+ };
+
+ protected JPanel btnPanelSampleSizeInBits = new JPanel();
+ protected ButtonGroup btnGroupSampleSizeInBits = new ButtonGroup();
+ JRadioButton[] btnSampleSizeInBits = new JRadioButton[]{
+ new JRadioButton("8"),
+ new JRadioButton("16",true)
+ };
+
+ public AudioCheck(){//constructor
+ initUI();
+ checkMultiRecord();
+ }
+
+ protected void initUI () {
+ Box buttons = Box.createHorizontalBox();
+ buttons.add(captureBtn);
+ buttons.add(stopBtn);
+
+ Box box = Box.createVerticalBox();
+ box.add(filenameField);
+ box.add(buttons);
+
+ for (JRadioButton b : btnSampleRate) {
+ //Include the radio buttons in a group
+ btnGroupSampleRate.add(b);
+ //Add the radio buttons to the JPanel
+ btnPanelSampleRate.add(b);
+ b.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ updateConfigInfo();
+ }
+ });
+ }
+
+ //Put the JPanel in the JFrame
+ box.add(btnPanelSampleRate);
+
+ for (JRadioButton b : btnSampleSizeInBits) {
+ //Include the radio buttons in a group
+ btnGroupSampleSizeInBits.add(b);
+ //Add the radio buttons to the JPanel
+ btnPanelSampleSizeInBits.add(b);
+ b.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ updateConfigInfo();
+ }
+ });
+ }
+
+ //Put the JPanel in the JFrame
+ box.add(btnPanelSampleSizeInBits);
+
+ informationArea.setBorder(BorderFactory.createRaisedBevelBorder());
+ informationArea.setLineWrap(true);
+ box.add(informationArea);
+ box.add(loadBtn);
+ box.add(playerPanel);
+
+ //Finish the GUI and make visible
+ setTitle("Sound Test");
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
+ getContentPane().add(box, "Center");
+ pack();
+ setVisible(true);
+
+ captureBtn.setEnabled(true);
+ stopBtn.setEnabled(false);
+
+ // ADD LISTENER
+
+ //Register anonymous listeners
+ captureBtn.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ captureBtn.setEnabled(false);
+ stopBtn.setEnabled(true);
+ captureAudio();
+ }
+ });
+
+ stopBtn.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ captureBtn.setEnabled(true);
+ stopBtn.setEnabled(false);
+ recorder.stop();
+ }
+ });
+
+ loadBtn.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ File file = new File(filenameField.getText());
+ playerPanel.loadFile(file);
+ }
+ });
+ }
+
+ protected void captureAudio(){
+ try{
+ File file = new File(filenameField.getText());
+ recorder = new SammoaAudioRecorder(getSampleRate(), getSampleSizeInBits(), 0);
+ recorder.record(file, true);
+ }catch (Exception eee) {
+ logger.error("Can't capture audio", eee);
+ }
+ }
+
+ protected float getSampleRate() {
+ float result = 44100;
+ for (JRadioButton b : btnSampleRate) {
+ if (b.isSelected()) {
+ result = Float.parseFloat(b.getText());
+ }
+ }
+ return result;
+ }
+
+ protected int getSampleSizeInBits() {
+ int result = 44100;
+ for (JRadioButton b : btnSampleSizeInBits) {
+ if (b.isSelected()) {
+ result = Integer.parseInt(b.getText());
+ }
+ }
+ return result;
+ }
+
+ protected void updateConfigInfo() {
+ informationArea.setText(String.format(
+ "sammoa.audio.recordDelayInSeconds=%s\n"
+ + "sammoa.audio.sampleRate=%s\n"
+ + "sammoa.audio.sampleSizeInBits=%s\n",
+ delay, getSampleRate(), getSampleSizeInBits()));
+ }
+
+ protected void checkMultiRecord() {
+ SammoaAudioRecorder r1 = new SammoaAudioRecorder(8000, 16, 2);
+ SammoaAudioRecorder r2 = new SammoaAudioRecorder(8000, 16, 2);
+ try {
+ File f1 = File.createTempFile("sammoa-audioCheck-", ".wav");
+ f1.deleteOnExit();
+ File f2 = File.createTempFile("sammoa-audioCheck-", ".wav");
+ f2.deleteOnExit();
+
+ r1.record(f1, true);
+
+ r2.record(f2, true);
+
+ r1.stop();
+ r2.stop();
+ delay = 5;
+ SammoaUtil.showSuccessMessage(this, "The recording delay is set to " +
+ "5 seconds between each recording, " +
+ "you can update this value from" +
+ " configuration interface");
+ } catch(IOException ex) {
+ throw Throwables.propagate(ex);
+
+ } catch(LineUnavailableException ex) {
+ delay = 0;
+ logger.error("Can't record multiple file in same time", ex);
+ SammoaUtil.showErrorMessage(this, "Can't record multiple file in " +
+ "same time, 0 second delay " +
+ "between recording must be used");
+
+ } finally {
+ r1.close();
+ r2.close();
+ }
+ updateConfigInfo();
+ }
+
+
+ public static void main( String args[])
+ throws LineUnavailableException, UnsupportedAudioFileException, IOException {
+ new AudioCheck();
+ }
+}
\ No newline at end of file
Property changes on: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/AudioCheck.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css 2012-09-05 14:04:06 UTC (rev 525)
@@ -40,13 +40,20 @@
mnemonic:C;
}
-#menuHome {
+#menuFileHome {
text:"sammoa.action.home";
toolTipText:"sammoa.action.home.tip";
actionIcon:"home";
mnemonic:H;
}
+#menuFileAudioCheck {
+ text:"sammoa.action.audioCheck";
+ toolTipText:"sammoa.action.audioCheck.tip";
+ actionIcon:"sound";
+ mnemonic:A;
+}
+
#exit {
text:"sammoa.menu.exit";
toolTipText:"sammoa.menu.help.tip";
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx 2012-09-05 14:04:06 UTC (rev 525)
@@ -56,10 +56,12 @@
<!-- menu -->
<JMenuBar id='menu'>
<JMenu id='menuFile'>
- <JMenuItem id='menuHome'
+ <JMenuItem id='menuFileHome'
onActionPerformed="getHandler().showHome()"/>
<JMenuItem id='menuFileConfiguration'
onActionPerformed="getHandler().showConfig()"/>
+ <JMenuItem id='menuFileAudioCheck'
+ onActionPerformed="getHandler().showAudioCheck()"/>
<JSeparator/>
<JMenuItem id='exit'
onActionPerformed='getHandler().closeSammoa()'/>
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -427,6 +427,10 @@
helper.displayUI(ui, false);
}
+ public void showAudioCheck() {
+ new AudioCheck();
+ }
+
/**
* Reload the given device identified by its {@code deviceManagerClass} for
* {@code ui}.
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.css
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.css 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.css 2012-09-05 14:04:06 UTC (rev 525)
@@ -99,3 +99,7 @@
#lblSpeed {
text: {model.getSpeed()};
}
+
+#soundPlayer {
+ enabled: {flightUIModel.getTransectFlightEditBean() != null};
+}
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.jaxx
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.jaxx 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBar.jaxx 2012-09-05 14:04:06 UTC (rev 525)
@@ -51,15 +51,15 @@
<Table id='validationBar'>
<row>
- <cell fill='horizontal' weightx='0.2'>
+<!-- <cell fill='horizontal' weightx='0.2'>
<JPanel id='audioButtonPanel'
layout='{new BoxLayout(audioButtonPanel, BoxLayout.X_AXIS)}'>
<JButton id='startAudioButton'/>
<JButton id='stopAudioButton'/>
</JPanel>
- </cell>
+ </cell>-->
<cell fill='horizontal'>
- <JSlider id='audioSlider' enabled='false'/>
+ <SoundPlayer id='soundPlayer'/>
</cell>
<cell fill='horizontal' weightx='0.2'>
<JPanel id='validButtonPanel'
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBarHandler.java
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBarHandler.java 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/FlightBarHandler.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -24,6 +24,7 @@
*/
package fr.ulr.sammoa.ui.swing.flight.bar;
+import fr.ulr.sammoa.application.device.audio.AudioReader;
import fr.ulr.sammoa.application.device.audio.AudioRecorder;
import fr.ulr.sammoa.application.device.gps.GpsHandler;
import fr.ulr.sammoa.application.flightController.FlightController;
@@ -72,12 +73,17 @@
if (flightUIModel.isValidationMode()) {
// Put actionName for validation buttons
- ui.getStartAudioButton().putClientProperty("actionName", "startAudio");
- ui.getStopAudioButton().putClientProperty("actionName", "stopAudio");
+// ui.getStartAudioButton().putClientProperty("actionName", "startAudio");
+// ui.getStopAudioButton().putClientProperty("actionName", "stopAudio");
ui.getValidObservationButton().putClientProperty("actionName", "validObservation");
ui.getValidRouteButton().putClientProperty("actionName", "validRoute");
ui.getValidTransectButton().putClientProperty("actionName", "validTransect");
+ AudioReader audioReader = flightController.getDeviceManager(AudioReader.class);
+ ui.getSoundPlayer().setReader(audioReader);
+ audioReader.addDeviceStateListener(ui.getSoundPlayer());
+ audioReader.addAudioPositionListener(ui.getSoundPlayer());
+
} else {
// Remove the bar used only for validation
Copied: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/SoundPlayer.java (from rev 524, trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java)
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/SoundPlayer.java (rev 0)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/SoundPlayer.java 2012-09-05 14:04:06 UTC (rev 525)
@@ -0,0 +1,233 @@
+package fr.ulr.sammoa.ui.swing.flight.bar;
+
+import fr.ulr.sammoa.application.device.DeviceState;
+import fr.ulr.sammoa.application.device.DeviceStateEvent;
+import fr.ulr.sammoa.application.device.DeviceStateListener;
+import fr.ulr.sammoa.application.device.audio.AudioPositionListener;
+import fr.ulr.sammoa.application.device.audio.AudioReader;
+import fr.ulr.sammoa.application.device.audio.SammoaAudioReader;
+
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Composant qui permet de charge un fichier audio et de le jouer. On peut se
+ * placer ou l'on veut dans le fichier audio.
+ *
+ * usage:
+ * <li> SoundPlayer sp = new SoundPlayer();
+ * <li> panel.add(sp);
+ * <li> sp.load(myFileWav);
+ *
+ * Created: 03 septembre 2012
+ *
+ * @author Benjamin POUSSIN <poussin(a)codelutin.com>
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class SoundPlayer extends JComponent implements DeviceStateListener, AudioPositionListener {
+ protected AudioReader reader;
+ protected boolean playing = false; // whether the sound is currently playing
+
+ // The following fields are for the GUI
+ protected JButton play; // The Play/Stop button
+ protected JSlider progress; // Shows and sets current position in sound
+ protected JLabel time; // Displays audioPosition as a number
+ protected JLabel maxTime;
+
+ // Create a SoundPlayer component for the specified file.
+ public SoundPlayer() {
+ initUI();
+// initAudio();
+ }
+
+ protected void initUI() {
+ // Now create the basic GUI
+ play = new JButton("Play"); // Play/stop button
+ progress = new JSlider(0, 0, 0); // Shows position in sound
+ progress.setMajorTickSpacing(60000);
+ progress.setMinorTickSpacing(10000);
+ progress.setPaintTicks(true);
+ progress.setPaintLabels(true);
+
+ time = new JLabel("0"); // Shows position as a #
+ maxTime = new JLabel("/0"); // Shows position as a #
+
+ // put those controls in a row
+ Box row = Box.createHorizontalBox( );
+ row.add(play);
+ row.add(progress);
+ row.add(time);
+ row.add(maxTime);
+
+ // And add them to this component.
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ this.add(row);
+
+ // ADD LISTENER
+
+ // When clicked, start or stop playing the sound
+ play.addActionListener(new ActionListener( ) {
+ public void actionPerformed(ActionEvent e) {
+ if (playing) {
+ stop( );
+ } else {
+ play( );
+ }
+ }
+ });
+
+ progress.addMouseListener(new MouseAdapter() {
+ boolean inPlay = false;
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ inPlay= playing;
+ if (inPlay) {
+ reader.stop();
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ int value = progress.getValue( );
+ // Update the time label
+ time.setText(value/1000 + "." + (value%1000)/100);
+ // If we're not already there, skip there.
+ if (value >= 0 && value <= reader.getLength()) {
+ reader.setPosition(value);
+ }
+
+ if (inPlay) {
+ reader.start();
+ }
+ }
+ });
+
+ // Whenever the slider value changes, update the time label.
+ progress.addChangeListener(new ChangeListener( ) {
+ public void stateChanged(ChangeEvent e) {
+ int value = progress.getValue( );
+ time.setText(value/1000 + "." + (value%1000)/100);
+ }
+ });
+ }
+
+ @Override
+ public void stateChanged(DeviceStateEvent event) {
+ DeviceState state = event.getNewValue();
+ if (state == DeviceState.RUNNING) {
+ this.playing = true;
+ play.setText("Stop");
+ } else {
+ this.playing = false;
+ play.setText("Play");
+ }
+ }
+
+ @Override
+ public void positionChanged(AudioReader source, long audioPosition) {
+ progress.setValue((int) audioPosition);
+ }
+
+ @Override
+ public void audioChanged(AudioReader source, long audioLength) {
+ progress.setMaximum((int) audioLength);
+ maxTime.setText("/" + audioLength / 1000 + "." + (audioLength % 1000) / 100);
+ }
+
+ /**
+ * Charge un nouveau fichier
+ * @param f le fichier a charger
+ */
+ public void loadFile(File f) {
+ getAudioReader().load(f);
+ }
+
+ public void setReader(AudioReader reader) {
+ this.reader = reader;
+ }
+
+ /**
+ * retourne le lecture utilise par ce composant
+ * @return
+ */
+ public AudioReader getAudioReader() {
+ return reader;
+ }
+
+ /**
+ * Donne la position actuelle de la lecture en milliseconde
+ * @return
+ */
+ public long getPosition() {
+ return getAudioReader().getPosition();
+ }
+
+ /**
+ * Donne la longueur total du fichier en milliseconde
+ * @return
+ */
+ public long getLength() {
+ return getAudioReader().getLength();
+ }
+
+ /**
+ * Start playing the sound at the current position
+ */
+ public void play() {
+ getAudioReader().start();
+ }
+
+ /**
+ * Stop playing the sound, but retain the current position
+ */
+ public void stop() {
+ getAudioReader().stop();
+ }
+
+ // The main method just creates a SoundPlayer in a Frame and displays it
+ public static void main(String[] args)
+ throws IOException, UnsupportedAudioFileException, LineUnavailableException {
+ SoundPlayer player;
+
+ File file;
+ if (args.length == 0) {
+ file = new File("/tmp/junkk.wav");
+ } else {
+ file = new File(args[0]);
+ }
+
+ // Create a SoundPlayer object to play the sound.
+ player = new SoundPlayer();
+ AudioReader reader = new SammoaAudioReader();
+ reader.addDeviceStateListener(player);
+ reader.addAudioPositionListener(player);
+ player.setReader(reader);
+ player.loadFile(file);
+
+ // Put it in a window and play it
+ JFrame f = new JFrame("SoundPlayer");
+ f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ f.getContentPane().add(player, "Center");
+ f.pack();
+ f.setVisible(true);
+ }
+}
\ No newline at end of file
Property changes on: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/SoundPlayer.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties
===================================================================
--- trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-05 14:03:46 UTC (rev 524)
+++ trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-05 14:04:06 UTC (rev 525)
@@ -4,6 +4,8 @@
sammoa.action.about=About
sammoa.action.about.tip=About
sammoa.action.add.tip=ADD \: create a new LEG route for the current Transect (the observation conditions have changed)
+sammoa.action.audioCheck=
+sammoa.action.audioCheck.tip=
sammoa.action.begin=Begin
sammoa.action.begin.tip=BEGIN \: begin effort to create a new LEG route for the next selected Transect
sammoa.action.cancel=Cancel
1
0
r524 - in trunk: sammoa-application/src/main/java/fr/ulr/sammoa/application sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence sammoa-persistence/src/main/xmi sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action src/site
by fdesbois@users.forge.codelutin.com 05 Sep '12
by fdesbois@users.forge.codelutin.com 05 Sep '12
05 Sep '12
Author: fdesbois
Date: 2012-09-05 16:03:46 +0200 (Wed, 05 Sep 2012)
New Revision: 524
Url: http://forge.codelutin.com/repositories/revision/sammoa/524
Log:
refs #1197 : impact on next transect to avoid errors with audio files
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/FlightService.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java
trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/FlightImpl.java
trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/RouteDAOImpl.java
trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java
trunk/sammoa-persistence/src/main/xmi/sammoa.zargo
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/NextAction.java
trunk/src/site/site.xml
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/FlightService.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/FlightService.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/FlightService.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -689,6 +689,23 @@
return result;
}
+ protected TransectFlight getPreviousTransect(TopiaContext tx,
+ Route previousRoute)
+ throws TopiaException {
+
+ TransectFlight result;
+ if (previousRoute.getRouteType() == RouteType.LEG) {
+ result = previousRoute.getTransectFlight();
+
+ } else {
+
+ RouteDAO dao = SammoaDAOHelper.getRouteDAO(tx);
+ Route previousLEG = dao.findPreviousLEG(previousRoute);
+ result = previousLEG == null ? null : previousLEG.getTransectFlight();
+ }
+ return result;
+ }
+
public List<Observation> getObservations(Flight flight) {
TopiaContext transaction = beginTransaction();
@@ -1061,6 +1078,52 @@
return result;
}
+ public TransectFlight getNextTransectFlightFrom(TransectFlight transectFlight,
+ Flight flight,
+ Date beforeTime) {
+ TopiaContext tx = beginTransaction();
+ try {
+ TransectFlight result = getNextTransectFlightFrom(tx, transectFlight, flight, beforeTime);
+ return result;
+ } catch (TopiaException ex) {
+ throw new TopiaRuntimeException(ex);
+ } finally {
+ endTransaction(tx);
+ }
+ }
+
+ public TransectFlight getNextTransectFlightFrom(TopiaContext tx,
+ TransectFlight transectFlight,
+ Flight flight,
+ Date beforeTime)
+ throws TopiaException {
+
+ // Note that this may not reflect the real next transect if exists in routes
+
+ RouteDAO routeDAO = SammoaDAOHelper.getRouteDAO(tx);
+
+ // Skip previous elements
+ int numberToSkip;
+ if (transectFlight == null) {
+ numberToSkip = 0;
+ } else {
+ numberToSkip = flight.getTransectFlight().indexOf(transectFlight) + 1;
+ }
+ Iterable<TransectFlight> transectFlights = Iterables.skip(
+ flight.getTransectFlight(), numberToSkip);
+
+ // Return only if not deleted and doesn't have any route
+ for (TransectFlight element : transectFlights) {
+
+ if (!element.isDeleted()
+ && routeDAO.countByTransectFlightBeforeTime(element, beforeTime) == 0) {
+
+ return element;
+ }
+ }
+ return null;
+ }
+
public Flight getFlightByNaturalId(Map<String, Object> naturalId) {
TopiaContext tx = beginTransaction();
try {
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -78,7 +78,7 @@
protected TransectFlight nextTransect;
- protected TransectFlight lastTransect;
+ protected TransectFlight currentTransect;
protected final Set<FlightControllerListener> listeners;
@@ -203,14 +203,14 @@
Preconditions.checkState(
isWaiting(), "You can call start() only if flight is waiting (not started, not ended)");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
- setFlightBeginDate(transaction, flight, currentDate);
+ setFlightBeginDate(tx, flight, currentDate);
if (logger.isInfoEnabled()) {
logger.info("Start Flight {} at {}", flight.getFlightNumber(), flight.getBeginDate());
@@ -221,14 +221,14 @@
logger.info(String.format("Create TRANSIT [START] at %1$tH:%1$tM:%1$tS.%1$tL", currentDate));
}
Route previousRoute = currentRoute;
- currentRoute = service.createTransit(transaction, flight, currentDate, previousRoute);
+ currentRoute = service.createTransit(tx, flight, currentDate, previousRoute);
// Auto selection of the next transect starting from the begining
- nextTransect = flight.getNextTransectFlightFrom(null);
+ nextTransect = service.getNextTransectFlightFrom(tx, null, flight, currentRoute.getBeginTime());
state = FlightState.OFF_EFFORT;
- transaction.commitTransaction();
+ tx.commitTransaction();
startTime = timeLog.log(startTime, "start()", "Commited");
@@ -243,7 +243,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
}
@@ -288,7 +288,7 @@
currentRoute = newCurrentRoute;
- TransectFlight lastTransectOldValue = lastTransect;
+ TransectFlight currentTransectOldValue = currentTransect;
if (currentRoute == null) {
@@ -306,26 +306,27 @@
currentRoute = service.getPreviousRoute(newCurrentRoute);
}
- // Update state, lastTransect and nextTransect depends on routeType
+ TransectFlight previousTransect = service.getPreviousTransect(currentRoute);
+
+ // Update state, currentTransect and nextTransect depends on routeType
switch (currentRoute.getRouteType()) {
case LEG:
state = FlightState.ON_EFFORT;
- lastTransect = service.getPreviousTransect(currentRoute);
- nextTransect = flight.getNextTransectFlightFrom(lastTransect);
+ currentTransect = previousTransect;
+ nextTransect = service.getNextTransectFlightFrom(previousTransect, flight, currentRoute.getBeginTime());
break;
case CIRCLE_BACK:
state = FlightState.OFF_EFFORT;
- lastTransect = service.getPreviousTransect(currentRoute);
- nextTransect = lastTransect;
+ currentTransect = previousTransect;
+ nextTransect = previousTransect;
break;
case TRANSIT:
state = FlightState.OFF_EFFORT;
- lastTransect = null;
- nextTransect = flight.getNextTransectFlightFrom(
- service.getPreviousTransect(currentRoute));
+ currentTransect = null;
+ nextTransect = service.getNextTransectFlightFrom(previousTransect, flight, currentRoute.getBeginTime());
break;
default:
@@ -335,7 +336,7 @@
if (fireChanges) {
onStateChanged(state);
- onLastTransectChanged(lastTransectOldValue, lastTransect);
+ onCurrentTransectChanged(currentTransectOldValue, currentTransect);
onNextTransectChanged(nextTransect);
onCurrentRouteChanged(currentRoute);
}
@@ -358,36 +359,36 @@
nextTransect != null, "You can't call begin() if no transect is selected. " +
"Call setNextTransect() method first");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
- // The next transect becomes the last one (or current in this case)
- TransectFlight lastTransectOldValue = lastTransect;
- lastTransect = nextTransect;
+ // The current transect becomes the next one
+ TransectFlight previousTransect = currentTransect;
+ currentTransect = nextTransect;
// Create new LEG route
if (logger.isInfoEnabled()) {
logger.info(String.format("Create LEG [BEGIN] at %1$tH:%1$tM:%1$tS.%1$tL", currentDate));
}
Route previousRoute = currentRoute;
- currentRoute = service.createLeg(transaction, flight, currentDate, previousRoute, lastTransect);
+ currentRoute = service.createLeg(tx, flight, currentDate, previousRoute, currentTransect);
// automatic selection of the next transect
- nextTransect = flight.getNextTransectFlightFrom(lastTransect);
+ nextTransect = service.getNextTransectFlightFrom(tx, currentTransect, flight, currentRoute.getBeginTime());
state = FlightState.ON_EFFORT;
- transaction.commitTransaction();
+ tx.commitTransaction();
startTime = timeLog.log(startTime, "begin()", "Commited");
// Fire events after commit
onRouteAdded(previousRoute, currentRoute);
- onLastTransectChanged(lastTransectOldValue, lastTransect);
+ onCurrentTransectChanged(previousTransect, currentTransect);
onNextTransectChanged(nextTransect);
onStateChanged(state);
@@ -397,7 +398,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
}
@@ -415,27 +416,27 @@
"You can't call circleBack() during TRANSIT");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
- setObservationStatus(transaction, observation, ObservationStatus.CIRCLE_BACK);
+ setObservationStatus(tx, observation, ObservationStatus.CIRCLE_BACK);
// Create CIRCLE_BACK
if (logger.isInfoEnabled()) {
logger.info(String.format("Create CIRCLE_BACK at %1$tH:%1$tM:%1$tS.%1$tL", currentDate));
}
Route previousRoute = currentRoute;
- currentRoute = service.createCircleBack(transaction, flight, currentDate, previousRoute, observation);
+ currentRoute = service.createCircleBack(tx, flight, currentDate, previousRoute, observation);
- nextTransect = lastTransect;
+ nextTransect = currentTransect;
state = FlightState.OFF_EFFORT;
- transaction.commitTransaction();
+ tx.commitTransaction();
startTime = timeLog.log(startTime, "circleBack()", "Commited");
@@ -450,7 +451,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
}
@@ -465,10 +466,10 @@
Preconditions.checkState(
isOnEffort(), "You can call add() only if flight is on effort (started, not ended, on effort)");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
@@ -477,9 +478,9 @@
logger.info(String.format("Create LEG [ADD] at %1$tH:%1$tM:%1$tS.%1$tL", currentDate));
}
Route previousRoute = currentRoute;
- currentRoute = service.createLeg(transaction, flight, currentDate, previousRoute, lastTransect);
+ currentRoute = service.createLeg(tx, flight, currentDate, previousRoute, currentTransect);
- transaction.commitTransaction();
+ tx.commitTransaction();
startTime = timeLog.log(startTime, "add()", "Commited");
@@ -492,7 +493,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
}
@@ -521,32 +522,22 @@
Preconditions.checkState(
isRunning(), "You can call observation() only if flight is running (started, not ended)");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
-// ObserverPosition observer;
-// if (currentRoute == null) {
-//
-// // problem we don't have any observerPosition
-// observer = null;
-//
-// } else {
-// observer = currentRoute.getObserverPositionByPosition(position);
-// }
-
if (logger.isInfoEnabled()) {
logger.info(String.format("Create Observation %2$s at %1$tH:%1$tM:%1$tS.%1$tL",
currentDate,
position)
);
}
- Observation observation = service.createObservation(transaction, flight, currentDate, position);
+ Observation observation = service.createObservation(tx, flight, currentDate, position);
- transaction.commitTransaction();
+ tx.commitTransaction();
startTime = timeLog.log(startTime, "observation()", "Commited");
@@ -558,7 +549,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
}
@@ -573,30 +564,30 @@
Preconditions.checkState(
isOnEffort(), "You can call end() only if flight is on effort (started, not ended, on effort)");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
- TransectFlight lastTransectOldValue = lastTransect;
- lastTransect = null;
+ TransectFlight previousTransect = currentTransect;
+ currentTransect = null;
// Create new TRANSIT route
if (logger.isInfoEnabled()) {
logger.info(String.format("Create TRANSIT [END] at %1$tH:%1$tM:%1$tS.%1$tL", currentDate));
}
Route previousRoute = currentRoute;
- currentRoute = service.createTransit(transaction, flight, currentDate, previousRoute);
+ currentRoute = service.createTransit(tx, flight, currentDate, previousRoute);
state = FlightState.OFF_EFFORT;
- transaction.commitTransaction();
+ tx.commitTransaction();
// Fire events after commit
onRouteAdded(previousRoute, currentRoute);
- onLastTransectChanged(lastTransectOldValue, lastTransect);
+ onCurrentTransectChanged(previousTransect, currentTransect);
onNextTransectChanged(nextTransect);
onStateChanged(state);
@@ -604,7 +595,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
timeLog.log(startTime, "end()");
@@ -621,10 +612,10 @@
Preconditions.checkState(
isOffEffort() && flight.getEndDate() == null, "You can call stop() only if flight is running (started, not ended, not on effort)");
- TopiaContext transaction = beginTransaction();
+ TopiaContext tx = beginTransaction();
try {
- GeoPoint geoPoint = getLocation(transaction);
+ GeoPoint geoPoint = getLocation(tx);
Date currentDate = geoPoint.getRecordTime();
@@ -634,7 +625,7 @@
flight.getFlightNumber())
);
}
- setFlightEndDate(transaction, flight, currentDate);
+ setFlightEndDate(tx, flight, currentDate);
currentRoute = null;
@@ -642,7 +633,7 @@
state = FlightState.ENDED;
- transaction.commitTransaction();
+ tx.commitTransaction();
startTime = timeLog.log(startTime, "stop()", "Commited");
@@ -657,7 +648,7 @@
throw new TopiaRuntimeException(e);
} finally {
- endTransaction(transaction);
+ endTransaction(tx);
}
}
@@ -667,68 +658,36 @@
persistence.stopAutoSaveListener();
}
- protected void setFlightBeginDate(TopiaContext transaction,
+ protected void setFlightBeginDate(TopiaContext tx,
Flight flight,
Date beginDate)
throws TopiaException {
- FlightDAO flightDAO = SammoaDAOHelper.getFlightDAO(transaction);
+ FlightDAO flightDAO = SammoaDAOHelper.getFlightDAO(tx);
flight.setBeginDate(beginDate);
flightDAO.update(flight);
}
- protected void setFlightEndDate(TopiaContext transaction,
+ protected void setFlightEndDate(TopiaContext tx,
Flight flight,
Date endDate)
throws TopiaException {
- FlightDAO flightDAO = SammoaDAOHelper.getFlightDAO(transaction);
+ FlightDAO flightDAO = SammoaDAOHelper.getFlightDAO(tx);
flight.setEndDate(endDate);
flightDAO.update(flight);
}
- protected void setObservationStatus(TopiaContext transaction,
+ protected void setObservationStatus(TopiaContext tx,
Observation observation,
ObservationStatus status)
throws TopiaException {
ObservationDAO observationDAO =
- SammoaDAOHelper.getObservationDAO(transaction);
+ SammoaDAOHelper.getObservationDAO(tx);
observation.setObservationStatus(status);
observationDAO.update(observation);
}
-//
-// protected Date saveGPS(TopiaContext transaction)
-// throws TopiaException {
-//
-// GeoPoint geoPoint = gpsHandler.getCurrentLocation();
-//
-// Date result;
-// if (geoPoint == null) {
-// result = new Date();
-//
-// if (logger.isWarnEnabled()) {
-// logger.warn("No GPS point at {}", result);
-// }
-//
-// } else {
-//
-//// lastLocation = geoPoint;
-//
-// if (logger.isTraceEnabled()) {
-// logger.trace("Create GPS Point : {}", geoPoint);
-// }
-//
-// result = geoPoint.getRecordTime();
-//
-// GeoPointDAO dao = SammoaDAOHelper.getGeoPointDAO(transaction);
-//
-// geoPoint.setFlight(flight);
-//
-// dao.create(geoPoint);
-// }
-// return result;
-// }
protected DeviceManagerProvider getDeviceManagerProvider() {
if (deviceManagerProvider == null) {
@@ -771,7 +730,7 @@
}
}
- protected void onLastTransectChanged(TransectFlight oldValue, TransectFlight newValue) {
+ protected void onCurrentTransectChanged(TransectFlight oldValue, TransectFlight newValue) {
// no fire by default
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -125,10 +125,10 @@
}
@Override
- protected void onLastTransectChanged(TransectFlight oldValue,
- TransectFlight newValue) {
+ protected void onCurrentTransectChanged(TransectFlight oldValue,
+ TransectFlight newValue) {
- // Record audio for the lastTransect (also current one in case of LEG)
+ // Record audio for the currentTransect
if (!Objects.equal(oldValue, newValue)) {
@@ -144,7 +144,7 @@
}
}
- super.onLastTransectChanged(oldValue, newValue);
+ super.onCurrentTransectChanged(oldValue, newValue);
}
protected void restartAudio(AudioRecorder audioRecorder) {
@@ -152,7 +152,7 @@
|| currentRoute.getRouteType() == RouteType.CIRCLE_BACK) {
File audioFile = flightStorage.getAudioFile(
- lastTransect, audioRecorder.getOutputType().getExtension());
+ currentTransect, audioRecorder.getOutputType().getExtension());
audioRecorder.record(audioFile);
}
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -160,10 +160,10 @@
}
@Override
- protected void onLastTransectChanged(TransectFlight oldValue,
- TransectFlight newValue) {
+ protected void onCurrentTransectChanged(TransectFlight oldValue,
+ TransectFlight newValue) {
- // Read audio for the lastTransect (also current one in case of LEG)
+ // Read audio for the currentTransect
if (!Objects.equal(oldValue, newValue)) {
@@ -181,7 +181,7 @@
}
}
- super.onLastTransectChanged(oldValue, newValue);
+ super.onCurrentTransectChanged(oldValue, newValue);
}
protected AudioReader getAudioReader() {
Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/FlightImpl.java
===================================================================
--- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/FlightImpl.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/FlightImpl.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -24,10 +24,6 @@
*/
package fr.ulr.sammoa.persistence;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.Collection;
@@ -70,29 +66,6 @@
}
@Override
- public int getTransectFlightIndex(TransectFlight transectFlight) {
- int result = Iterables.indexOf(getTransectFlight(),
- Predicates.equalTo(transectFlight));
- return result;
- }
-
- @Override
- public TransectFlight getNextTransectFlightFrom(TransectFlight transectFlight) {
-
- // Get index of the transect
- int index = getTransectFlightIndex(transectFlight);
-
- // Find the first which is not started after skipping all previous ones
- Optional<TransectFlight> result =
- FluentIterable.from(getTransectFlight())
- .skip(index + 1)
- .firstMatch(TransectFlights.isNotDeleted());
-
-// TransectFlight result = Iterables.get(getTransectFlight(), index + 1, null);
- return result.orNull();
- }
-
- @Override
public Collection<Observer> getObserver() {
if (observer == null) {
observer = Lists.newArrayList();
Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/RouteDAOImpl.java
===================================================================
--- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/RouteDAOImpl.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/RouteDAOImpl.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -26,6 +26,7 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.TopiaRuntimeException;
+import java.util.Date;
import java.util.List;
/**
@@ -133,4 +134,20 @@
}
}
+ public long countByTransectFlightBeforeTime(TransectFlight transectFlight,
+ Date time) {
+
+ String ql = "SELECT count(*) " +
+ "FROM RouteImpl " +
+ "WHERE transectFlight = :transectFlight " +
+ "AND beginTime < :beginTime";
+
+ try {
+ long result = countByQuery(ql, "transectFlight", transectFlight, "beginTime", time);
+ return result;
+ } catch (TopiaException e) {
+ throw new TopiaRuntimeException(e);
+ }
+ }
+
}
Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java
===================================================================
--- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -25,7 +25,6 @@
import com.google.common.base.Function;
import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Sets;
import org.nuiton.validator.bean.list.BeanListValidator;
@@ -69,10 +68,6 @@
return result;
}
- public static Predicate<TransectFlight> isNotDeleted() {
- return Predicates.not(isDeleted());
- }
-
public static Predicate<TransectFlight> isDeleted() {
return IS_DELETED_PREDICATE;
}
Modified: trunk/sammoa-persistence/src/main/xmi/sammoa.zargo
===================================================================
--- trunk/sammoa-persistence/src/main/xmi/sammoa.zargo 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-persistence/src/main/xmi/sammoa.zargo 2012-09-05 14:03:46 UTC (rev 524)
@@ -1,7 +1,9 @@
-PK(�Asammoa.argo�TK��0�ﯰr��l�B��.�bϕO���8��zƱ�8}����JQ5��y�̔\7��@T�*{�Uw��Bծ��rK�G�ζJ����,#e��(Ot�#T���weq�'���)c�(��+
+PK]Z%Asammoa.argo�TK��0�ﯰr��l�B��.�bϕO���8��zƱ�8}����JQ5��y�̔\7��@T�*{�Uw��Bծ��rK�G�ζJ����,#e��(Ot�#T���weq�'���)c�(��+
X�}c��^N�q�������)��V�7J
_���\(�9��@�PJ�= ����j�V�����N���%�C�H�N��I����L<�'9�h���R���Vh��I�Ijì�`O���A4��^�I��*p�����G[N�i�P�=
-�V�Ch��(`�5��18��!F��NݹU�'��nP5eq&��/�����<��-�����휈3F��@ o4�|T���jIm�Q��j��tFh`��ہۖ�����ӷ�~�?=e�5t�7X�g�ʨ �(!��~��Uf(��Q���繟����{�������O�" �I~y"^�(XeJ7�߂����"��/굡~��Ӑ;�i�<�S1�U�!�k���%q#��]`���ǥ��Z��cI��zmQ�0��|Hr�W϶��ލ-oTe�P/t�HǑ*����c��?��(��z���PK/UgH�PK(�Asammoa_Diagrammedeclasses.pgml�]m��6���_�*{B� &����s�c����m��R�k�����[���w�;��H��lR�D��nR�D���F���t����q6�.��h���p�
+�V�Ch��(`�5��18��!F��NݹU�'��nP5eq&��/�����<��-�����휈3F��@ o4�|T���jIm�&o�g&���v�e���*�����LJ��OO+FM݆4F
+�2j�-J�☆��y��E�uT�Ge�y��g��}䞽~nh:�B�ӝ�7�_���3
+V��M�w��d����o�zm�j�4�s�%�Ts�m�����}I�gi�q{�qi�����Xҳ��^[7L��2���ճ-��wc�UY%�]<�q��d�h�����G<1�hx����7PK��DH�PK]Z%Asammoa_Diagrammedeclasses.pgml�]m��6���_�*{B� &����s�c����m��R�k�����[���w�;��H��lR�D��nR�D���F���t����q6�.��h���p�
��(O����rw��=����^�������}�<=�>�����σg�.ƫ�3~E��8\�ӧU�h�p1\<Dk~Q��x:|X/���j:�m�Z�G��"�XO/~����l�\^o���������sB�y��\/&s���q���<��A��W϶�z��������w��5/��i{������X�)�~�=��9��S��#��O��N���Y�j2�-���pF�oO�_������p1�����B�����j��ޯW��u:�/�p��[���!��l�"�y͢ūg�q�����g>���P�a������p�{�����O����*���{鏛��h5�?�B�\����W�8��?}�/w��?����uw�| �_V|�(��2���i�3On0�~;�U��J8���Sm�H8A�j�v��=�#6}?��d�̢��w��p6�z������h6V������3���z��N���f9]�s.��_�-��%�/����B�.ˋ�Q��ܬ����Z�?�/J�,J/��?��O�����U��L/�ཽ�^"/(mImU���%K�&�&)���w���fn�x��~�NU]k�ٚ����?�
�Y��Uh^��+��_f�����շ�<�?����}�4_��T�u�L�����L�Z���֔��\.�-�*z|.V�����������*����.J�a��/�UXs=�kR�]��`�h�vyNV�n���0�����AT)F�q ����.�{�V_8��њJwK��b��ip��o8�q��Kg��
x��]��
@@ -32,66 +34,68 @@
pS�\�mg3 ب�Pg���hKh�������k\�w��P��n��x��o
���K������41�A_|5�{�%����?�C/>�#�=�"���"�e>N��@-uT|eN��B`���h��W�C�(Ǽ�<�L��z�5�?�_��^DŇRcJY�����"z�"��Rf*�ԣ.�N&�b��%_| e��M�0Lg�G�h=�������"[N��@e�z���`�5�Mg\u�o&7Jj�B�<l�~��<��DMUN��\
�;B
-˕(��AS#�v��ٟj����A��\�|�h#k��ɚE4�h�KD;,^2��n�pS�<��c��|�g���偣�=��:�n��6���$�ٷF��q5� �Ms��Q�ވ]W�k�;�������i���(w�'�S������N��DK}�5��)w�]��F��]l�c��vQwڂ44-���c�M��Kwvvm�t[=*m��c��n�d�I�ǚ,�G�l���Xҿ)9%)�of��UNh`�'&����I?e����T�1�?1���N�)(�v����,�m�هY;���}Sr������J�y٢L;�0��� F�S��ig����k?�s�a��GQ���Ǡ��l2�g��vI�>�v�U���ԋz��V���iE����ҍ�ϣ�UD�߸���vc�1-�H��X?��\�|�XT��YLK8�07���10�>>�x�ֳ�W���b䍥�{��|��
-��4��iyG*��|�q��2W��+�۔�h»�š��F�貕�r�j�r<�m�k6��zrv,wձ�-W5���������zj�Kf�T9�-��h��Uz�ғ��h�Ź(s�r���z���`��Ӳ����w7���b�L��)��8�_R���Ŀy�C�M�/�M/�o�������C���C��Ŏ�ͥ"�?�-�G>�0�(��3�|dw\�'����E�ÅQ�>�.x����L&�p�}� '��qC�y=[M����5��@������0���P��y3_���JV�'��XG�`�u@�Rđ�W���=wL������/�w XQ��rͨ�p����K�G~��h�
-`~xS��'�T`���*J�X_ۂ�ZA�f���r"�J��s<8%ƥ��}2����]���J�Ӿ������K&H��lv�֥t���,VC��y)Ț��*�;�?G�����U)���K�yo_��m_r�;m`
-�F�/���W��Ą��&&r�nc�6ݭ��hc�/g�����'�1o,{0o�z0o��%R�13��LL����5�:laޔ;0`a�n[�7'p`r�{�?��Icu�ļ)��al_�{��m5��D&'&B^���k ���L���')�&k+���p̕�S�p�N��=�C��w�x��-����50C
-a)E���W�Q�R�]�#��qR��r����`2p-G
-ky��#�td���(M��i+O���xu�]�jKyR���>�D�Q��1e!-�#z�D�d6��l�L)qש�.�߇�/�hm��K��w'q̈́�x��m�"s�h��U4�R��3T4jʔ�4�Mt)��~���d%*:�����>]������r�4.D�3U ��~w�S9�n1ʦ��}sk����OW�n~���W� ��y���L�Fm�V����#����g�=�y �24u�:����DN����d+�[��ξ��L�ڎߥ���R��𤛤^zS����p�VcVf��E��nG�nY)���˪`�G���[爹�� �F��xn����������k19Bz���o������w�8��yi��|#�io3����,�Bȵ0�Y���e��@�9\������.�@v�_��Ƅ���
-%�t��,��@���U@��
-/�r�?#=��P�����ɡ4ۜ�iG��WNb��Vf(�����a�zMf��j�6�����S*��-� Af�'�qZ�#i�T�-�YKz%������B���4Cq1n��2���tbD�� �%����%�A�f��#ڟiF%���� n"ӌ�f�%�����ǝU4*�L]��T�Ӵ4�Q�@ŨL����n�O7W��~�tŜ��L�J��.��o��e�e
-�u��UjR��Q�ۍ�6��J�>�" R��Q�Uj�� �Ծs�GTj��(öqԾl��
-��q���o�G����7N�=�xM5�F�K�K�J7IԾ������(k��p�>��qWqA�n�8�ׇ]+�o���u:�*�y�ۧ�y}е���}^�ì(0q���C�˹㦒5�g����#0��]�⽊r�]��6}$TJ�u{�P�/�J�,q���z�5��U���o�ԗb����#���kY�?�3 �~NN<�R�Z����dUv����)��xtO���H �d�R�b���0|-F��t�IkO�H�����㣪�Rd�Ӻ��j�⭖ �V�X��q�ZF����2��<i)_�֟H�x�9��}q�Ճ{�&��b�]�v��֡� k�����-�+��Z�,
-gW�p�>�f�p^ucz�.��fԈ]�jPo������zg���Q=}Uh��ƅ���� � -W��������^V��zX/}��+�*�$���X��zb{_���BA�e>���Y��z�@�v�3X,ި�����*��zV!��u;�G
-�|�.�SM��S�
-�q>�۰�c���9X[�IQ� ȉ���G����֪�Nܡ;�\ |g��?<�@\��^���Z��v�N�� ���Y�$�����צ���i����Z٥��Z���u|P��
-F~�������x�*T�ke��:;F��id�oSo~~�"��}@���w�w]�Q]Ե�|92����GHe;��qRR#G$���1+a�DNv$N��P|�p�,��19e|�H9�G�sʶ�S�#,d�a�����dY�Xeu��Y�bD�@�M��6�T�LٚNO*ۇT�߅H*Su6m ���*�l�d�T�;�eTR��,�%X�,�[��`�%3)S0��t��4�OW�/\�8N �t�'���>�.���`fY��[�:2˺�:?V���n�Ѓ.��7��|���
-<- U:{��������^ �n��� `����K��;K~�UM�0"YX9!���#�d����Dn��H�
-�����q�����!TZ�A�`RQ�=IB3࣑62US����T�è��
-V�L)��vo���2m���\zA`�
-�
-�=m��� �#8E���e�4�M�����
-0���"�9@�����25<S������r��|=����0jG�W��(<6���j��t�N�_�
-`zO����5F��b;5�8��?��1�ׅ�^��C�ۢ`� ���
-9�]�E�PT��mQ�ۢp�-'�a�tK4��t�%-˪�˖<���x2;4��a���H�{ڡ���y;4U�������v��-UQ/`���-2��v�e��C���?�%M�8�]�C/��N� �ʹb/no��_� �=�S�m�)J�͡=������P�W���Pna��5���4���X��.o�g�e�m8V�Kp����8��?�4�Nm����d��M^���o����܌��<�Q�]3��Lr�~
-���RU_��r��{H{F;�Rׄ5�M)���)����"s/�ɲpO��5u�vK���V6U���M�H\#R⚬�Mݢuu]���23�ݼ�D�l{E'�뤫FM[Sפ�DziM:�(��F�����´?w�"ѽ��D���4���"Ṯ'ZҚ���it����0�����q��G�r��bЍ=�{Х��UU�I1��F�=���Ye�i1��=�Ro��0W�+���Z���0�*�Gç��tΆ��f"�\̙�
-s�j)S�0̭�L%�9u��0��1u�v��1�-FS�q16.a*Cv/�m��H
-��`ƅ����*>����H���Yԣ�b����r��0)*�c��O)# ��2wb�D9hvr�b5}XL�q���i.�Otƅ1�a�vn�#j�sS���˩����.q͗��^�rq�Y���:������+^���P%b�>�w�X����8a�N1�7b��p�U��J�n�����l����de?�+�1GJڏ9h�~���W�I67s�f'Zy6�\���ۄ#�V{���B^�)��r=x�b��/��l8-��7(�>E���p%�����M��(���.�6��q���.\�~����.���8�^
-2O�Ev�(������6���!|Y�XL�D�:�@O�L�~b ����1ђY�6h��b+z��foy�$�✤�KYȂ�$ތ�wOƠQ�U6���Z^��$ɀD�4���Z9T9�F��2�����4\2)�����!Y�T��*:�4zkyAB5m|`������E��[˫*[3��P��rk���a.�
-p���J�З%���I�����IgK��1�,��V^�/�Z��c4�P�Vo.���E-�=�STE����F-C=��+�NKP��D�.�����B�����'����[i�K ��jw+Ǯ#��s��eQ�E�i��*�es.����c��fі" �Gg�ʓ�,t�̖*(t�D�1��?,[Q��I鬵�����CI�MR�)��$%����EA�>k��oa��:�1s��.X�K]Vܥ�-�tQg��C�~�5��:6�]q�5������(��O/O������t~����1I�e�AP�����*=��w�e��x8��q���/�3���drx~F �38�¡�euIv'7=��/����f�/;#��,� ��[�s���E���}&䌻�p���vϺ��X�h����W�ze�Z+ �&pt������`b�KYRM��E���FP��Q6U�g������P�����Е����]��F�x�V�P��F�ghk��e״&)0
-svF��3jϣr4�u��XD��t��~�x.�l]3�v'��]��+�7
-4z����cB�r�5���Y�
-s0��bO�=���Վ�=��^�[��؞�|������y�Y�c�`��d�+I"V� �X\�P{���!��0��`��JR��kqN� `��e����G
-f>=�L�I�%���a�:��֒5�s�0 G��a�Z2���o��Aoy ��� ��0Xk�ȃ�z(�u�
-����X��4=Ș6��A�4_���5�:�e���=�����Cb���\`b�'U�7[������6�L�Gp�y��m������#h��p�e+���Y�y�[�����2o���J�*��м��g�anߺl}�y���6.�d>�����b�M�if�>`9
-�<����qXE��pM��$�F��H�>c�"t������A�҃v����9M�sS$�M��6��!f��p�k;���X�y��7]�ߔ�"������I_c��Cܾ������m�6�'���'�3,�~ޭq9���r���0��b����cq.�Gv�1)>by���p4rh"�؟���5
-��o4z����+�_�Y��$���0E��c���#G��y�Z
-FW�c^
-��|�)J��`�J��/"Y�T ��::�"
-1�
-oK�QMJ�^!3��5��B�>��]����v-���`���&`l����[-�Xg�����-K��f̴,�A-�/j
-F��t���@f8.�@,�����&��%��}E���Ç�<�i��`NJ0�P������q%�i �>�iw��bB�D1�H5����f�դ���PP��V��j��*�l\�@W">ZM�K�m���t!����.��C����jD<s��!q�.�쮒� i]P���i��E�I�ⵖd�/<�"�>�7�Vy-�[}֣䤍Q�Z�H�����ar��#��
-��>�2��
-��������g���v�5iU����-�`OB�.�������(.`�F����lC�r�v7k�Ī\��Bz����|��6�B�.���]m�Dy7B۟��ea`�Zl�א�ʘk������:_�ۂ�j2j��F����c:}`{��6�۪��5��Ae�+l�Kj7���2>�i�tVͨ�m}]���q]:�0ڦZh{��t6U!�M�жx`�A���mS-��n$o�+]��Ѿq���r�I �&�F�
-���
-���M�r9�=�&�^ �&� �.� 8�9r��E�b��~�#i�Un�G���]?�Z�xgh��<}9����c�x�̜�G�@5�*<P���W*s�h<��=��令_һJL^�y�$�����NQ�����:�8Ee(�gT���m��C�^Ӊ;z�ٜ罜z�ڥ^#d0����%Y�9/�ڜofs�|�j�͉�P���� (�b���;ns^��n���{����mN��6�r=c���{�����:�M�215�Sc����4V#�|}Lv�f�J�8Od��0��i��0�BΨ�歹Qźl����UZ�ȾU�z���֭R�q�����Hѐ*��v)�
-ضKY��RjN�B2ۙ9�� �[��]��٥��h�4��1�u .1�:�7���q �V��-R�
- Nd���p��F��٨ sJ&>%g*�r�bdv�&�qK����IS����[�t��yu�٪ �j���.��u����'��¸�L�$��(M��05���zԦ�l�U��/���9s�|�0�l�^->�W{�7��7T�!xM�JV�>ys��ĉ��1o�4���BK�s
-�1��c�2]�R��7����i�;��p�C����Af�+�Qf��e7���g{9Y�jF�}=\�� ��G�<E�l4�=\��w��p�]�57X�̅���|�D�n�q�m�{G7��}d��02���\W�
-u�_Y��b#�4�j��5@Fo�x=ȪΒŭ�Bߏ}�m>&g�h&m��g�'/��V����x�����u��-���b_ia#�b�}R�K�U&By�N��mQk���7������/�������%��Zc��C���
-�-w���9�r�>���_��&�������8s]�d�V�<pHE#�b�Ӽ��|�����9��|@q��lSk�~��0{�;�b�f���md�IeQ��M����c��E�f��aq�����K ĩ��t����g�-��r[|�4r��\�yC�m�������V�h�x��BQ�-��݊_F�DQ�S���V��T�wkXN�ϻ��\���DT��֨�e����8�t���@kn�=�d����J��Z���
-o����j%�w�궚�Op��[� �ۡ�$����ܭ�!���6���8=Ce��$lq��V2�2-��^K��T;��۟?��)�Ғ �K�6��0!
-���:��?��FF����,����p[3���,��9;�]\���j[-͢�Ap
-6�4��:�!*�G�?����R}���2����n�n*�_��
-R�S�"��a�d"��J���r��*g�[ώ%n���o9 ��MC!���Pq�A�80e!���"Kk�͢
-ےJ��=mK*T$<�mY��k[B�\I�:�4�s8۲����<��ۖ��h~�e+��1��o[��O�M�mۖ���c[z$/�56�z=r������ZH�ƃ*��>
-�^���1:��(0
-\.�����ͩ�Z���Wj!�ԯ����P�t�Ѳ-Qu�u�k-Y�>�3`i
-�Z2t�,m�k�&,m� [k�ȃܾ
-K�n�Z�߶K�nĚ���䘘F�}��ie������ #�O�c�G�!2
-�3H�σ��� ͵G�Y皣�b֤�
-TjH��9�9��*5�c����4P���us��
-Tj�y��7G;�@�"����ƷL�T��>ɱ/]��r�}ɿzx�����PK:�&s�*ѡPK)�A&sammoa_Diagrammedecasdutilisation.pgmlMN=o�0��+�7�ٵAuM 0�1Q�d`���aY"qd'U~|������ݻw��Os'���m�q ���P�G��l7��eޕ���l:�\/��D`$���c�:����|�L�d�8m�n�����Xu��"����1���4TrR*�����M��9U�����o�� �n��gV��I�������л��z�Y��:��d�PKǒV9�PK)�Asammoa_Diagrammedeclasses2.pgml��o�8��_���t'�)6�������i�v�nݤi�N�ʍ�����$�@RJ[��6U1�����>�'&�on��tE��gC
+˕(��AS#�v��ٟj����A��\�|�h#k��ɚE4�h�KD;,^2��n�pS�<��c��|�g���偣�=��:�n��6���$�ٷF��q5� �Ms��Q�ވ]W�k�;�������i���(w�'�S������N��DK}�5��)w�]��F��]l�c��vQwڂ44-���c�M��Kwvvm�t[=*m��c��n�d�I�ǚ,�G�l���Xҿ)9���"~3����pB�?1���N�!�j� �1�1�?1���N�)�h��ݨ�t;�g[t�a��>,iߔ�}�w��{o�A�(��>L�yd:.A�7����>�'��~���ä�������AQ�:dv�>풜}�b�������H��Ǹ"OY�i�F����*"�o��}|;��ꘖo�An��C.B>I,*p�,�%i��J�����O�\�G�Y�+\�I1�|�y-��zCi,�gdZޑ��1��G\���U����6%3���nq��dF�Q.�le���T����l�P^X�)/Ǵ��c���]m�jD����F�}h2�%�l�����h4M�*�}��l�e�^��\�99�|k=Ojg���i����ۻ���h��&���x��/��mn��ơ�&�����7�C�m�����!{��N��b�����ȟ��?�#�qk����L>�;��Ge��?���i�D�z��@T�&�e/p�L89� ������j���n�A:-�E�y�݆B.�Λ��r>�V�"=��:���"�\�
+��co
+�~Ō|�����kF=���]\�?�;>F�T�Û�u>Y��}
+WQb������
+�5�η��Tj����(1.��Y��o�Z��W���.��f]2A"Wf�S�.���fg�BN��KAִ�V�`߱��9�6/��JA�n^r�{���m����iS�5� �\�h�*��&&�
+X61��t3��&����i���6ffn��Ƽ��������9�S�H����G31�{��{J�갅yS��<����maޜ���1�-L8�C�'��m�܇��}��
+L8��
+L�x���yy����^31��v�������>�1W:N��1W;{�����[0po39k`��R���������H��aG���H!,�H�Y��d�Z��
+�t#G*��t��AQ��V��ꤻ�Ֆ�nEm}�1�
+�+b�BZ�G��R�l�����R�S+]��1_J��L˗:}�N>� S�ֿۚE"�F�0�h��Mg�hԔ)miB��R /�S�<JTt����}�|��mq��i\��g��#-"���r��b�Mu����Rs뷟�������A����e�
+�� ��)$ۣG\�ݭ�p{T��eh��u�����,~w���V�w�R�}�w�����KD�ߥ�E�I7I���?���ޭƬ�>���ݎ�ݲR�s�U�������s��v�<����>�W�<��<��4br����;��/���2=p:�Ҳ��F���fF�=��Y���ka��H�-��r��4r��'71�s?\��z�
+轍 J<鸑Y���`+����[�^�b/~
+4Fz���6'9O��Ci�9ӎ�5.��� ��0�P\w�e)�����0{#Ԩm`#"����T��[��0�\O��"�G���4p[���"J~�����L3j�i��b��=�e����,:*Ĉ*.$�AVKL���#Jf�,ͦ�G�?ӌJL3Y{�D���4K
+�;���;�hT���4��"�ii�@F�A�fTc�՞Gw�����x�˧�bոf�P�Ew�~�_�(��(S �(���P�b�}����nܵ�}T��)I����H�R�6�Hإ���=�R��e@����e�<U���#��x}�H=����q2���k�Q4j_*^z�U�I���7����^EY�>���y����2t��9�>�Z��>��QWq�ȃ�>��냮�M��fE���G�j_��(�7���=�~��I�B��[��`�߸��C �R��QB��*j�ĵW0�ζ4�J�U���o�ԗb����#��#u䕂����$X�99�FH}kR��U{
+(�"V�S ��9����B���j2j��=b����0|-F��t�IkO�H�����㣪�Rd
+Tv�¶����.�j�m���J�e����,C�HӲ<i)_�֟H�x�9��}q�Ճ{�&��b�]���QQ���MwKdž� ��q��>�F���"�5/���Y8�W�EŘ����D�5b����.����jTO_���֓�[�&�'�\����6�zYm�a��9ZX��g�t���g(b��}�Ϯ�
+����og��yہ�`�Tx�Vz�0H�Y�$b���)X�id/��OA�5]N�7����o�v��5>��`m�&E�� 'җsC ��;X�z:q��p�s��1&�0�Lq�z��h%
+��:���HJ6g�L�G�J$k_��:b�}�#ke��:k1s��A%�*��oSo��ɫP���}���y�ۧ���M�M���T6�i56ߵ�u5FuQ�z��LP� C3cY �Q�< �IIe��TƬ�E9eؑ8e4{C�I�q ��l����#i�Hy�)�.�M���U�k�2�"�e c��YFg��UUT�7)B�tRY2dk:=�lR"�L�ٴ��2>d������;RYL(猪QIe���`��l]�U�̤L��g�Y~�t>]�p �8%��н�TV�d�X�ރ�e �n ��,�.��XtR��@�:߬���?wl>(�x$T��7>��
+�{%���VZ�8��j��/�LO�,i�i:�V5����da�t��f�����7�#�#Y�͇#�+�/F��t*҆Pi�i�IE��$m̀�F��TM�FvSq|���6XAd3���b���˴
+V^r���6�*���
+0�>����U�i�@�6m�C��6��#���������L}P�r��ˑ�b��kx��è�^y*sT���0G@�i��N�i:�6��=%Zw�-b���T�3x����hP^�z)Jyo���' [ԃ7��w�CQ9�۷Eqo��ᷜ��q�-ќ�y�h`�,�^.[�;4���Ь��
+;�R"M�i�^�V���T�W�C�{J4��a;��TE��Շf���.ۡ�h�u{;�� �4�N��w��,Я;-��+�V����%
+�����NQ��(16��pN���B ^�^�B�����\��.Ҙ��cM�^��I�Q����|X1/��kD�^�����<:�]2z��67yM��kDJ^s3bTN�hG88w�<�3�]�)�>FJiT}UZ�]��!��XK]��7���𦈖��̽�&��=�2�ԙ�I,!Z�Z��TI\�k6
+`d q�H�k��6u���u�����$v�����d���j5mM]��˦5�آ<H�Ѳ��O�
+��ܕ�D��-�w�$�皋P1ǞhIk�Ʀ�=�Rv��a�Z�c��њ�Aw�A7���A�R�VU1'ŘI���g�1�Ř�z[��K�-��p\p�pjjka�R�T�
+�b�u8~ӛ�@s1gJ6̩��L5�0��2���E[��R����jƔ�M����ظ��ٽ���c"1(��ף���X:��"�&s|8deP�⊥�+V�Bʅ�ä����B<��8�P��܉����M���a1]�A���E��/<��P�I���k����ML���/��˃J���5_n{��űga���g�:�~�O�xy��B�� �8�Q@be{��e;Ŝވ1���Wك*����k������[z����#���)i?�i��kJ`>^m'��T�}��h���s�g�n��Z�m'ye������1������`�������e�-\��A�TtL�~>���6�������_���z�p ������NxN�|{5�<q��Ȧ�R�k�T7��}d�b1qE�=13s��%<�����DKf)ڠ͗���a<
+���C�@�s�2�.e!F�x3��=ed<1oF�V��2�rky!��$�М2�rky�Py�HyG�~
+G�pYȤ��[���dU"P�:��<J��� �d��U����{L����Bn-��l͔nB�+˭�J���*�m�2*�B_����'�����c&�-]8��в�z[y�,j9���ѼB5Z���{_���OQuR�z_��dW��:-AZ����*G�k�
+z��NK����o��/��n�ݭ���C�E"�E9a���"�d�;.��o��E*�E[�$�Rl�E*Of��\ 2[����qA�\���lE�&������z_%I7I1�����hֺRuM��m3���.��<�헺`m/ua~Xq�J跰�E�#q��X��\�v�5�tz�&B$�4�?i�< �W�gd��������$
+�=A=v��ª���!�Q,~��OƁc�l�~����Q������
+�Z��%ٝ`��p�;�d>|;#�ݾ�@bg���`2n��E�f�9C���3�������Y<�B�F`����F�2c_��Q4j�$����]GtG���.eI5��
+Gs�A
+4�F��TehԞM`hCCQڞV�BW�GwDv
+��[
+C��j����IS�]Ӛ��(�A���Ψ=��Ѥs�-2W`-�������}�гuͰ�b�M��v����ch�4���&R� ��1�� >g�*���{�q<y���#T;:l�4�{�o�Vc{�����緗�Agi�U�}�
+��$�Xt'8bq�C��F *����C���*}HA����9�����`��R�.5���2�&���b���.
+XKִ����k-�<�_:����@�/�v$����H`�m#r�@�i{(�*��c����X c�t�!c,�|9r�ּ��mLoH'��:\�L\�A$�r�� �T��la�f'O�d`2A�m楛nk��w��f���i��ٗ�l3_g5�an�f涾˼M�_�:*!Ī��B�Ξ���}��m�m�o۸l|���n.��7e������4`�|�#�a���5�����n"mC������҃iJ~�����H4��M�6�w[ؔ���i�Ù��lJ_c-�an�tmSz��[����'}��"q��k�{�[�߶������Ξ4ϰ$�y���(����)��ì֊-��/|�Ź�ٕǤ���1_����ȡ�pcrO�(�7��� �c����g]C�$rOK�0Ȓs�Y��I#�k)]��y5||�(���i+����d]RP��Z��,�4Đ*�-AF5)mz��d:��t�
+���_�w!�_(J�u���W��C�����2��o�c��2j��,]S�1Ӳ<=�@��)�'�݊^�� �p��\|.����IK���.��n�9)��B���b�Ǖ�%���R��-(� 1�D#�L g�㛉V���fb@A[m&�ID���z�q]��h5].��C�҅��CR
+TN��i��^@<;˫��ݫ����_��J�'�uA�ZҦ}'m���Z�y���@�ހ[�
+�<Hn�mX���6F�k�"y������ɭ�|"+��T�p�>4lN�6|S����s"�֤U�ڶԃ= m�,jc��������Mmˍ�ݬ�c�r�B�6�#�QC�T
+m���#w��u��m
+����mj-��_C�*c� "�ۢK�,| Tl�ɨIJئZ`{������T
+l�*��<��]���z,����V��t�e�Y5�F��u�\��u���<Hh�j��=f�� T��6�B�:��!�^3�M�ж�����t}�yG��њ���!'%���=�*��?+@NK 78z��������{%��&̻L'����9�*y�U�����QV�U��*w�`k�����Q����hjj\���d2s2Մ��<@Q�
+O;\U��Ţ�2���#��~I�* 0y�����:�#8Ee(�gT��:s��8s�����9Pn�Uf`%xM'���gs��r2�uj�z=�8��|:�S(�d�漴js�9�͉�6'��BmN��6'�؊}����yY
+�}���m�
+�[�9��ۜo���u���m�
+�ۮ��7����HO�y�f+�X����1ٱ�U*U�<�U
+k���il�$
+18�J��VF�Uz�L��Viy �V)��
+�[�JYǭ��@/f EC���ۥ�7`�.eM�K�9m
+�lg�\��oi�wU�f�f���Ҭ�DŽց�<����{�ā$Z��hH=7$8�A6��1egg���)��p���@ʙ�������-�����&M=rj
+ni�����df�&���b�����"\�(��3ђ,v�p4����܊�Q����T���r�c�̡�
+���oz��^��T��P��<�5E+Y�����'JǼ9\�໎
+-��)���t��1V�t1J���/vJW�
+�Ԯ;�N���y��G��>��L2��
+�dY���p�Z�����j��|����p1���M��wq��`9�2��u8���Q���e���%����.r=\�+ԩ~e-Ƌ�p��F��w����� �:K��
+u|?��7J���L�!?����*�~��rZ��v��Y^�:��ׁ���{�}���Pk���I�/�W���k8�v�E��2s�C����H���Z�߶˗��+j��#qL0H�*����k��e�zI㛤f��2���u=��Z���!�Ԋ-O�N7���6��W���ű�M���u�������Y������I&�E�6I�,&��:UXr��z�Ž�2z�.%�Bg��QPnK�ߞ���m���ȑ6r��
+)��?��:.�r[|#XM���_EE��Vt+~�EIO���[u�RYޭa9?�6FTs�YPM�Z��i�V*�$�A������t�՟[s+�{j�"X*��*oO��hP���j�?�uo�&�n������s���*ڬk��[����eL��8��y��[�Dʴt"�z-m�2R��o��JK�4.A�T4�JK됾���i��k�(����m�P�Vk�lԶ���vqm�6�m�4��9H�5ش�,�b����(�8@:�a��FH����2z�J�I�!����v7HEN��@�n��N��@�>*��zT��vT��o=;��}P
+��$�6=�b�ơ�rq`�B��E��>,B�E�%�be{ږT�Hx,۲(�5�湒�u�#h��p�e+�Y�y�۷-[�)�&��m�V6
+��c�!n߶l}�@��۶-�0Ƕ�H�m�V��A�ƃA�J-´lWj�}��$�ct2 Q`�,<\X��<�ٛS���L[��B�_-[C��&�e[��h���Z��}g��6��d��-X�v�*��MX�F�֮��}��݆���m#�6݈5W�#�11�������<�6QF����&Cdf�1H�O;�A�k����5G�ŬI�Ԑ4�s8s��
+Tj,�<�훣h�b��hK���3� �o�v���E�m���o���
+7}�c_�N������8{���PK�[�+ѡPK`Z%A&sammoa_Diagrammedecasdutilisation.pgmlMN=o�0��+�7�ٵAuM 0�1Q�d`���aY"qd'U~|������ݻw��Os'���m�q ���P�G��l7��eޕ���l:�\/��D`$���c�:����|�L�d�8m�n�����Xu��"����1���4TrR*�����M��9U�����o�� �n��gV��I�������л��z�Y��:��d�PKǒV9�PK`Z%Asammoa_Diagrammedeclasses2.pgml��o�8��_���t'�)6�������i�v�nݤi�N�ʍ�����$�@RJ[��6U1�����>�'&�on��tE��gC
Y�3'��3o(�8�3e��h���_�O��7|������$���Md��\��؉�9KZ#o`G^��J�5�m/������w��Y�p�"���?����q`��ɲ�{���=]�H�Mt�T�Z�n�6:�3E9P�yGJ��=�Cy�֔B�$��Nc �;#�u�E�b��x�{Jzk{��Ą�*Vv%U�w%�Ю����6�����8�C�b�:f4�!����>�*��9�l��q���X���ʳ�^Fԅ������̬�h�p�A
��K���X~���˒U�q`;���Qr�p�W6������,��g^@sc1�F�f(�7ӳ[8S���ڟ�ˡ>NK.��]����iIɮ:��������%�ް|�Q�è�a��a�:��V�����ÒĻZU�3�h$���gv�;C9 ��p�Ro3����i�?������K��������p�߶r`Y~��iK .�1�Q�oć���b�J���k����0NUC�0Z�U��n嬴S�<ȽW1 �!Y��D�2��z�+,����Ʋ��ud���f��Zi5Z�T[����*`��J}v�ʃ3xD���pԐ��D*&b#S�����Rs���y�૭�$]�����l���r��.�eS�q8����/��ܾ���2K�Ϻ�8ڦ�c�d��KnXҀ��^���h����٬
R�
@@ -99,75 +103,65 @@
8
��R���E�H�(tX )q���Ed�b賀��S�3��aHi�lޔj#���h*�� Bz�)��jo�O��)\�RF�J�Jz�x�OT=�,u>�&㔁J�jQ��5}0��@�@U���({R�I����(�,U��n�'e�=EL�Y�>0���b��Я*6�,��������}ZS\OS�h�ŔG��QGA�jWE��S�RK�RY�ȳ�4�,!M��LSj��>���2M��gWυ�>C�B� ������V�#�m�6z�9H�O��:_˪��H�O��5�Y���NL�XJ-�M��1Q���-kV�j[l��̝��Z�t�5/�t">�W�!xg;>�CJ��DېN�6�qvϞ<���.˒�'����I�dP��I��q��������9�����Z�oG6ko���1��vx�.8�|���"r�y1�c�K@`�_�Q��>(�3�������_�f�Õw8�ATM!μ�W�|$_"[Vmp�9���=�)�g��wޮM���G�
�o.��Ѩ���d���&��S>h�Ӌ�Ƚ���0WG�G]0}p�p�yܶd����,�M�+�B��4��]}М���X��m���
-�&=���i��6����s���Fm#M�F۰��Nۤ��Ʀ`n��s|��~gm�=���i��6���������V�V�6�Զ�wm���ңI��w�6y�`��?PKɟ���FAPK)�Asammoa.todoeO�j�0<�_��.YnkW6�M��{��Xk#P�ERL?�5%Ѕeg��aV�/�,`�ƙ�H�3��Tz���ٝ�HɾI����Н?�ģBҞ���J�H��*%a%�u�|��
+�&=���i��6����s���Fm#M�F۰��Nۤ��Ʀ`n��s|��~gm�=���i��6���������V�V�6�Զ�wm���ңI��w�6y�`��?PKɟ���FAPK`Z%Asammoa.todoeO�j�0<�_��.YnkW6�M��{��Xk#P�ERL?�5%Ѕeg��aV�/�,`�ƙ�H�3��Tz���ٝ�HɾI����Н?�ģBҞ���J�H��*%a%�u�|��
���,���\�l�v�
-l�:�L�A;��Nx�{�i7�����D�7��=�l5�^8�0�@h�@���h^PZ���ˢ����CYV�j*8�5���ӓ��LB�l�)�?�~�$?PKP����KPK)�Asammoa_profile.profile�����Q(K-*���S�UP2�3PRH�K�O��K ����Z()��qq��e��qqr�䔦g恘���>
+l�:�L�A;��Nx�{�i7�����D�7��=�l5�^8�0�@h�@���h^PZ���ˢ����CYV�j*8�5���ӓ��LB�l�)�?�~�$?PKP����KPK`Z%Asammoa_profile.profile�����Q(K-*���S�UP2�3PRH�K�O��K ����Z()��qq��e��qqr�䔦g恘���>
�z& Q}�0�
-�����������b<��SR�S�R�K�����+�,EȂ9PK8��7y�PK)�A
-sammoa.xmi�]ݖ�8r�ߧ���cϜl�E��({�s$�������{f7Ws TsM����*���\fr�g��$O�բB�����ݒ�X(|U(������S�p����Ey�6�/�[���c��O��K�7��o�o����i��$�y~�����7A8n�q�6��GSd�����c�&S��:t��l��TE5_5�WjW���j/��AQ����8|�(��v`�&؏QL(������� �I�^8(1��"��8a�G
-%���K�,_���w�_fz�n����f����N �a[!w����+Jt�^���i���+UW��|�T�}�V�������wʟ��3��'����ẍ́� &�l�))��
-y�oV��/ߨ
-���7�;-���
-���wqK������\;R�sѼ �rq�nb��6�شڸ��R_]��f�Us�2����(I�.�h2 �Kō��r�J^��� /����Ag�x������n�Eq�����Q�/p����7�CO�o�l4&�����\�V��(��Џ��.}��#�|�]�0R�hD��Q�ç�s��j���7+�_���|? ��x���������{����btd����=�o���w����
-�)� ��Ɗ�1e��uY�ap%7_�u�N�+A8e�B%DS
-d,>+���3��1h�u0�$������L�쉒���1���|��8�J��w�Q2g�O&�cFJS�����|��~7|�b�V�M~ŎC��;�"
-�������K�E��ۈ�z���c����!���o}�E#yD��У37"ӘHI����]�
-�~��eu\�֡$п�D�=�c"�P��%y++�E�t�u�)脘�b��+6Z��%6ɜ�Xy
-<Ŧ���I/Oq=����_O�H�G�L�@o����P#�я0я�,$���J�5
-)�#�϶��>�Ŵ��ұTȸ)�� O��q0�,���������sAHn�-C�Rvr�#��c������w��A���
-���c��z�(+��Cd$,%ڐA�\�a.t�����V��_gA��#a����p$����Ǣx(G�O�B%��""�O�K����Q�/�QC��/d�B��'�o�4,��
-ߢz+����
--�C�2��S"��L!�7J�e���-/�i�BBX�ikzu�,®��ܨ�2�R,�K�1�pxU�y>F�w�>��.�[|\r�om<��!�5��\c����M!!���A?�ax�b�}@�'�h��uZ��a!:�][m�]�`�nVץ8'l̼�%�Ɣ.-��N1�5]Fj��;�n�~��vˆC����9={�讲��Y���P͢C,o���g�M�f o��f�w�����N�*{>�?}r�ry2R<Ro�-�W\"�~9K[��ͮ�P���#��m� W���|����
-�U��9�m�f�D�^����`!?QC�8l8��O�sF�ǡK�}�Z��L���]��86�Nw����F�ǿ��T����d��?��<��1�"yxo��6d
-#�V���=�<��#��Q8���}6��`�}�,�6�]��ט̼؝r��Y�R�J�}Y�g��|T#�/�ל��#m�/�L�L//���T�_*��4��A/e^j�5s,/w���L�ȡ�P�H�qa�=�����%�`6�A8�$k �%K�K�_��A�����'D�A��X��l����y��\g#�v�8�M!.p|����m���c �u���H��xw��˻��C)hն�����?����XjS����VR��Va������/;M�RZl[⦣~fk��5WP�2̨���*��oKAd�\?�N�T�O|��8��]>���K1��C������͠�r����>�����<2��ޭ?8�{QX�A&��_'}ý����^y��ck�Y�����3���7�M�~G^�r�61t3?��m���x���~�s�\�H�7˴��1Y&OѺ'=��H�Z�g\�R��q)a�P����/���7&�w|U�oL�����$Grw�ش:���(6�䪞��G�ƃ�e��h�s!�X@����E}B6r4�����U���J��q�Snmܻb
-Bz-�qsE_�[(N��ݞ:E��p6���\�"��I�[�W�����֥�.{�t���6����{�`���.�-��yH/��*�^+�-6<_���<�"��ءYr�nl̯^����P��n�
-��'V�m̲*�����+�kf0H��IW��G�Ϩ_3#���[|�<&\�p͝3�#��O��l�|at}
-�l'Pǩhc'�����Γ�a�1��S�^L�8g�������o2���7�N���-�Q=�o�yr>z����C�±�v���ى�z�b��8�L�Hz�a,�!�"4uh㾞{���Xgf���6>�SD�˽���̔�N��l$�yA�n��RH���Z�U��Yc;u����WH
-'�-&r^�<��yP��>�t|8˸��z5��637�u������%�����O`O�s��Ť�&O,�h����1��j���2"�aT�U~rź�bv.=X*`q>�&��k�j�'.:l9mƁ����p�s���um�U{0,%$�"�Z�#����KJ���-'<�gUҤ��mұK���V�
-%�
-�<��/bR���o�?��W���̊�'2+�r��1�~�&#����y�{8r����]�Ps+D�KHO�/ S����>���(MX9�,�̬L��}\,Wye_D��$;���r*@����yċR*0Hϧ�Y���Rkn[���l"��1M���[�(�Bȝ��P�V��Ť��o�d��ҫ<��NU�v��,PkpO��@�H�\sk�9����MF*V��#��2�����Ae+VzfHO
-�d��s���L�C8�sP�~���=W�"nj�B8���r+͏��� v��i��y��<�O_�P�3pݨ����L��6�4KՒ�&�M
-@P ��r��k��F�n��F��s�]1�$�@@f��[������~>���~����
-�X�o���V�m��a?v��աN��6�����G��+7E!aP�C�t}H��;@���bB�σ�O�o����Ԓn��Y6>r��9��T��<��0#V�&^Ζ���nd�.
-q�7��j�.K <6Pr�R"��%�㉦`nQ���Q<���b%����@�Q��O����~�r����,�Ri����i5���v%;�:Vul����|��^[\����~Rxxr�J�@�Um2zlr��%7��72G�I���m��ڦ�05[w��h1�mt���eo�G;�8K��˵V���J��%��1���;]��:��:3�&�Uz3_���2�ܼF%������*4���ixo9��ľ�j�u.�I��ڍ�O*!oq�!pw��
-;zq�g�G���z�n+�w 2L�S�P�>f����R��>3F%/��n<��xZ���V��Á��*���%� H ��vɑ w3�^��B��t��3s{����b�J(��������M1�dr-��8�p�)ӡ�H�p��U���m:#�V[:s/���R:����Hp��@�<0
-2*����LR9�r���F�vK�P`�/�%�]�)�m�����i��-�����j��{W�%0��_[Hc��iR��{,�y��g����1%�k�'.��繽cJ$�ͫ��D���,���B�Ce���n(�� �H�)Ҡ�� �Y��Dd:@�A���uN�`���?`KA��F�Q��<ő^��6��E�>S
-6�z��$�bi1U����=VI/@�sEne4��f���� mr�C���jQ�M�l���YL�dq� Ir� � nT�h~�n%�xZ��m*�t�1�[��͂�7wr�
-H���I Nld:��) ����p8 ��b����L�[�2��K�>q ��bj%���2�at���� |� ���h�]�pf:��?��Y�^)<!υ�r�K~q�[�^���.ڪ��4��$�i�l�q��!7�����4�$K��"� �3*�%�tin`H��.��!�eY3]�����%p\���R,�{
-i2C
-���F�אFW�;1",UCV����e�fc
-�F�-�|�r<Պ�a��n��8K�. ��YZ�14a�`���0мp�N ���c�T4g��O����L�"�x3<A� �ς�̈́�p�L�c�D�(n�I/��71�-���Px2ӡ��KB��"��º��#5�6�Uv��7�l�zĝI3q� �,ӡ�0P�<������.� rw2(66��{ϰ�|��m��\V(���ƌ��Ja�X�@~a��l ���pK����[�ZeL-�(�8���t�q&Qq���s�n���@���sH���.J$,�&3�$�܇���Ƃ��<�^�u��?'·
-�l�,-�(&��L�ʺm�ߑAB+�g���q�j�L��P�0�Q��f���q�������9�;�^y�H���������,�o�~�_g�\q���H/!�`�t���W�n�B¢�����s�ڹ:<��|6r}{�%��ts�в�x/aN���9��T��<���f{�בΖ���rd��l�ň=Ƨ�p�e|�M�&ܼ��
-�\�*0w>- �����O��<��亩����l91`rGF��tő�`����t��F���䦓 ��e:T}�y��]��y���d�������FRU A������O��9ӡ��gq�eZ�h�;R�����c�`P'0�|�-lG��6a:�dxZLy;q���]������da���x�?�9P(N�'�tH���:����89�1|;�_�OIX�E�0{��A�,��2��KH����B�K[���}.���8�ی��F�1��D�#�^L�q���E�C���5B��4ZI��32�-�\
-nt��C!�ɷwIQ_?0��jA!�B�A�C�C��En�
-��GK^����^��w�CnhA��� ���(�ׂ"��ȂL�z��ł�t���uL
-dx�.90�Q���AA���D����q�0��MF�,�ckA���L��u�ao2���2���A�Sa��0S��m�̐��:? ���$)�����)��c+�,n�ө�a�RB�� �;-��/�%�
+�����������b<��SR�S�R�K�����+�,EȂ9PK8��7y�PK`Z%A
+sammoa.xmi�]ݖ�8r�ߧ���cϜl�EJ�${�s���q��n��@$��"5���*���\fr�g��$O�բB�����ݒ�X(|U(������Uq:���Ey�6��왾�xS��O�7W��������Q>ϜF����|�zዟ������Ϧ
+��C3Α����J䐏��i��bK��s��+��B��h6����^њ�����>��W���l�f<�^�"Bm����AD����O��6�;���#/T(�
+�d���m���:ӛu˟�_5����wJ����O����Jt�^���i/��������|����L^Q��%;S��d���>y��'�k&�0�oaWI���oȻ~�>.�Fm���~��Ӓ�)?Mߋ�}��$]_�[�α�!�:W�+�*WWF���%��2p�6�-����6�M2ZkW�П/�FI�w�C����+Nx7Ǧc;f�*�'�!��|��(��[��/�wt��$�d��]�}��+)��5v�l���FCF�=�=�����mλM|��H���Ǻ8T�ˡ
+C�z��~�ҟ�8xL:����6_>�v�u���|"
+��{j�0\�`��}߱�}~�!�Z��L��p��-���N�x��NA�2��,��[�Q�a�ݔu�#�a�����3GS���b�9
+��)�������Ό2ưU��IΉ�밣�q�H����-�W��w`%��;r�0�3�#��B%�)����?bOy�F/ߎ_?�F/�o�_�m�!�N1I����{��x"�^������>��������<"�g�ҙ�iL�$BG��� U?����>.Gd�X��b���)��8PptM���JhR�!�1��V,'$�ae�F=8�&Yp+���X�^q1��*�K��_�� ��@�������
+`D9z!&�1�қ̯�^s��b> �l���8��l���B�MA�GxJ�����������-!�ͷ8�KY�]L����&�3�5N3��*7��Mq
+�)�����0 sVhC�r���Х2��+\�'
+\�~����G�2��S��D,h�'37NE�X��<�J.�/DD}�������_�Æ��U��q�r������7M2+<��yL�f䓻P���B;�O!Cb:��?'�n�
+1�g�Q-�5�ly�v���:MKkwP�`6t�F��1��bR]������Z�ϋ1"��a�uQ^c��~k�y�P����w��v�{'Y��$�P��=�E���(����nMz�����,����:st��.]��A#v�F���s��#:�d�t�ɮ�����Zۭ�=�^��w2��Β�' �#C��X�>��֛6\��@�f��o
+e�`��u�|���8���l�y����D��D��r���.��L�fL�n۲�01��������/���_eh]`�N��jvJ���y�ai2�5D����� �8g��Q8��g��+������c]��p���>o�=�}�s�� ��C�-���x�:&�AɃ;ӟ'�!k�Q��x��������.�M��)���͔%[� 6 ې{�`_c��3'�۳��ҵf��t�����F@_6�9��G��P���^��Y��[?W��<��AK�e^j�5s,�������ȡF(B������h������܆L��Z�vȒ�|���-l#B����#�� ll��C6��ތM��j���u7f�Ȧ8�����u���c �u���H��x�������RЪ������\b[<b�MQ��w�zb�
+l�o�kr��b�ɵ�7�[��o���t��aF�l��� };~]
+"�KY��:yS�.��^�\���Hڿ+�L��>��o��KA(way���C|H�^�G��p�/��#N�~��s� ���I��i.>��^��'y��~gV�g���Ů�?� �'[��{9���K>a��84�x����{��%����2�1GAD��s��I�t:Ѧ��ײ��z�EJ�+���,��-$G�����Xߘ�H��V�!ۣ�s�V�\ճ���x��l�m<d.Ahc}�l��fR���lͶr���^յ�m|dm�uʭ��#� ��J7״�U�������KQ������{��*bӟ%Q��Zq�\PH�8�Lo]z]��D�J�oSJ[��w���m����b̝��[�"뵲�b��u��/�)r~�wK��㭍��0v�*��v��"}b5��,�"��
+��"�a��^�uE��zd��� �
+3R����7M�c
-����1�8b����a9�f�F77�0�vu���)v�J����<��#�;��ĈK��O˩�-�˥�a�&�+Y{3�zx3q��U�Ã�)�'���;���)�����6;QW�_�'��I��%9�S���m<h���6n33T�^��)�n�{�3h3Sj�8E*�x�`���1vN!��j��Wg���-�^��K@_!5,�����ya����A����)��"�����8J@Xں� �뮇�ܬ]�k����$��\L
+a��x�F�8��=�6VM42WF�9�U<�O�XwU�ΥKbA,��b������x�S̓��%B�O-#��8PV�.|):x��
+�j������[��t��d~������0n-��r��xV%M�~��&��HzAl��Prް��jk�"&uK�!����x�kXL̬8}b!��b.7��! ��~2"��
+/��9p�� G���!�g5�B4���4��0��P��|�˒ф�����O�ʔI?��2�+�"B�6�aDf��S���[5�#^tw��R�Az>EObwx�Z]��avZ��n��N��^}�p��_��7T��ai1�&E�7�~��*�!�sը] ����S�G*P+!��mv���dz ���r|-�H�8��D0�uyhPي�����ғ�3�!�3v��~GvJ��ò�JV�1Xg�Tn�� �:�N�=��6Ԓg��b��
+�����P�1W�)`� �f�Zr ����sn�{����K��`]��pN��3MB
+dޓQ
+�-�݃/��S.���_ր��=3�ɷ!�5�^� w�C�^{m~�X=�����n� ����9t����7)��(�˟�ZkɅ�ݜ�j|�$z�s�E��hy��aF(��M��-�G�9��\��#�h"5�]V@xj���D��J��3M�ܢ0%�Ǔx"�J�����"��?�(��-.��z
+7�Y
+r��j�7N���~ÚXՠ��jV�n"���Hns��2F�2-�j�8}�0L/pTcc`��H��VR�q��B�R�x����vw��f£��Hx2�M?����e�:(���8}��p���RN�#�������{S'�-�)������1����p�$n�
+B���2� dYj� ��p� ĝj}fb���P�O�If%A�XBI�Kn�i8�N��1��0Sq!�4ӡ�H�p��S���k��R[m�v��5
+L4�t����Hp��@�<0
+2*{ ���LR�Jr��n'!�;�V`*�!���{��ʃ���x� 4��m
+S��kc��vZ�9)Y��˰����J�,�y��g���RW0%�k�g�������u�ͫ~FU���,���B�Ce���n(��Ak��W�A
+A��z�#
+t�4�t�H���`�:�h0��;��� �Q��(`0#����P��f�����gJ���fߛ��R,-�T�8}̼��Hp�H�Ms��R�,y��>��t��q�#/
+�y��@��Ť��2�e:��FL�mc�s+�Ӓ��4 � ӡ�8 nr7�ߜ���ڕ+f�@�>�$�t��S@\9p L�>�p@���D����5��e���i;�#0@���$����f:���p뿕��A�i%�ђ�;�"�t��1 ~m�r#�RxD�'��.� �an6fz]���2T��4��d5�h�,�q�јDhaGpY���DJa���ł�d��naH��>E5!�eY3]v�Ir��;4�>8��X�+���)H��S5^C�=���X�a�2;fo/37W�� ��#�w+�S����6H/������0`@��C�֏��ѐuJ��<�{���`(x*L�f:��ƛ�r\�~n&L��e:�$��q������a�� �gl15�$�"j���]B�F����^�4���S,���gs��!�L���ĝ��qg������l-57w�?����A�����{���p�pH��O�B1��0f��T
+c�"�3�fG�(��;L�����*�`jAE�� �m�C�3���
+7��rҼ��<-&�C�@���t�wQ"a�4��%��!,�)7T�����<,����9�Ug��`iQF�0�`d:T�m����Z�0=����V�յ����>頮�Y�u�lbd"n:a_�厥W^!'�1���5t1}ό�����!�5&抃ܝ�@z �s�k�H��6tsE8��؇�́Cd���t�L��x���\�Z�͙C����C��9鷒�\�R���c�����^G:[v��s̑{�,��O��
+=��,�HM�E� �0��U&`�}Zs�!�͟��my���uSg˝��rf�䎌̡�#��B��� �<C��M'A $��t��"�Hz\�s���d�G���L��FRU A������O��9ӡ��gq�eZ��h��R��z��c�`P'0�|�-lG��8a:�dxZLy;q���]���X��da�v�x�?�9P(N�'�tH�B�:�x�w�������ȧ$��"A��y�k܀� � Df�n�$|���u rU���rÀ��>�^�`,lFn}����s�]L�q���E�C���5A���[I��=�{-�\�unt��E�ɳ�IQ_?0��jA!�B�A�C�C��En�
+��GK^����^��w��CnhA�w���(�ׂ"��ȂL�z��ł�t���M��
+dxj�
+��(����f�p"kn�Rl�~��gpȱ��
+���A��L�:C��7�y�l���ck��Uز�@ ��Q�m�63�$�.*�<(I��Ak+iF� w،|(�[�t�mK7uJ)�ڶn�-��/�&�
ƣ<[���'N���t����v�~v8B
->�Ĕ�g1�$ ����P�T�D��Pk��b���Z2ӡ��'�]K��]ˡ�G���;e�FD�r)I�˟n���ג��݈��-d�Y��8}���Pc�Q\&��#i����U�$S�)�#N���t�1�N���=2��yZ�th8ܜ�8@d�[�c�)��,O���!N��t�1H$��m���-愳�p�9ӡ�>e!Dh��Q��LzԵ��]]s�b��҄�&�ǘ�Z��@�>pd:��,� �Ѷe�TB @�;�%�f9����$N�lodEXn.��N��
-�[^�'�����*�[C�}�j`K\���ɵr!�R��������PMw�Jnp~���b�H�2���?���eg10 N�@�C5��Ҭ{7���@䀞�<�����v�Z�WӴ��V���a�{���pR�.7�=�{e�Y��]Hh��PM'��U���l*-�0tu�a
-��<���q�( ��b��HgB2�fq���K�]�
-p@�����J����i�}P@��U�'�Yd:
-P�������Hq��pa!<�p 7݊5( ��b
-bK�3j���\�Ș�[p��P���Z?zp'�d
-��s��Mq�`� ӡ�U��&g������63�А]��9s�>�֍o�π2l-
-��4�t�fY�#�ʉ�ؐ��P�k�?�̭�u=|�s�K���SL�Ϸ�6G���(�y��4Cǎ�)�:��j��V�m�sc[H;�8�;Nh���7�6�v�u������ ��&R#��n�� ��ȥ��I��W�镣)�=~���ˊ,[�o��{��ǿ�?]�m
-.���|�E�>~DOn��ZS���@뇴;C��ٝS� Q>�"����JK��^����ƫ(����^?ǀL�s)J�Z��
-{�yul��ٲ}t�C��ПM������v��7��p�.K@<�����@���%�$�2a�s�V�>8x��Ps7��X�̣W)<!ϵ� ��A�a@g�����n+�<�d�GL)���V�>�B��Pu ��P�t[�D.t�m�-�f+�C%zv��#�@��)�#�(�4�X�����^�r���Y�`r'�?R����W��u(ufp�3��cj�$�1�-�Z�������&.��������tM�)'�F���F�����C&H������������V.8�҇�<��&$s���� Y���l]��mB�k.>P[ynv���~�d��_Hd/���`�x`��ny*42Yw��Wi���ŋ
-yn<$���3�@����D4�t�fu?(�q��c���O>a��84�x�����m ��Q��2��#h��I����Zn5W��.
-�#�J����I�)b��\v�{d®9�B2��z�$�˒=A"g�kS�Yr��W$�UI B&�� !b�M�ͱ�r3��g��R���:���X&���7<����ߜ�w#L`;z۲M[�y�9&��K1����LvCf�
-�)�Gf�(��
-Ŕ��O�<0ā��`���V��R��d3�z#�@��/�7gf��K^��|UL�a��NM���_��r�_��T�u��jl��V_�FȲ�F"hZ��SІ�
-[ŕ����̽v�¢nfaF�eC'��3�@�^�zX$��������
-b�7:���U��ɲꯈ�YC@^_�]��#��ƶ�]ˡ�F�=2L�f�u��t?B#��D@P��a
��f��:�f�Hwˮ����.���Q0B3����i�N�L��i��5X�U3��.(N_�9%zA`�9�B8)�el���#���!�r`�x���]{K�)q+�[��"�CN8)~T�R�@(E��p��ܣ?'-B'�܃��@~j�'P����9���ͤ���5(�8�*;�f�����QR6p0J
-L+q
-T���h��P�,7�^g�}�����Y��}�IcF�`��b��L�`H���r2B=�L��b�!�b���}��M���S�v���ô3?� K� ��FL��S�[��)�%�a��g��I-p'e:
-l�M<�c�'�5@�S��K,A &�t8<T��#��
-@ ��bRJX�T�{���ԜD&�մ�ӫ14�;́��A��ih ��b���� ӡ�Չ��V�v��&Qy��4�K��oͦm��ڶغ�DD���~s���͊���QL`��T��,ə8�:�f9͊�Y�:9>�F��A,����q����떷D���3mI���CH�2o�����$[TxCR��|��s���M>�΄,��� � ����.A�^y�,�3�VZ��7ܓ)�������
-9,aH�q��_��ԗ#s.x[پ�l[A��u�J�I�:�>;Q�`1�7$��k�*���( q��� �(��1�Ɔg��zX�͙�ڠ��iRr��NѵN�YH3;���j'�����j'�m�p�v�\h�本��x�c̱����.�Ȍ8�b�AKf��u-,.�p���.��v`=��q�zX3t�h�|][M��bGQ�76rʼn�F}6^�rV����+<ž�}�K��\��#�U͉�J�:�� �a�C��O^�A�8�fl/n�&g!���z\a�p.�0�(?b�g� �F�3�r�0���%�c#Gs�n�]�MD.�L��)̜݃����s����"�k0GR8a�ݔ�"Ξ7a�%L:�Y87�q��/+}�qj���6¿Έ�ȓ���?`;�l��G�j V�)�0#fͨe�i�}#7Qz: !&D�<�r}{�%� ���s^l���gƒ�^����2a%5��.�y����P��Uˢ��n�nw[���b���ǿ���T)��]�@ȇ��p�d�ܣ�=��E'�����]a�@h�����p�A+??��ZY�|�r���fc�Z�����h�f9lGC�W}�Q��a�q/KG��E��&6�:�
-��6'��
-�m��sZ�?������9��%3�Mݠ��p�>�KM
-�Z�s9�?�|�+d=g����\�6���>���<�͊��F+�[%��{�����z��q|@�+츾{��Pڐ5����!g47^>CG[��Mk33���?�њ̈́H�b*����[������"�h�&k�`Bf�Q����C�Q`'Z�6��B��X��yA�L�тX� ��9����|�S�hD���i�
-���H!��B�5��+SoћY8���<<W9��˽(���=���q�L�Y�Dq`}"��\��;�ǯ��9��7��1����A.��Ί�b����L;9%�����#����NﮥV6��Q�m��
-���?���ț�Zt�O�UU�?�a�%��F�����AP9�&���0nR����ߎ�m
-�}Bn���'�������{Cq����7�PKa;�v�"��PK(�A/UgH�sammoa.argoPK(�A:�&s�*ѡ�sammoa_Diagrammedeclasses.pgmlPK)�AǒV9�&�-sammoa_Diagrammedecasdutilisation.pgmlPK)�Aɟ���FA�.sammoa_Diagrammedeclasses2.pgmlPK)�AP����K�5sammoa.todoPK)�A8��7y�7sammoa_profile.profilePK)�Aa;�v�"��
-�7sammoa.xmiPK��Z
\ No newline at end of file
+�Ĕ�g1�$ ����P�T�D��P���b���Z2ӡ��'�]K��.��L�ʓfL�n۲�)S�"ZWKI
+X�t�%Ͻ�l�F�I(m!��b6 ��
+�L����2�MI����{XEJ2���<��Am�L�����{��%�p@��%O�6��͙�D&��8���dyZL5q��G�C�q@"y.�l3���gl1'�%�#Ι��)!���'u�Q�^��5�);*M�h�p�I��Ÿ ��7A�C��q�`m[%H%Ȱs\r`�cK/��j@@I┻�VV���r�(����ey��.~=��Ҡ5�WΡ���Yu�V.TJ�#W�@�r3���Pɭί�[L1 �@�C��_��o���r��,���t��QP�u���8��3����U�n�p[K�jvM[*b:��,|���NJ��&��u�,;K�о �3���W��jjˢB�2u��N:L�qσ�؛F�R-�H��p&$���8Э p7yɼ��Hq��}^ a�7�p�zA�5-�g
+��j�B5�L@*�"W��7�)�.L D�g:䦠[���YLAl �"v�C�Q@8>���?c��a2�#�S��4�&��l��a��q��i N�d:�;���B�䬐��v�]��Uh�.u��9��g�π2l-
+��4�t�fY��ʉ�ؒ��P�י>��m�u3|�s�C��9&��Q[���i��sc��ƶ�){ml6�N���
+�sc;H��8�[Nh���������u������ q��s; q���~���
+��*���є�?�8��&˦�q�qO��ט��A���Rz ͗\T����k�5GaK�~H�:D����0���,�O�g�����ݱj������r��9עTm�<�ذ����f��-�G�9�Ȍ�x�ňƧ�@���Ϣ�Ԅ[tY�i�-~��'��M�,i$��Y83���������L���DŢ�<z���#r�2����`����m��������@ ��b�Њ�Yh3�;*�V�R'8��v�0
+S��
+��P �*�H9�#E|h��H9�=�8��z���*���W���ôv���_���LJ�>o�mW��u,u�s�3�nWcj�,�1�-�Z�������&.�������n�5͢��魦:��m�&6�2A�$��w��z]08��Jn����9}��C/kB2�{k+q��L��ε]�&d����s��d�ϙ�O�χ�D���7��Fn햧B#�%p?��|�[��ؐ��c"��:��O����Ɣ�߬�oJ�����X�C�i����z����n媑,ӊ8�V����J��Qsm�誐="ɡd
+?��t�#V��U'�7@&욳/$C��Y@��,9$� �ؘ�͒cĠ"��J2I��[mrm���{�a��I[��r�͞�ji�e«�����&��L�+a��i�ikڒϓ���O��)P�>�p=0�d7d��М�L0q�`&���QL�q���@i_������0;�D����t�l&�l����%����;` «8�G�n�O������ջ)��%.L�[w���6�yu�Uk�L��'��u��k1m���U\ �����k-,�fft��l��2�`����K��TK�s��n!WA��F���*b57YV�13k(��+⛲+��xdz�"��ؖ��ݞiS�fL�n�b�u
+J�!��L"�����U
+�0�B�b3�_b3Ϥ�{e��b�@�z��$��@����v�����l�vOg9NTM/���8}����������As���x��S�hǁ�ӥ
+�ov��ĭn1J��9��YP)Jq�e����Kp�����8�s���d��t�G�@�����7����wԠ��h��8����^��'I��
+�()0��u(@PuN��F١�Yn0�
+.
+��O��)��,-�ޓƌJ/����n-��.�di1�d$�z2��łc�_;��Rsk�:�!�͑3��Z�01��a�io~� A Ӎ�^��0��L�SrJ��$�ϲ��Z�N�t�Y�x���G�k�9�S�X�@(L��p|(��+��-F�=�@��Ť:� �"�dZ���ىL�Z�iӫ1��;;��a��ih ��b���� ӡ�ՉO�V�v��&Q����4�k���̦mM��j� ���DD���~s���͊���^L`��T��,ə8�:��r����!uv|h�%��xg8T���U84{4��]��%�o~�iKj�,�Br�y+�dd�ųlQ�-I��Y������?r����"�f��r.o�Qz�D�ȟn��[k�v��@�p�_���v�a C�NC&7�xt��@�̅��d�V�=l�3�u+}&��P��L���ߐ �olt�d����E�?�l����\��[����a�7gj�>��Iɝ�:8E7:��f)��p��+k��9�w���&�H�7��n�X�1�`�本��x�S̱����.�Ȍ8�b�AKf��u-,.�p�]�.��vd=��q�zX����05�zml6�N�Eilm�S��l�8��w���#<Ǟ�=�K�t���U-��I�&�!� �a�C������#p�`l/n�&g)�O�zZa�r.�0�(?a�g� �V�3�r�0�f[�5Jt�B�f[�&�Z��\\�0oRz�9�����X�3WE��`��p�9/pE�=n�'L�tʳpN�c��/k}�qj�A@�~�_c"�r�d���[���Z��cJ��&̈X3j��C�����M��H� Q���Zk�uB���[5>癱�ע$n��_XI���j�孼�'��6ƪiR�l�c�V��>���C��o�Ap&U���C'�g:�$�!���q�����r�=��#���|�V���C˭�e·�V�l6�Фew�j"=���6�Q�P�U�lu�l<��gtQ��� ��ƍN't���Y#o�Evs�D�����#���D�H{����Ή�nP�Z:q�ڥ��� ��۹��D>�5��2�ED�u�k�J�x���x��fMP҅
+��Э�"���� �d���8ޣ�ێ��4�6f
+��w�E�ͭ7����>j��Ό"��Or�f;!���=?����z|�Ȁ0Zn��ПQ�90GT?;��b�[�y��&V,��ɼ @���hA�̐cw�y���6_�����K�y��Bn��)D���5cW��2w����Q��G��8X��_t ��(��{����H��q���o~"��M���;>�F/7�=���7�������Q��ad�w���IG�������d�Z�����h����Rk~�(��6�چ��匟b�g���]���T�OnX(B�_�����"��ywT���kk1��>=��p[n���-����n�r��뿽{CQ����W�PK/��"p�PK]Z%A��DH�sammoa.argoPK]Z%A�[�+ѡ�sammoa_Diagrammedeclasses.pgmlPK`Z%AǒV9�&�-sammoa_Diagrammedecasdutilisation.pgmlPK`Z%Aɟ���FA�.sammoa_Diagrammedeclasses2.pgmlPK`Z%AP����K 6sammoa.todoPK`Z%A8��7y�&7sammoa_profile.profilePK`Z%A/��"p�
+�7sammoa.xmiPK�)Z
\ No newline at end of file
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/NextAction.java
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/NextAction.java 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/NextAction.java 2012-09-05 14:03:46 UTC (rev 524)
@@ -44,7 +44,7 @@
public NextAction(JAXXContext context) {
super(_("sammoa.action.next"), context);
putValue(Action.SHORT_DESCRIPTION, _("sammoa.action.next.tip"));
- bindModelProperties(FlightUIModel.PROPERTY_FLIGHT_STATE);
+ bindModelProperties(FlightUIModel.PROPERTY_FLIGHT_STATE, FlightUIModel.PROPERTY_NEXT_TRANSECT);
}
@Override
Modified: trunk/src/site/site.xml
===================================================================
--- trunk/src/site/site.xml 2012-09-05 14:03:26 UTC (rev 523)
+++ trunk/src/site/site.xml 2012-09-05 14:03:46 UTC (rev 524)
@@ -30,7 +30,7 @@
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
- <version>1.2.1</version>
+ <version>1.3.0</version>
</skin>
<custom>
1
0
r523 - in trunk/sammoa-ui-swing/src/main: java/fr/ulr/sammoa/ui/swing/home resources/i18n
by fdesbois@users.forge.codelutin.com 05 Sep '12
by fdesbois@users.forge.codelutin.com 05 Sep '12
05 Sep '12
Author: fdesbois
Date: 2012-09-05 16:03:26 +0200 (Wed, 05 Sep 2012)
New Revision: 523
Url: http://forge.codelutin.com/repositories/revision/sammoa/523
Log:
refs #1434 : resolve text for flightNumber less than
Modified:
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/home/HomeUIHandler.java
trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/home/HomeUIHandler.java
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/home/HomeUIHandler.java 2012-09-05 13:05:30 UTC (rev 522)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/home/HomeUIHandler.java 2012-09-05 14:03:26 UTC (rev 523)
@@ -299,7 +299,7 @@
if (flightNumber < nextFlightNumber) {
SammoaUtil.showErrorMessage(
- ui, _("sammoa.inputDialog.flightNumber.error.greaterThanNextFlightNumber", nextFlightNumber));
+ ui, _("sammoa.inputDialog.flightNumber.error.lessThanNextFlightNumber", nextFlightNumber));
} else {
Modified: trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties
===================================================================
--- trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-05 13:05:30 UTC (rev 522)
+++ trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-05 14:03:26 UTC (rev 523)
@@ -103,7 +103,7 @@
sammoa.info.importApplication.importfile.loaded.on.existingCampaign=Import an existing campaign %s, please choose which flights of the following list to import
sammoa.info.importApplication.importfile.loaded.on.newCampaign=Import a new campaign %s, all the flights of the following list will be imported
sammoa.info.importApplication.no.importfile.loaded=No import file loaded, choose an file to import then press the 'load import file' button
-sammoa.inputDialog.flightNumber.error.greaterThanNextFlightNumber=The flight number can't be greater than %d
+sammoa.inputDialog.flightNumber.error.lessThanNextFlightNumber=The flight number can't be less than %d
sammoa.inputDialog.flightNumber.error.notANumber=The flight number must be a valid integer
sammoa.inputDialog.flightNumber.message=Choose the flight number
sammoa.label.campaign=Campaign\:
1
0
r522 - trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio
by bpoussin@users.forge.codelutin.com 05 Sep '12
by bpoussin@users.forge.codelutin.com 05 Sep '12
05 Sep '12
Author: bpoussin
Date: 2012-09-05 15:05:30 +0200 (Wed, 05 Sep 2012)
New Revision: 522
Url: http://forge.codelutin.com/repositories/revision/sammoa/522
Log:
suppression d'import inutilise
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java 2012-09-04 23:44:49 UTC (rev 521)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java 2012-09-05 13:05:30 UTC (rev 522)
@@ -4,8 +4,6 @@
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
-import javax.media.CannotRealizeException;
-import javax.media.NoPlayerException;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.BorderFactory;
@@ -232,7 +230,7 @@
public static void main( String args[])
- throws LineUnavailableException, UnsupportedAudioFileException, IOException, NoPlayerException, CannotRealizeException{
+ throws LineUnavailableException, UnsupportedAudioFileException, IOException {
new AudioTest();
// float sampleRate = 8000; // 8000,11025,16000,22050,44100
1
0
r521 - trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio
by bpoussin@users.forge.codelutin.com 04 Sep '12
by bpoussin@users.forge.codelutin.com 04 Sep '12
04 Sep '12
Author: bpoussin
Date: 2012-09-05 01:44:49 +0200 (Wed, 05 Sep 2012)
New Revision: 521
Url: http://forge.codelutin.com/repositories/revision/sammoa/521
Log:
Composant de lecture audio et fenetre de test de l'audio
Pas de compression (speex ou flac ne fonctionne pas pour l'instant :()
ps: vraiment pas la bonne place, mais je prefere commit et
laisser florian le deplacer la ou il faut.
Added:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java
Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java (rev 0)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioTest.java 2012-09-04 23:44:49 UTC (rev 521)
@@ -0,0 +1,330 @@
+package fr.ulr.sammoa.application.device.audio;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import javax.media.CannotRealizeException;
+import javax.media.NoPlayerException;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Petite application de test de l'audio. Elle permet de choisir differente
+ * configuration audio. De faire des enregistrements et de relire le fichier
+ * enregistre.
+ * <p>
+ * La configuration choisi est inscrite et permet de la copier dans le fichier
+ * de configuration
+ * <p>
+ * Si la machine ne supporte pas deux enregistrement simultane, delay est mis
+ * a 0.
+ *
+ * Created: 27 aout 2012
+ *
+ * @author Benjamin POUSSIN <poussin(a)codelutin.com>
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class AudioTest extends JFrame {
+
+ private static final Logger logger = LoggerFactory.getLogger(AudioTest.class);
+
+ protected SammoaAudioRecorder recorder;
+ /** delay par defaut de chevauchement d'enregistrement */
+ protected int delay = 0;
+
+ protected JTextField filenameField = new JTextField("/tmp/junkk.wav");
+ protected JTextArea informationArea = new JTextArea();
+
+ protected JButton captureBtn = new JButton("Capture");
+ protected JButton stopBtn = new JButton("Stop");
+ protected JButton loadBtn = new JButton("Load");
+ protected SoundPlayer playerPanel = new SoundPlayer();
+
+ protected JPanel btnPanelSampleRate = new JPanel();
+ protected ButtonGroup btnGroupSampleRate = new ButtonGroup();
+ JRadioButton[] btnSampleRate = new JRadioButton[]{
+ new JRadioButton("8000",true),
+ new JRadioButton("11025"),
+ new JRadioButton("16000"),
+ new JRadioButton("22050"),
+ new JRadioButton("44100")
+ };
+
+ protected JPanel btnPanelSampleSizeInBits = new JPanel();
+ protected ButtonGroup btnGroupSampleSizeInBits = new ButtonGroup();
+ JRadioButton[] btnSampleSizeInBits = new JRadioButton[]{
+ new JRadioButton("8"),
+ new JRadioButton("16",true)
+ };
+
+ public AudioTest(){//constructor
+ initUI();
+ testMultiRecord();
+ }
+
+ protected void initUI () {
+ Box buttons = Box.createHorizontalBox();
+ buttons.add(captureBtn);
+ buttons.add(stopBtn);
+
+ Box box = Box.createVerticalBox();
+ box.add(filenameField);
+ box.add(buttons);
+
+ for (JRadioButton b : btnSampleRate) {
+ //Include the radio buttons in a group
+ btnGroupSampleRate.add(b);
+ //Add the radio buttons to the JPanel
+ btnPanelSampleRate.add(b);
+ b.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ updateConfigInfo();
+ }
+ });
+ }
+
+ //Put the JPanel in the JFrame
+ box.add(btnPanelSampleRate);
+
+ for (JRadioButton b : btnSampleSizeInBits) {
+ //Include the radio buttons in a group
+ btnGroupSampleSizeInBits.add(b);
+ //Add the radio buttons to the JPanel
+ btnPanelSampleSizeInBits.add(b);
+ b.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ updateConfigInfo();
+ }
+ });
+ }
+
+ //Put the JPanel in the JFrame
+ box.add(btnPanelSampleSizeInBits);
+
+ informationArea.setBorder(BorderFactory.createRaisedBevelBorder());
+ informationArea.setLineWrap(true);
+ box.add(informationArea);
+ box.add(loadBtn);
+ box.add(playerPanel);
+
+ //Finish the GUI and make visible
+ setTitle("Sound Test");
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
+ getContentPane().add(box, "Center");
+ pack();
+ setVisible(true);
+
+ captureBtn.setEnabled(true);
+ stopBtn.setEnabled(false);
+
+ // ADD LISTENER
+
+ //Register anonymous listeners
+ captureBtn.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ captureBtn.setEnabled(false);
+ stopBtn.setEnabled(true);
+ captureAudio();
+ }
+ });
+
+ stopBtn.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ captureBtn.setEnabled(true);
+ stopBtn.setEnabled(false);
+ recorder.stop();
+ }
+ });
+
+ loadBtn.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(
+ ActionEvent e){
+ File file = new File(filenameField.getText());
+ playerPanel.loadFile(file);
+ }
+ });
+ }
+
+ protected void captureAudio(){
+ try{
+ File file = new File(filenameField.getText());
+ recorder = new SammoaAudioRecorder(getSampleRate(), getSampleSizeInBits(), 0);
+ recorder.record(file, true);
+ }catch (Exception eee) {
+ logger.error("Can't capture audio", eee);
+ }
+ }
+
+ protected float getSampleRate() {
+ float result = 44100;
+ for (JRadioButton b : btnSampleRate) {
+ if (b.isSelected()) {
+ result = Float.parseFloat(b.getText());
+ }
+ }
+ return result;
+ }
+
+ protected int getSampleSizeInBits() {
+ int result = 44100;
+ for (JRadioButton b : btnSampleSizeInBits) {
+ if (b.isSelected()) {
+ result = Integer.parseInt(b.getText());
+ }
+ }
+ return result;
+ }
+
+ protected void updateConfigInfo() {
+ informationArea.setText(String.format(
+ "sammoa.audio.recordDelayInSeconds=%s\n"
+ + "sammoa.audio.sampleRate=%s\n"
+ + "sammoa.audio.sampleSizeInBits=%s\n",
+ delay, getSampleRate(), getSampleSizeInBits()));
+ }
+
+ protected void testMultiRecord() {
+ try {
+ File f1 = File.createTempFile("sammoa-test-", ".wav");
+ f1.deleteOnExit();
+ File f2 = File.createTempFile("sammoa-test-", ".wav");
+ f2.deleteOnExit();
+
+ SammoaAudioRecorder r1 = new SammoaAudioRecorder(8000, 16, 2);
+ r1.record(f1, true);
+
+ SammoaAudioRecorder r2 = new SammoaAudioRecorder(8000, 16, 2);
+ r2.record(f2, true);
+
+ r2.stop();
+ r1.stop();
+ delay = 5;
+ } catch(Exception eee) {
+ logger.error("Can't record multiple file in same time", eee);
+ delay = 0;
+ }
+ updateConfigInfo();
+ }
+
+
+ public static void main( String args[])
+ throws LineUnavailableException, UnsupportedAudioFileException, IOException, NoPlayerException, CannotRealizeException{
+ new AudioTest();
+
+// float sampleRate = 8000; // 8000,11025,16000,22050,44100
+// int sampleSizeInBits = 16; // 8,16
+//
+// int channels = 1; // 1,2
+// boolean signed = true; //true,false
+// boolean bigEndian = false; //true,false
+//
+// AudioFormat audioFormat = new AudioFormat(
+// sampleRate,
+// sampleSizeInBits,
+// channels,
+// signed,
+// bigEndian);
+//
+// DataLine.Info dataLineInfo = new DataLine.Info(
+// TargetDataLine.class, audioFormat);
+// {
+// TargetDataLine l1 = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
+// System.out.println("Line: " + l1);
+// System.out.println("Line: " + l1.getLineInfo());
+// l1.open(audioFormat);
+// l1.start();
+//
+// TargetDataLine l2 = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
+// System.out.println("Line: " + l2);
+// System.out.println("Line: " + l2.getLineInfo());
+// l2.open(audioFormat);
+// l1.start();
+// }
+// {
+// AudioFileFormat aff = AudioSystem.getAudioFileFormat(new File("/tmp/junkk.wav"));
+// System.out.println("File: "+ aff.toString());
+// AudioInputStream sourceAis = AudioSystem.getAudioInputStream(new File("/tmp/junkk.wav"));
+//
+// DataLine.Info clipInfo = new DataLine.Info(Clip.class, audioFormat);
+// Clip clip = (Clip)AudioSystem.getLine(clipInfo);
+//
+// AudioInputStream ais = AudioSystem.getAudioInputStream(audioFormat, sourceAis);
+//// clip.open(ais);
+//// clip.start();
+// }
+// {
+// File f = new File("/tmp/junkk.wav");
+// Player p = Manager.createRealizedPlayer(f.toURI().toURL());
+// p.start();
+//// p.set
+// }
+//
+// System.out.println("#############################################");
+// Line.Info[] sources = AudioSystem.getSourceLineInfo(new Line.Info(SourceDataLine.class));
+// Line.Info[] target = AudioSystem.getTargetLineInfo(new Line.Info(TargetDataLine.class));
+//
+// System.out.println("AudioFileTypes:" + Arrays.toString(AudioSystem.getAudioFileTypes()));
+//
+// System.out.println("mixer:" + Arrays.toString(AudioSystem.getMixerInfo()));
+// for(Mixer.Info i : AudioSystem.getMixerInfo()) {
+// Mixer mixer = AudioSystem.getMixer(i);
+// System.out.println("-----");
+// System.out.println("mixer:" + mixer + "("+mixer.isLineSupported(Port.Info.MICROPHONE)+")");
+// try {
+// mixer.open();
+// } catch (LineUnavailableException eee) {
+// System.out.println("Can't open mixer");
+// }
+// System.out.println("mixer:" + mixer + "("+mixer.isLineSupported(Port.Info.MICROPHONE)+")");
+//
+// System.out.println("mixer info: " + mixer.getLineInfo());
+// System.out.println("max line: " + mixer.getMaxLines(mixer.getLineInfo()));
+//
+// for (Line.Info li : mixer.getSourceLineInfo()) {
+// System.out.println("s line info: " + li + "("+mixer.getMaxLines(li)+")");
+// System.out.println("s line info: " + li.getLineClass());
+// }
+//
+// for (Line.Info li : mixer.getTargetLineInfo()) {
+// System.out.println("t line info: " + li + "("+mixer.getMaxLines(li)+")");
+// System.out.println("t line info: " + li.getLineClass());
+// }
+//
+// for (Line l : mixer.getSourceLines()) {
+// System.out.println("s line: " + l);
+// System.out.println("s line info: " + l.getLineInfo());
+// }
+// for (Line l : mixer.getTargetLines()) {
+// System.out.println("t line: " + l);
+// System.out.println("t line info: " + l.getLineInfo());
+// }
+// }
+// System.out.println("sources: " + Arrays.toString(sources));
+// System.out.println("target: " + Arrays.toString(target));
+
+ }
+}
\ No newline at end of file
Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java (rev 0)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SoundPlayer.java 2012-09-04 23:44:49 UTC (rev 521)
@@ -0,0 +1,225 @@
+package fr.ulr.sammoa.application.device.audio;
+
+import fr.ulr.sammoa.application.device.DeviceState;
+import fr.ulr.sammoa.application.device.DeviceStateEvent;
+import fr.ulr.sammoa.application.device.DeviceStateListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ * Composant qui permet de charge un fichier audio et de le jouer. On peut se
+ * placer ou l'on veut dans le fichier audio.
+ *
+ * usage:
+ * <li> SoundPlayer sp = new SoundPlayer();
+ * <li> panel.add(sp);
+ * <li> sp.load(myFileWav);
+ *
+ * Created: 03 septembre 2012
+ *
+ * @author Benjamin POUSSIN <poussin(a)codelutin.com>
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class SoundPlayer extends JComponent implements DeviceStateListener {
+ protected SammoaAudioReader reader;
+ protected boolean playing = false; // whether the sound is currently playing
+
+ // The following fields are for the GUI
+ protected JButton play; // The Play/Stop button
+ protected JSlider progress; // Shows and sets current position in sound
+ protected JLabel time; // Displays audioPosition as a number
+ protected JLabel maxTime;
+
+ // Create a SoundPlayer component for the specified file.
+ public SoundPlayer() {
+ initUI();
+ initAudio();
+ }
+
+ protected void initUI() {
+ // Now create the basic GUI
+ play = new JButton("Play"); // Play/stop button
+ progress = new JSlider(0, 0, 0); // Shows position in sound
+ progress.setMajorTickSpacing(60000);
+ progress.setMinorTickSpacing(10000);
+ progress.setPaintTicks(true);
+ progress.setPaintLabels(true);
+
+ time = new JLabel("0"); // Shows position as a #
+ maxTime = new JLabel("/0"); // Shows position as a #
+
+ // put those controls in a row
+ Box row = Box.createHorizontalBox( );
+ row.add(play);
+ row.add(progress);
+ row.add(time);
+ row.add(maxTime);
+
+ // And add them to this component.
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ this.add(row);
+
+ // ADD LISTENER
+
+ // When clicked, start or stop playing the sound
+ play.addActionListener(new ActionListener( ) {
+ public void actionPerformed(ActionEvent e) {
+ if (playing) {
+ stop( );
+ } else {
+ play( );
+ }
+ }
+ });
+
+ progress.addMouseListener(new MouseAdapter() {
+ boolean inPlay = false;
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ inPlay= playing;
+ if (inPlay) {
+ reader.stop();
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ int value = progress.getValue( );
+ // Update the time label
+ time.setText(value/1000 + "." + (value%1000)/100);
+ // If we're not already there, skip there.
+ if (value >= 0 && value <= reader.getLength()) {
+ reader.setPosition(value);
+ }
+
+ if (inPlay) {
+ reader.start();
+ }
+ }
+ });
+
+ // Whenever the slider value changes, update the time label.
+ progress.addChangeListener(new ChangeListener( ) {
+ public void stateChanged(ChangeEvent e) {
+ int value = progress.getValue( );
+ time.setText(value/1000 + "." + (value%1000)/100);
+ }
+ });
+ }
+
+ protected void initAudio() {
+ reader = new SammoaAudioReader();
+ reader.addDeviceStateListener(this);
+ // on se met listener de l'avancee de la lecture
+ reader.addAudioPositionListener(new SammoaAudioReader.AudioPositionListener() {
+ public void positionChange(Object source, long audioPosition) {
+ progress.setValue((int)audioPosition);
+ }
+ });
+
+ }
+
+ public void stateChanged(DeviceStateEvent event) {
+ DeviceState state = event.getNewValue();
+ if (state == DeviceState.RUNNING) {
+ this.playing = true;
+ play.setText("Stop");
+ } else {
+ this.playing = false;
+ play.setText("Play");
+ }
+ }
+
+ /**
+ * Charge un nouveau fichier
+ * @param f le fichier a charger
+ */
+ public void loadFile(File f) {
+ getAudioReader().load(f);
+ long value = getLength();
+ progress.setMaximum((int)value);
+ maxTime.setText("/" + value/1000 + "." + (value%1000)/100);
+ }
+
+ /**
+ * retourne le lecture utilise par ce composant
+ * @return
+ */
+ public SammoaAudioReader getAudioReader() {
+ return reader;
+ }
+
+ /**
+ * Donne la position actuelle de la lecture en milliseconde
+ * @return
+ */
+ public long getPosition() {
+ return getAudioReader().getPosition();
+ }
+
+ /**
+ * Donne la longueur total du fichier en milliseconde
+ * @return
+ */
+ public long getLength() {
+ return getAudioReader().getLength();
+ }
+
+ /**
+ * Start playing the sound at the current position
+ */
+ public void play() {
+ getAudioReader().start();
+ }
+
+ /**
+ * Stop playing the sound, but retain the current position
+ */
+ public void stop() {
+ getAudioReader().stop();
+ }
+
+ // The main method just creates a SoundPlayer in a Frame and displays it
+ public static void main(String[] args)
+ throws IOException, UnsupportedAudioFileException, LineUnavailableException {
+ SoundPlayer player;
+
+ File file;
+ if (args.length == 0) {
+ file = new File("/tmp/junkk1.wav");
+ } else {
+ file = new File(args[0]);
+ }
+
+ // Create a SoundPlayer object to play the sound.
+ player = new SoundPlayer();
+ player.loadFile(file);
+
+ // Put it in a window and play it
+ JFrame f = new JFrame("SoundPlayer");
+ f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ f.getContentPane().add(player, "Center");
+ f.pack();
+ f.setVisible(true);
+ }
+
+}
\ No newline at end of file
1
0
r520 - trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio
by bpoussin@users.forge.codelutin.com 04 Sep '12
by bpoussin@users.forge.codelutin.com 04 Sep '12
04 Sep '12
Author: bpoussin
Date: 2012-09-05 01:42:36 +0200 (Wed, 05 Sep 2012)
New Revision: 520
Url: http://forge.codelutin.com/repositories/revision/sammoa/520
Log:
lecteur et enregistreur fonctionnel
Added:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java
Copied: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java (from rev 479, trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java)
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java (rev 0)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioReader.java 2012-09-04 23:42:36 UTC (rev 520)
@@ -0,0 +1,316 @@
+package fr.ulr.sammoa.application.device.audio;
+/*
+ * #%L
+ * SAMMOA :: Application
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2012 UMS 3462, Code Lutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.base.Preconditions;
+import fr.ulr.sammoa.application.device.DeviceState;
+import fr.ulr.sammoa.application.device.DeviceStateEvent;
+import fr.ulr.sammoa.application.device.DeviceStateListener;
+import fr.ulr.sammoa.application.device.DeviceTechnicalException;
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Classe permettant la lecture d'un fichier audio, et de ce deplace a une
+ * position souhaite dans ce fichier.
+ *
+ * Created: 04 septembre 2012
+ *
+ * @author Benjamin POUSSIN <poussin(a)codelutin.com>
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class SammoaAudioReader implements AudioReader {
+
+ private static final Logger logger = LoggerFactory.getLogger(SammoaAudioReader.class);
+
+ protected Clip clip; // Contents of a sampled audio file
+ protected AudioPositionTraker audioPositionTraker;
+
+ // Length and position of the sound are measured in milliseconds for
+ // sampled sounds
+ protected long audioLength; // Length of the sound.
+ protected long audioPosition = 0; // Current position within the sound
+
+ protected DeviceState state = DeviceState.UNAVAILABLE;
+
+ protected Set<DeviceStateListener> listeners = new HashSet<DeviceStateListener>();
+ protected Set<AudioPositionListener> audioPositionListener = new HashSet<AudioPositionListener>();
+
+ /**
+ * Permet de se mettre listener sur l'avancement de la lecture du fichier
+ */
+ static public interface AudioPositionListener {
+ /**
+ *
+ * @param source La source de l'evenement
+ * @param audioPosition la nouvelle position en milliseconds
+ */
+ public void positionChange(Object source, long audioPosition);
+ }
+
+ /**
+ * Classe servant a surveiller l'avancement de la lecture
+ * et a prevenir les listeners
+ */
+ static protected class AudioPositionTraker {
+ static final protected long STEP = 100; // toutes les 100 ms
+
+ protected Timer timer;
+ protected TimerTask task;
+ protected SammoaAudioReader reader;
+
+ public AudioPositionTraker(SammoaAudioReader reader) {
+ timer = new Timer("SammoaAudioReader");
+ this.reader = reader;
+ }
+
+ /**
+ * Demarre la surveillance
+ */
+ public void start() {
+ task = new TimerTask() {
+ @Override
+ public void run() {
+ if (reader.clip.isActive()) {
+ // on appele pas setPosition car, sinon on modifie la position dans le clips :(
+ // alors que c'est lui qu'on surveille et qui fait le changement
+ long old = reader.audioPosition;
+ long position = reader.getClip().getMicrosecondPosition()/1000L;
+ if (old != position) {
+ reader.audioPosition = position;
+ reader.firePositionChange(position);
+ }
+ } else {
+ reader.stop();
+ reader.setPosition(0);
+ }
+ }
+ };
+ timer.schedule(task , 0, STEP);
+ }
+
+ /**
+ * Arrete la surveillance
+ */
+ public void stop() {
+ if (task != null) {
+ task.cancel();
+ task = null;
+ }
+ }
+
+ }
+
+ public SammoaAudioReader() {
+ audioPositionTraker = new AudioPositionTraker(this);
+ }
+
+ public Clip getClip() {
+ return clip;
+ }
+
+ @Override
+ public AudioFileFormat.Type getOutputType() {
+ return AudioFileFormat.Type.WAVE;
+ }
+
+ @Override
+ public void load(File file) {
+ Preconditions.checkNotNull(file);
+ Preconditions.checkArgument(file.exists());
+ unload();
+ try {
+ // Getting a Clip object for a file of sampled audio data is kind
+ // of cumbersome. The following lines do what we need.
+ AudioInputStream ain = AudioSystem.getAudioInputStream(file);
+
+ // Get information about the format of the stream
+ AudioFormat format = ain.getFormat( );
+ DataLine.Info info = new DataLine.Info(Clip.class, format);
+
+ if (!AudioSystem.isLineSupported(info)) {
+ // This is the PCM format we want to transcode to.
+ // The parameters here are audio format details that you
+ // shouldn't need to understand for casual use.
+ AudioFormat pcm =
+ new AudioFormat(format.getSampleRate( ), 16,
+ format.getChannels( ), true, false);
+
+ // Get a wrapper stream around the input stream that does the
+ // transcoding for us.
+ ain = AudioSystem.getAudioInputStream(pcm, ain);
+
+ // Update the format and info variables for the transcoded data
+ format = ain.getFormat( );
+ info = new DataLine.Info(Clip.class, format);
+ }
+
+ try {
+ clip = (Clip) AudioSystem.getLine(info);
+ clip.open(ain);
+ }
+ finally { // We're done with the input stream.
+ ain.close( );
+ }
+ // Get the clip length in microseconds and convert to milliseconds
+ audioLength = (int)(clip.getMicrosecondLength( )/1000);
+
+ setState(DeviceState.READY);
+ logger.debug(String.format("Sound file '%s' loaded", file));
+ } catch (Exception eee) {
+ logger.error(String.format("Can't load audio file '%s'",file), eee);
+ setState(DeviceState.ERROR);
+ }
+
+ }
+
+ @Override
+ public void unload() {
+ if (clip != null) {
+ stop();
+ clip.close();
+ clip = null;
+ }
+ setState(DeviceState.UNAVAILABLE);
+ }
+
+ @Override
+ public long getLength() {
+ return audioLength;
+ }
+
+ @Override
+ public void setPosition(long position) {
+ if (clip != null) {
+ long old = audioPosition;
+ this.audioPosition = position;
+ if (old != position ) {
+ clip.setMicrosecondPosition(position * 1000L);
+ firePositionChange(position);
+ }
+ }
+ }
+
+ protected void firePositionChange(long position) {
+ for (AudioPositionListener l : audioPositionListener) {
+ l.positionChange(this, position);
+ }
+ }
+
+ @Override
+ public long getPosition() {
+ return audioPosition;
+ }
+
+ @Override
+ public void open() throws DeviceTechnicalException {
+ // no state set here, only open device and throw error
+ }
+
+ @Override
+ public void start() {
+ if (clip != null) {
+ clip.start();
+ audioPositionTraker.start(); // all time start tracker after clip
+ logger.debug("Sound playing");
+ if (state == DeviceState.READY) {
+ setState(DeviceState.RUNNING);
+ }
+ }
+ }
+
+ @Override
+ public void stop() {
+ logger.debug("Stop playing");
+ audioPositionTraker.stop();
+ if (clip != null) {
+ clip.stop( );
+ }
+
+ if (state == DeviceState.RUNNING) {
+ setState(DeviceState.READY);
+ }
+ }
+
+ @Override
+ public void close() throws DeviceTechnicalException {
+ unload();
+ }
+
+ @Override
+ public DeviceState getState() {
+ return state;
+ }
+
+ protected void setState(DeviceState state) {
+ DeviceState oldValue = getState();
+ this.state = state;
+
+ DeviceStateEvent event = new DeviceStateEvent(this, oldValue, state);
+ for (DeviceStateListener listener : listeners) {
+ listener.stateChanged(event);
+ }
+ }
+
+ @Override
+ public void addDeviceStateListener(DeviceStateListener listener) {
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeDeviceStateListener(DeviceStateListener listener) {
+ listeners.remove(listener);
+ }
+
+ @Override
+ public Set<DeviceStateListener> getDeviceStateListeners() {
+ return listeners;
+ }
+
+ public void addAudioPositionListener(AudioPositionListener listener) {
+ audioPositionListener.add(listener);
+ }
+
+ public void removeAudioPositionListener(AudioPositionListener listener) {
+ audioPositionListener.remove(listener);
+ }
+
+ public Set<AudioPositionListener> getAudioPositionListeners() {
+ return audioPositionListener;
+ }
+}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-09-04 23:41:55 UTC (rev 519)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-09-04 23:42:36 UTC (rev 520)
@@ -30,9 +30,11 @@
import fr.ulr.sammoa.application.device.DeviceStateEvent;
import fr.ulr.sammoa.application.device.DeviceStateListener;
import fr.ulr.sammoa.application.device.DeviceTechnicalException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
@@ -40,16 +42,27 @@
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
+import org.apache.commons.io.FilenameUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * Created: 16/05/12
+ * Classe permettant l'enregistrement d'un fichier audio. Par defaut la
+ * methode record n'ecrase jamais un fichier existant mais incremente le nom
+ * du fichier.
+ *
+ * Pour l'instant aucune compression n'est faite. Si on souhaite une compression
+ * il faut trouver une librairie de compression et modifier la ligne 284
+ * AudioFormat.Encoding targetEncoding = AudioFormat.Encoding.PCM_SIGNED;
+ * pour utilise le format de compression choisi.
+ *
+ * Created: 27 aout 2012
*
- * @author fdesbois <desbois(a)codelutin.com>
+ * @author Benjamin POUSSIN <poussin(a)codelutin.com>
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
*/
public class SammoaAudioRecorder implements AudioRecorder {
@@ -67,16 +80,35 @@
protected AudioRecorderThread currentRecorder;
+ protected int delay;
+
public SammoaAudioRecorder(AudioConfig config) {
this.config = config;
+ init(config.getSampleRate(), config.getSampleSizeInBits(),
+ config.getRecordDelayInSeconds());
+ }
+ /**
+ * Permet de forcer le sampleRate et sampleSizeInBits
+ * @param sampleRate 8000, 11025, 16000, 22050, 44100
+ * @param sampleSizeInBits 8 ou 16
+ * @param delay le delai avant de reellement coupe un enregistrement (tous
+ * les PC ne le supporte pas)
+ */
+ public SammoaAudioRecorder(float sampleRate, int sampleSizeInBits, int delay) {
+ init(sampleRate, sampleSizeInBits, delay);
+ }
+
+ protected void init(float sampleRate, int sampleSizeInBits, int delay) {
+ this.delay = delay;
+
int channels = 1; // 1,2
boolean signed = true; // true,false
boolean bigEndian = false; // true,false
audioFormat = new AudioFormat(
- config.getSampleRate(),
- config.getSampleSizeInBits(),
+ sampleRate,
+ sampleSizeInBits,
channels,
signed,
bigEndian);
@@ -132,20 +164,11 @@
// nothing to do
}
+
@Override
public void record(File outputFile) {
- Preconditions.checkNotNull(outputFile);
-
try {
- // stop last started if necessary
- stop();
- // start new recorder thread
- currentRecorder = new AudioRecorderThread(
- audioFormat, outputType, outputFile, config.getRecordDelayInSeconds(), this);
- currentRecorder.start();
-
- setState(DeviceState.RUNNING, null);
-
+ recordStream(outputFile, false);
} catch (LineUnavailableException ex) {
fireError("Error recording " + outputFile.getName(), ex);
} catch (IllegalArgumentException ex) {
@@ -157,6 +180,49 @@
}
}
+ /**
+ * Cette methode laisse passer les exceptions sans les intercepter
+ * @param outputFile
+ * @param overwrite
+ * @throws LineUnavailableException
+ */
+ public void record(File outputFile, boolean overwrite) throws LineUnavailableException {
+ recordStream(outputFile, overwrite);
+ }
+
+ /***
+ *
+ * @param outputFile
+ * @param overwrite si faux alors on recherche un nom de fichier inexistant
+ * pour l'utiliser à la place du fichier d'entre. Par exemple si toto.wav
+ * est déjà existant, alors toto-1.wav sera utilise ou toto-2.wav, ...
+ */
+ public void recordStream(File outputFile, boolean overwrite) throws LineUnavailableException {
+ Preconditions.checkNotNull(outputFile);
+
+ if (!overwrite && outputFile.exists()) {
+ // recherche du premier fichier inexistant
+ String path = outputFile.getName();
+ String filename = FilenameUtils.getBaseName(path);
+ String ext = FilenameUtils.getExtension(path);
+
+ int i = 1;
+ while (outputFile.exists() && i < Integer.MAX_VALUE) {
+ outputFile = new File(path + "-"+(i++) + ext);
+ }
+ }
+
+ // stop last started if necessary
+ stop();
+ // start new recorder thread
+ currentRecorder = new AudioRecorderThread(
+ audioFormat, outputType, outputFile, delay, this);
+ currentRecorder.start();
+
+ setState(DeviceState.RUNNING, null);
+
+ }
+
@Override
public void stopRecord() {
stop();
@@ -211,7 +277,8 @@
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
- AudioFormat.Encoding targetEncoding = AudioFormat.Encoding.ULAW;
+ AudioFormat.Encoding targetEncoding = AudioFormat.Encoding.PCM_SIGNED; //ULAW;
+
targetDataLine.open(audioFormat);
targetDataLine.start();
stream = new AudioInputStream(targetDataLine);
1
0
r519 - trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio
by bpoussin@users.forge.codelutin.com 04 Sep '12
by bpoussin@users.forge.codelutin.com 04 Sep '12
04 Sep '12
Author: bpoussin
Date: 2012-09-05 01:41:55 +0200 (Wed, 05 Sep 2012)
New Revision: 519
Url: http://forge.codelutin.com/repositories/revision/sammoa/519
Log:
Par defaut 16 bits, 8 est vraiment trop mauvais
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java 2012-09-04 16:12:27 UTC (rev 518)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java 2012-09-04 23:41:55 UTC (rev 519)
@@ -73,7 +73,7 @@
SAMPLE_SIZE_IN_BITS(
"sammoa.audio.sampleSizeInBits",
n_("sammoa.config.audio.sampleSizeInBits"),
- "8",
+ "16",
Integer.class
),
/** Time in seconds between each record, this will record in multiple files */
1
0
r518 - trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio
by bpoussin@users.forge.codelutin.com 04 Sep '12
by bpoussin@users.forge.codelutin.com 04 Sep '12
04 Sep '12
Author: bpoussin
Date: 2012-09-04 18:12:27 +0200 (Tue, 04 Sep 2012)
New Revision: 518
Url: http://forge.codelutin.com/repositories/revision/sammoa/518
Log:
si pas de delai on ferme tout de suite sans timer
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-09-04 16:05:15 UTC (rev 517)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-09-04 16:12:27 UTC (rev 518)
@@ -228,18 +228,25 @@
logger.debug("Ask for stop record... close in {} seconds",
delayToClose);
}
- Timer timer = new Timer();
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- targetDataLine.stop();
- targetDataLine.close();
- if (logger.isDebugEnabled()) {
- logger.debug("Closing record: {}", file);
+ if (delayToClose == 0) {
+ targetDataLine.stop();
+ targetDataLine.close();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Closing record: {}", file);
+ }
+ } else {
+ Timer timer = new Timer();
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ targetDataLine.stop();
+ targetDataLine.close();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Closing record: {}", file);
+ }
}
-
- }
- }, delayToClose * 1000);
+ }, delayToClose * 1000);
+ }
}
@Override
1
0
04 Sep '12
Author: fdesbois
Date: 2012-09-04 18:05:15 +0200 (Tue, 04 Sep 2012)
New Revision: 517
Url: http://forge.codelutin.com/repositories/revision/sammoa/517
Log:
refs #1197 : add configuration for audio + improve FlightController behavior with devices
Added:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java
Modified:
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorder.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderMock.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java
trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java
trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties
trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java
trunk/sammoa-ui-swing/pom.xml
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java
trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -27,6 +27,7 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
+import fr.ulr.sammoa.application.device.audio.AudioConfig;
import fr.ulr.sammoa.application.device.gps.GpsConfig;
import fr.ulr.sammoa.persistence.AutoSaveListener;
import org.apache.commons.io.FileUtils;
@@ -89,6 +90,8 @@
protected GpsConfig gpsConfig;
+ protected AudioConfig audioConfig;
+
public SammoaConfig(String file, String... args) {
applicationConfig = new ApplicationConfig();
@@ -106,6 +109,7 @@
}
gpsConfig = new GpsConfig(applicationConfig);
+ audioConfig = new AudioConfig(applicationConfig);
try {
prepareDirectories();
@@ -147,6 +151,10 @@
return gpsConfig;
}
+ public AudioConfig getAudioConfig() {
+ return audioConfig;
+ }
+
public void save() {
applicationConfig.saveForUser();
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/DeviceManagerProvider.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -28,6 +28,7 @@
import com.google.common.base.Throwables;
import com.google.common.collect.Sets;
import fr.ulr.sammoa.application.SammoaServiceSupport;
+import fr.ulr.sammoa.application.device.audio.AudioConfig;
import fr.ulr.sammoa.application.device.audio.AudioReader;
import fr.ulr.sammoa.application.device.audio.AudioReaderMock;
import fr.ulr.sammoa.application.device.audio.AudioRecorder;
@@ -53,20 +54,23 @@
deviceManagers = Sets.newHashSet();
}
- public <T extends DeviceManager> T openDeviceManager(Class<T> deviceManagerClass, boolean autoStart) {
+ public <T extends DeviceManager> T openDeviceManager(Class<T> deviceManagerClass,
+ boolean autoStart) {
T result;
if (GpsHandler.class.isAssignableFrom(deviceManagerClass)) {
result = (T) openGpsDevice(context.getConfig().getGpsConfig());
} else if (AudioRecorder.class.isAssignableFrom(deviceManagerClass)) {
- result = (T) openAudioRecorderDevice();
+ result = (T) openAudioRecorderDevice(context.getConfig().getAudioConfig());
} else if (AudioReader.class.isAssignableFrom(deviceManagerClass)) {
- result = (T) openAudioReaderDevice();
+ result = (T) openAudioReaderDevice(context.getConfig().getAudioConfig());
} else {
- throw new IllegalArgumentException("The deviceManager class " + deviceManagerClass.getName() + " is not supported");
+ throw new IllegalArgumentException("The deviceManager class "
+ + deviceManagerClass.getName()
+ + " is not supported");
}
if (autoStart) {
@@ -87,7 +91,8 @@
return null;
}
- public GpsHandler openGpsDevice(final GpsConfig config) throws DeviceTechnicalException {
+ public GpsHandler openGpsDevice(final GpsConfig config)
+ throws DeviceTechnicalException {
GpsHandler oldInstance = getDeviceManager(GpsHandler.class);
@@ -137,7 +142,8 @@
return result;
}
- public AudioRecorder openAudioRecorderDevice() throws DeviceTechnicalException {
+ public AudioRecorder openAudioRecorderDevice(final AudioConfig config)
+ throws DeviceTechnicalException {
AudioRecorder oldInstance = getDeviceManager(AudioRecorder.class);
@@ -146,13 +152,14 @@
@Override
public AudioRecorder get() {
// return new AudioRecorderDefault();
- return new SammoaAudioRecorder(44100, 16);
+ return new SammoaAudioRecorder(config);
}
});
return result;
}
- public AudioReader openAudioReaderDevice() throws DeviceTechnicalException {
+ public AudioReader openAudioReaderDevice(final AudioConfig config)
+ throws DeviceTechnicalException {
AudioReader oldInstance = getDeviceManager(AudioReader.class);
@@ -160,7 +167,7 @@
@Override
public AudioReader get() {
- return new AudioReaderMock();
+ return new AudioReaderMock(config);
}
});
return result;
Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java (rev 0)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -0,0 +1,171 @@
+package fr.ulr.sammoa.application.device.audio;
+/*
+ * #%L
+ * SAMMOA :: Application
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2012 UMS 3462, Code Lutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+import org.nuiton.util.ApplicationConfig;
+
+import static org.nuiton.i18n.I18n.n_;
+
+/**
+ * Created: 18/06/12
+ *
+ * @author fdesbois <desbois(a)codelutin.com>
+ */
+public class AudioConfig {
+
+ protected ApplicationConfig applicationConfig;
+
+ public AudioConfig(ApplicationConfig applicationConfig) {
+ this.applicationConfig = applicationConfig;
+ this.applicationConfig.loadDefaultOptions(AudioConfigOption.values());
+ }
+
+ /** @return {@link AudioConfigOption#SAMPLE_RATE} value */
+ public float getSampleRate() {
+ float result = applicationConfig.getOptionAsFloat(AudioConfigOption.SAMPLE_RATE.key);
+ return result;
+ }
+
+ /** @return {@link AudioConfigOption#SAMPLE_SIZE_IN_BITS} value */
+ public int getSampleSizeInBits() {
+ int result = applicationConfig.getOptionAsInt(AudioConfigOption.SAMPLE_SIZE_IN_BITS.key);
+ return result;
+ }
+
+ /** @return {@link AudioConfigOption#RECORD_DELAY_IN_SECONDS} value */
+ public int getRecordDelayInSeconds() {
+ int result = applicationConfig.getOptionAsInt(AudioConfigOption.RECORD_DELAY_IN_SECONDS.key);
+ return result;
+ }
+
+ public enum AudioConfigOption implements ApplicationConfig.OptionDef {
+
+ /** Sampel rate to record audio */
+ SAMPLE_RATE(
+ "sammoa.audio.sampleRate",
+ n_("sammoa.config.audio.sampleRate"),
+ "8000",
+ Float.class
+ ),
+ /** Period time in seconds for each check of the gps to update location */
+ SAMPLE_SIZE_IN_BITS(
+ "sammoa.audio.sampleSizeInBits",
+ n_("sammoa.config.audio.sampleSizeInBits"),
+ "8",
+ Integer.class
+ ),
+ /** Time in seconds between each record, this will record in multiple files */
+ RECORD_DELAY_IN_SECONDS(
+ "sammoa.audio.recordDelayInSeconds",
+ n_("sammoa.config.audio.recordDelayInSeconds"),
+ "0",
+ Integer.class
+ );
+
+ /** Configuration key. */
+ private final String key;
+
+ /** I18n key of option description */
+ private final String description;
+
+ /** Type of option */
+ private final Class<?> type;
+
+ /** Default value of option. */
+ private String defaultValue;
+
+ /** Flag to not keep option value on disk */
+ private boolean isTransient;
+
+ /** Flag to not allow option value modification */
+ private boolean isFinal;
+
+ AudioConfigOption(String key,
+ String description,
+ String defaultValue,
+ Class<?> type,
+ boolean isTransient,
+ boolean isFinal) {
+ this.key = key;
+ this.description = description;
+ this.defaultValue = defaultValue;
+ this.type = type;
+ this.isTransient = isTransient;
+ this.isFinal = isFinal;
+ }
+
+ AudioConfigOption(String key,
+ String description,
+ String defaultValue,
+ Class<?> type) {
+ this(key, description, defaultValue, type, false, false);
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public Class<?> getType() {
+ return type;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return isTransient;
+ }
+
+ @Override
+ public boolean isFinal() {
+ return isFinal;
+ }
+
+ @Override
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public void setTransient(boolean newValue) {
+ // not used
+ }
+
+ @Override
+ public void setFinal(boolean newValue) {
+ // not used
+ }
+ }
+}
Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioConfig.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioReaderMock.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -41,12 +41,18 @@
*/
public class AudioReaderMock implements AudioReader {
+ protected AudioConfig config;
+
protected long position;
protected DeviceState state = DeviceState.UNAVAILABLE;
protected Set<DeviceStateListener> listeners = Sets.newHashSet();
+ public AudioReaderMock(AudioConfig config) {
+ this.config = config;
+ }
+
@Override
public AudioFileFormat.Type getOutputType() {
return AudioFileFormat.Type.WAVE;
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorder.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorder.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorder.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -43,18 +43,16 @@
/**
* Record the audio line and save the data in given {@code outputFile}. The
- * previous recording will be stopped in {@code delaySeconds}. The delay is
+ * previous recording will be stopped after some delay depends
+ * on {@link AudioConfig#getRecordDelayInSeconds()}. The delay is
* useful to avoid recording lost or too quick between two files.
*
* @param outputFile File to record
- * @param delaySeconds Delay for previous recording
*/
- void record(File outputFile, long delaySeconds);
+ void record(File outputFile);
/**
- * Stop the current recording after {@code delaySeconds}.
- *
- * @param delaySeconds Delay for current recording
+ * Stop the current recording.
*/
- void stopRecord(long delaySeconds);
+ void stopRecord();
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -81,6 +81,8 @@
private static final AudioFileFormat.Type DEFAULT_OUTPUT_TYPE = AudioFileFormat.Type.WAVE;
+ protected AudioConfig config;
+
protected AudioFormat audioFormat;
protected AudioFileFormat.Type outputType;
@@ -102,11 +104,11 @@
protected Set<DeviceStateListener> listeners;
- public AudioRecorderDefault() {
+ public AudioRecorderDefault(AudioConfig config) {
this(new AudioFormat(
DEFAULT_ENCODING,
- DEFAULT_SAMPLE_RATE,
- DEFAULT_SAMPLE_SIZE_IN_BITS,
+ config.getSampleRate(),
+ config.getSampleSizeInBits(),
DEFAULT_CHANNELS,
DEFAULT_FRAME_SIZE,
DEFAULT_FRAME_RATE,
@@ -216,7 +218,7 @@
}
@Override
- public void record(File outputFile, long delaySeconds) {
+ public void record(File outputFile) {
if (DeviceState.UNAVAILABLE == state) {
if (logger.isWarnEnabled()) {
@@ -243,7 +245,7 @@
} else if (currentRecorder == recorder1) {
if (recorder1.isRecording()) {
- recorder1.stop(delaySeconds);
+ recorder1.stop(config.getRecordDelayInSeconds());
}
if (recorder2 != null && recorder2.isRecording()) {
@@ -256,7 +258,7 @@
} else if (currentRecorder == recorder2) {
if (recorder2.isRecording()) {
- recorder2.stop(delaySeconds);
+ recorder2.stop(config.getRecordDelayInSeconds());
}
if (recorder1.isRecording()) {
@@ -276,9 +278,9 @@
}
@Override
- public void stopRecord(long delaySeconds) {
+ public void stopRecord() {
if (currentRecorder != null) {
- currentRecorder.stop(delaySeconds);
+ currentRecorder.stop(config.getRecordDelayInSeconds());
}
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderMock.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderMock.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderMock.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -41,6 +41,12 @@
*/
public class AudioRecorderMock implements AudioRecorder {
+ protected AudioConfig config;
+
+ public AudioRecorderMock(AudioConfig config) {
+ this.config = config;
+ }
+
@Override
public DeviceState getState() {
return DeviceState.UNAVAILABLE;
@@ -62,12 +68,12 @@
}
@Override
- public void record(File outputFile, long delaySeconds) {
+ public void record(File outputFile) {
// do nothing
}
@Override
- public void stopRecord(long delaySeconds) {
+ public void stopRecord() {
// do nothing
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -55,6 +55,8 @@
private static final Logger logger = LoggerFactory.getLogger(SammoaAudioRecorder.class);
+ protected AudioConfig config;
+
protected AudioFormat audioFormat;
protected AudioFileFormat.Type outputType;
@@ -65,16 +67,16 @@
protected AudioRecorderThread currentRecorder;
- public SammoaAudioRecorder(float sampleRate, // 8000,11025,16000,22050,44100
- int sampleSizeInBits) { // 8,16
+ public SammoaAudioRecorder(AudioConfig config) {
+ this.config = config;
int channels = 1; // 1,2
boolean signed = true; // true,false
boolean bigEndian = false; // true,false
audioFormat = new AudioFormat(
- sampleRate,
- sampleSizeInBits,
+ config.getSampleRate(),
+ config.getSampleSizeInBits(),
channels,
signed,
bigEndian);
@@ -131,7 +133,7 @@
}
@Override
- public void record(File outputFile, long delaySeconds) {
+ public void record(File outputFile) {
Preconditions.checkNotNull(outputFile);
try {
@@ -139,7 +141,7 @@
stop();
// start new recorder thread
currentRecorder = new AudioRecorderThread(
- audioFormat, outputType, outputFile, delaySeconds, this);
+ audioFormat, outputType, outputFile, config.getRecordDelayInSeconds(), this);
currentRecorder.start();
setState(DeviceState.RUNNING, null);
@@ -156,7 +158,7 @@
}
@Override
- public void stopRecord(long delaySeconds) {
+ public void stopRecord() {
stop();
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/BaseFlightController.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -67,10 +67,6 @@
private static final TimeLog timeLog = new TimeLog(BaseFlightController.class, 500, 1000);
protected FlightService service;
-//
-// protected AudioRecorder audioRecorder;
-//
-// protected GpsHandler gpsHandler;
protected boolean initialized;
@@ -292,6 +288,8 @@
currentRoute = newCurrentRoute;
+ TransectFlight lastTransectOldValue = lastTransect;
+
if (currentRoute == null) {
if (flight.getEndDate() == null) {
@@ -337,7 +335,7 @@
if (fireChanges) {
onStateChanged(state);
- onLastTransectChanged(lastTransect);
+ onLastTransectChanged(lastTransectOldValue, lastTransect);
onNextTransectChanged(nextTransect);
onCurrentRouteChanged(currentRoute);
}
@@ -368,6 +366,7 @@
Date currentDate = geoPoint.getRecordTime();
// The next transect becomes the last one (or current in this case)
+ TransectFlight lastTransectOldValue = lastTransect;
lastTransect = nextTransect;
// Create new LEG route
@@ -388,7 +387,7 @@
// Fire events after commit
onRouteAdded(previousRoute, currentRoute);
- onLastTransectChanged(lastTransect);
+ onLastTransectChanged(lastTransectOldValue, lastTransect);
onNextTransectChanged(nextTransect);
onStateChanged(state);
@@ -581,6 +580,7 @@
Date currentDate = geoPoint.getRecordTime();
+ TransectFlight lastTransectOldValue = lastTransect;
lastTransect = null;
// Create new TRANSIT route
@@ -596,7 +596,7 @@
// Fire events after commit
onRouteAdded(previousRoute, currentRoute);
- onLastTransectChanged(lastTransect);
+ onLastTransectChanged(lastTransectOldValue, lastTransect);
onNextTransectChanged(nextTransect);
onStateChanged(state);
@@ -771,7 +771,7 @@
}
}
- protected void onLastTransectChanged(TransectFlight lastTransect) {
+ protected void onLastTransectChanged(TransectFlight oldValue, TransectFlight newValue) {
// no fire by default
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerOnBoard.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -23,6 +23,7 @@
* #L%
*/
+import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import fr.ulr.sammoa.application.device.DeviceManager;
import fr.ulr.sammoa.application.device.audio.AudioRecorder;
@@ -47,10 +48,6 @@
*/
public class FlightControllerOnBoard extends BaseFlightController implements GpsLocationListener {
- protected GpsHandler gpsHandler;
-
- protected AudioRecorder audioRecorder;
-
@Override
public <T extends DeviceManager> void openDeviceManager(Class<T> deviceManager) {
boolean autoStart = initialized && isRunning();
@@ -59,16 +56,19 @@
if (result instanceof GpsHandler) {
((GpsHandler) result).addGpsLocationListener(this);
+
+ } else if (autoStart && result instanceof AudioRecorder) {
+ restartAudio((AudioRecorder) result);
}
}
@Override
public void init(Flight flight) {
- gpsHandler = getDeviceManager(GpsHandler.class);
+ GpsHandler gpsHandler = getGpsHandler();
Preconditions.checkNotNull(gpsHandler, "You must open the gpsHandler device before init");
- audioRecorder = getDeviceManager(AudioRecorder.class);
+ AudioRecorder audioRecorder = getAudioRecorder();
Preconditions.checkNotNull(audioRecorder, "You must open the audioRecorder device before init");
super.init(flight);
@@ -81,23 +81,16 @@
audioRecorder.start();
- // Restart recording audio if onEffort or circleBack (recovery mode)
- if (state == FlightState.ON_EFFORT
- || currentRoute.getRouteType() == RouteType.CIRCLE_BACK) {
-
- File audioFile = flightStorage.getAudioFile(
- lastTransect, audioRecorder.getOutputType().getExtension());
- audioRecorder.record(audioFile, 3);
- }
+ restartAudio(audioRecorder);
}
}
@Override
public void start() {
- gpsHandler.start();
+ getGpsHandler().start();
- audioRecorder.start();
+ getAudioRecorder().start();
super.start();
}
@@ -107,9 +100,9 @@
super.stop();
- audioRecorder.stop();
+ getAudioRecorder().stop();
- gpsHandler.stop();
+ getGpsHandler().stop();
}
@Override
@@ -123,7 +116,7 @@
@Override
protected GeoPoint getLocation(TopiaContext tx) throws TopiaException {
- GeoPoint result = gpsHandler.getCurrentLocation();
+ GeoPoint result = getGpsHandler().getCurrentLocation();
result.setFlight(flight);
if (result.getTopiaId() == null) {
SammoaDAOHelper.getGeoPointDAO(tx).create(result);
@@ -132,17 +125,43 @@
}
@Override
- protected void onLastTransectChanged(TransectFlight lastTransect) {
+ protected void onLastTransectChanged(TransectFlight oldValue,
+ TransectFlight newValue) {
- if (lastTransect == null) {
- audioRecorder.stopRecord(3);
+ // Record audio for the lastTransect (also current one in case of LEG)
- } else {
+ if (!Objects.equal(oldValue, newValue)) {
+
+ AudioRecorder audioRecorder = getAudioRecorder();
+
+ if (newValue == null) {
+ audioRecorder.stopRecord();
+
+ } else {
+ File audioFile = flightStorage.getAudioFile(
+ newValue, audioRecorder.getOutputType().getExtension());
+ audioRecorder.record(audioFile);
+ }
+ }
+
+ super.onLastTransectChanged(oldValue, newValue);
+ }
+
+ protected void restartAudio(AudioRecorder audioRecorder) {
+ if (state == FlightState.ON_EFFORT
+ || currentRoute.getRouteType() == RouteType.CIRCLE_BACK) {
+
File audioFile = flightStorage.getAudioFile(
lastTransect, audioRecorder.getOutputType().getExtension());
- audioRecorder.record(audioFile, 3);
+ audioRecorder.record(audioFile);
}
+ }
- super.onLastTransectChanged(lastTransect);
+ protected GpsHandler getGpsHandler() {
+ return getDeviceManager(GpsHandler.class);
}
+
+ protected AudioRecorder getAudioRecorder() {
+ return getDeviceManager(AudioRecorder.class);
+ }
}
Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java
===================================================================
--- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -54,8 +54,6 @@
private static final Logger logger = LoggerFactory.getLogger(FlightControllerValidation.class);
- protected AudioReader audioReader;
-
protected List<GeoPoint> geoPoints;
protected List<Route> routes;
@@ -68,7 +66,7 @@
@Override
public void init(Flight flight) {
- audioReader = getDeviceManager(AudioReader.class);
+ AudioReader audioReader = getAudioReader();
Preconditions.checkNotNull(audioReader, "You must open the audioReader device before init");
super.init(flight);
@@ -95,7 +93,7 @@
);
}
- long position = audioReader.getPosition();
+ long position = getAudioReader().getPosition();
DateTime newTime;
if (position > 0) {
@@ -162,16 +160,20 @@
}
@Override
- protected void onLastTransectChanged(TransectFlight transectFlight) {
+ protected void onLastTransectChanged(TransectFlight oldValue,
+ TransectFlight newValue) {
- // Only change audio if lastTransect isn't the same
- if (!Objects.equal(lastTransect, transectFlight)) {
+ // Read audio for the lastTransect (also current one in case of LEG)
+ if (!Objects.equal(oldValue, newValue)) {
+
+ AudioReader audioReader = getAudioReader();
+
audioReader.unload();
- if (transectFlight != null) {
+ if (newValue != null) {
File file = flightStorage.getAudioFile(
- transectFlight, audioReader.getOutputType().getExtension());
+ newValue, audioReader.getOutputType().getExtension());
if (file.exists()) {
audioReader.load(file);
@@ -179,6 +181,10 @@
}
}
- super.onLastTransectChanged(transectFlight);
+ super.onLastTransectChanged(oldValue, newValue);
}
+
+ protected AudioReader getAudioReader() {
+ return getDeviceManager(AudioReader.class);
+ }
}
Modified: trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties
===================================================================
--- trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties 2012-09-04 16:05:15 UTC (rev 517)
@@ -1,6 +1,9 @@
sammoa.config.admin.email=Administrator's email
sammoa.config.application.site.url=Website URL of the application
sammoa.config.application.version=Version of the application
+sammoa.config.audio.recordDelayInSeconds=Delay in seconds between each audio record. This will record multiple files at the same time to avoid too sudden stops. (Warning \: this is not supported by all sound systems)
+sammoa.config.audio.sampleRate=Rate for the audio sampling (possible values \: 8000, 11025, 16000, 22050, 44100)
+sammoa.config.audio.sampleSizeInBits=Size of bits for the audio sampling (possible values \: 8, 16)
sammoa.config.background.shape.file=Location of the Background shape file
sammoa.config.backup.directory=BAckup directory where to sotre all data backup
sammoa.config.campaign.directory=Directory where are stored campaign data (maps, flight audio files,...)
Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java
===================================================================
--- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -53,6 +53,10 @@
// static class do not have instanciation
}
+ public static boolean isAnyMatchTransectFlight(Iterable<Route> routes, TransectFlight transectFlight) {
+ return Iterables.any(routes, withTransectFlight(transectFlight));
+ }
+
public static boolean isRouteLeg(Route route) {
return route != null && RouteType.LEG == route.getRouteType();
}
Modified: trunk/sammoa-ui-swing/pom.xml
===================================================================
--- trunk/sammoa-ui-swing/pom.xml 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-ui-swing/pom.xml 2012-09-04 16:05:15 UTC (rev 517)
@@ -13,6 +13,8 @@
</parent>
<artifactId>sammoa-ui-swing</artifactId>
+ <inceptionYear>2012</inceptionYear>
+ <url>http://forge.codelutin.com/projects/sammoa</url>
<name>SAMMOA :: UI Swing</name>
<description>Swing interface using Jaxx</description>
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -26,7 +26,11 @@
import fr.ulr.sammoa.application.SammoaConfig;
import fr.ulr.sammoa.application.SammoaContext;
+import fr.ulr.sammoa.application.device.DeviceManager;
import fr.ulr.sammoa.application.device.DeviceTechnicalException;
+import fr.ulr.sammoa.application.device.audio.AudioConfig;
+import fr.ulr.sammoa.application.device.audio.AudioReader;
+import fr.ulr.sammoa.application.device.audio.AudioRecorder;
import fr.ulr.sammoa.application.device.gps.GpsConfig;
import fr.ulr.sammoa.application.device.gps.GpsHandler;
import fr.ulr.sammoa.application.flightController.FlightController;
@@ -255,8 +259,7 @@
ConfigUIHelper helper = new ConfigUIHelper(config);
helper.registerCallBack(
- "ui",
- n_("sammoa.action.reload.ui"),
+ "ui", n_("sammoa.action.reload.ui"),
SwingUtil.createActionIcon("reload-ui"),
new Runnable() {
@@ -264,143 +267,186 @@
public void run() {
reloadSammoa();
}
- });
- helper.registerCallBack(
- "home",
- n_("sammoa.action.reload.home"),
- SwingUtil.createActionIcon("config"),
- new Runnable() {
+ }
+ );
- @Override
- public void run() {
- if (SammoaScreen.HOME == ui.getScreen()) {
- HomeUI homeUI = (HomeUI) currentBody;
- homeUI.getHandler().selectCampaign();
+ // APPLICATION
+ {
+ helper.addCategory(n_("sammoa.config.category.applications"),
+ n_("sammoa.config.category.applications.description"));
+ helper.registerCallBack(
+ "home", n_("sammoa.action.reload.home"),
+ SwingUtil.createActionIcon("config"),
+ new Runnable() {
+
+ @Override
+ public void run() {
+ if (SammoaScreen.HOME == ui.getScreen()) {
+ HomeUI homeUI = (HomeUI) currentBody;
+ homeUI.getHandler().selectCampaign();
+ }
}
}
- });
+ );
+ helper.addOption(SammoaConfig.SammoaConfigOption.SYSTEM_ID);
+ helper.setOptionCallBack("home");
+ helper.addOption(SammoaConfig.SammoaConfigOption.DATA_DIRECTORY);
+ helper.setOptionCallBack("ui");
+ helper.addOption(SammoaConfig.SammoaConfigOption.FLIGHT_NUMBER);
+ helper.addOption(SammoaConfig.SammoaConfigOption.BACKGROUND_SHAPE_FILE);
+ helper.setOptionCallBack("ui");
+ helper.addOption(SammoaConfig.SammoaConfigOption.AUTO_COMMIT_DELAY); // milliseconds
+ helper.setOptionCallBack("ui");
+ }
- // categorie applications
- helper.addCategory(n_("sammoa.config.category.applications"),
- n_("sammoa.config.category.applications.description"));
+ // SHORTCUT
+ {
+ helper.addCategory(n_("sammoa.config.category.shortcuts"),
+ n_("sammoa.config.category.shortcuts.description"));
+ helper.registerCallBack(
+ "actions", n_("sammoa.action.reload.actions"),
+ SwingUtil.createActionIcon("config"),
+ new Runnable() {
- helper.addOption(SammoaConfig.SammoaConfigOption.SYSTEM_ID);
- helper.setOptionCallBack("home");
- helper.addOption(SammoaConfig.SammoaConfigOption.DATA_DIRECTORY);
- helper.setOptionCallBack("ui");
-// helper.addOption(SammoaConfig.SammoaConfigOption.CAMPAIGN_DIRECTORY);
-// helper.setOptionCallBack("ui");
- helper.addOption(SammoaConfig.SammoaConfigOption.FLIGHT_NUMBER);
- helper.addOption(SammoaConfig.SammoaConfigOption.BACKGROUND_SHAPE_FILE);
- helper.setOptionCallBack("ui");
- // milliseconds
- helper.addOption(SammoaConfig.SammoaConfigOption.AUTO_COMMIT_DELAY);
- helper.setOptionCallBack("ui");
+ @Override
+ public void run() {
-// helper.addOption(SammoaConfig.SammoaConfigOption.STRATE_SHAPE_FILE);
-// helper.setOptionCallBack("ui");
-// helper.addOption(SammoaConfig.SammoaConfigOption.TRANSECT_SHAPE_FILE);
-// helper.setOptionCallBack("ui");
+ if (SammoaScreen.FLIGHT == ui.getScreen()
+ || SammoaScreen.VALIDATION == ui.getScreen()) {
- helper.registerCallBack("actions",
- n_("sammoa.action.reload.actions"),
- SwingUtil.createActionIcon("config"),
- new Runnable() {
+ FlightUI flightUI = (FlightUI) currentBody;
+ flightUI.getHandler().initActions();
+ }
+ }
+ }
+ );
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_START);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_STOP);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_BEGIN);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_END);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_NEXT);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_ADD);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_LEFT_OBSERVATION);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_CENTER_OBSERVATION);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_RIGHT_OBSERVATION);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_CIRCLE_BACK);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_TRANSECT);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_OBSERVATION);
+ helper.setOptionCallBack("actions");
+ helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_ROUTE);
+ helper.setOptionCallBack("actions");
+ }
- @Override
- public void run() {
+ // GPS
+ {
+ helper.addCategory(n_("sammoa.config.category.gps"),
+ n_("sammoa.config.category.gps.description"));
+ helper.registerCallBack(
+ "gps", n_("sammoa.action.reload.gps"),
+ SwingUtil.createActionIcon("config"),
+ new Runnable() {
- if (SammoaScreen.FLIGHT == ui.getScreen()
- || SammoaScreen.VALIDATION == ui.getScreen()) {
+ @Override
+ public void run() {
- FlightUI flightUI = (FlightUI) currentBody;
- flightUI.getHandler().initActions();
- }
- }
- });
- // categorie raccourcis
- helper.addCategory(n_("sammoa.config.category.shortcuts"),
- n_("sammoa.config.category.shortcuts.description"));
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_START);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_STOP);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_BEGIN);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_END);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_NEXT);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_ADD);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_LEFT_OBSERVATION);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_CENTER_OBSERVATION);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_RIGHT_OBSERVATION);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_CIRCLE_BACK);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_TRANSECT);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_OBSERVATION);
- helper.setOptionCallBack("actions");
- helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_ROUTE);
- helper.setOptionCallBack("actions");
+ if (SammoaScreen.FLIGHT == ui.getScreen()) {
- // gps
- helper.registerCallBack("gps",
- n_("sammoa.action.reload.gps"),
- SwingUtil.createActionIcon("config"),
- new Runnable() {
+ reloadDevice((FlightUI) currentBody, GpsHandler.class);
+ }
+ }
+ }
+ );
+ helper.addOption(GpsConfig.GpsConfigOption.GPS_HANDLER,
+ SammoaConfig.PROPERTY_GPS_CONFIG + "." + GpsConfig.PROPERTY_GPS_HNALDER_CLASS);
+ helper.setOptionCallBack("gps");
+ helper.addOption(GpsConfig.GpsConfigOption.GPS_DEVICE);
+ helper.setOptionCallBack("gps");
+ helper.addOption(GpsConfig.GpsConfigOption.GPS_SPEED);
+ helper.setOptionCallBack("gps");
+ helper.addOption(GpsConfig.GpsConfigOption.GPS_CHECK_PERIOD);
+ helper.setOptionCallBack("gps");
+ helper.addOption(GpsConfig.GpsConfigOption.GPS_TIMEOUT);
+ helper.setOptionCallBack("gps");
+ }
- @Override
- public void run() {
+ // AUDIO
+ {
+ helper.addCategory(n_("sammoa.config.category.audio"),
+ n_("sammoa.config.category.audio.description"));
+ helper.registerCallBack(
+ "audio", n_("sammoa.action.reload.audio"),
+ SwingUtil.createActionIcon("config"),
+ new Runnable() {
- if (SammoaScreen.FLIGHT == ui.getScreen()) {
+ @Override
+ public void run() {
- FlightUI flightUI = (FlightUI) currentBody;
+ if (SammoaScreen.FLIGHT == ui.getScreen()) {
- try {
- FlightController flightController = flightUI.getHandler().getFlightController();
- flightController.openDeviceManager(GpsHandler.class);
- } catch (DeviceTechnicalException ex) {
- logger.error("Error on new GpsHandler", ex);
- SammoaUtil.showErrorMessage(ui, ex.getMessageWithCause());
- }
- }
- }
- });
- helper.addCategory(n_("sammoa.config.category.gps"),
- n_("sammoa.config.category.gps.description"));
- helper.addOption(GpsConfig.GpsConfigOption.GPS_HANDLER,
- SammoaConfig.PROPERTY_GPS_CONFIG + "." + GpsConfig.PROPERTY_GPS_HNALDER_CLASS);
- helper.setOptionCallBack("gps");
- helper.addOption(GpsConfig.GpsConfigOption.GPS_DEVICE);
- helper.setOptionCallBack("gps");
- helper.addOption(GpsConfig.GpsConfigOption.GPS_SPEED);
- helper.setOptionCallBack("gps");
- helper.addOption(GpsConfig.GpsConfigOption.GPS_CHECK_PERIOD);
- helper.setOptionCallBack("gps");
- helper.addOption(GpsConfig.GpsConfigOption.GPS_TIMEOUT);
- helper.setOptionCallBack("gps");
+ reloadDevice((FlightUI) currentBody, AudioRecorder.class);
- // others
- helper.addCategory(n_("sammoa.config.category.other"),
- n_("sammoa.config.category.other.description"));
+ } else if (SammoaScreen.VALIDATION == ui.getScreen()) {
- helper.addOption(SammoaConfig.SammoaConfigOption.LOCALE);
- helper.setOptionCallBack("ui");
+ reloadDevice((FlightUI) currentBody, AudioReader.class);
+ }
+ }
+ }
+ );
+ helper.addOption(AudioConfig.AudioConfigOption.SAMPLE_RATE);
+ helper.setOptionCallBack("audio");
+ helper.addOption(AudioConfig.AudioConfigOption.SAMPLE_SIZE_IN_BITS);
+ helper.setOptionCallBack("audio");
+ helper.addOption(AudioConfig.AudioConfigOption.RECORD_DELAY_IN_SECONDS);
+ helper.setOptionCallBack("audio");
+ }
- helper.addOption(SammoaConfig.SammoaConfigOption.SITE_URL);
- helper.addOption(SammoaConfig.SammoaConfigOption.UI_CONFIG_FILE);
- helper.setOptionCallBack("ui");
+ // OTHER
+ {
+ helper.addCategory(n_("sammoa.config.category.other"),
+ n_("sammoa.config.category.other.description"));
+ helper.addOption(SammoaConfig.SammoaConfigOption.LOCALE);
+ helper.setOptionCallBack("ui");
+ helper.addOption(SammoaConfig.SammoaConfigOption.SITE_URL);
+ helper.addOption(SammoaConfig.SammoaConfigOption.UI_CONFIG_FILE);
+ helper.setOptionCallBack("ui");
+ }
helper.buildUI(ui, "sammoa.config.category.applications");
helper.displayUI(ui, false);
}
+ /**
+ * Reload the given device identified by its {@code deviceManagerClass} for
+ * {@code ui}.
+ *
+ * @param ui FlightUI contains the controller that manage devices
+ * @param deviceManagerClass Class of the device to reload
+ * @param <T> Type of {@link DeviceManager}
+ * @see FlightController#openDeviceManager(Class)
+ */
+ protected <T extends DeviceManager> void reloadDevice(FlightUI ui,
+ Class<T> deviceManagerClass) {
+ try {
+ FlightController flightController = ui.getHandler().getFlightController();
+ flightController.openDeviceManager(deviceManagerClass);
+ } catch (DeviceTechnicalException ex) {
+ logger.error("Error on new " + deviceManagerClass.getSimpleName(), ex);
+ SammoaUtil.showErrorMessage(ui, ex.getMessageWithCause());
+ }
+ }
+
public void showHome() {
if (checkCurrentFlight(_("sammoa.confirmDialog.flightInProgress.message.showHome"))) {
setScreen(SammoaScreen.HOME);
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 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2012-09-04 16:05:15 UTC (rev 517)
@@ -569,10 +569,10 @@
((TransectFlightModel) input).getSource();
// Enabled only if no route match the transectFlight
- // Note : the deleted route case is too complex, the user must delete routes before transect
- boolean result = FluentIterable
- .from(getModel().getRoutes())
- .anyMatch(Routes.withTransectFlight(transectFlight));
+ // Note : the deleted route case is too complex,
+ // the user must delete routes before transect
+ boolean result = Routes.isAnyMatchTransectFlight(
+ getModel().getRoutes(), transectFlight);
return !result;
}
});
@@ -600,7 +600,16 @@
@Override
public boolean apply(Object input) {
- return !((TransectFlightModel) input).isDeleted();
+ TransectFlight transectFlight =
+ ((TransectFlightModel) input).getSource();
+
+ // Enabled only if no route match the transectFlight
+ // Note : the deleted route case is too complex,
+ // the user must create a new transectFlight to
+ // use it as next one
+ boolean result = Routes.isAnyMatchTransectFlight(
+ getModel().getRoutes(), transectFlight);
+ return !result;
}
});
Modified: trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties
===================================================================
--- trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-04 16:04:55 UTC (rev 516)
+++ trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-04 16:05:15 UTC (rev 517)
@@ -37,7 +37,8 @@
sammoa.action.quitExportMaps=Quit
sammoa.action.quitImportApplication=Quit
sammoa.action.reload.actions=Reload actions
-sammoa.action.reload.gps=Reload GPS
+sammoa.action.reload.audio=Relad Audio device
+sammoa.action.reload.gps=Reload GPS device
sammoa.action.reload.home=Reload home screen
sammoa.action.reload.ui=Reload sammoa ui
sammoa.action.right.tip=RIGHT \: create a new Observation for the observer on the right side
@@ -56,9 +57,10 @@
sammoa.action.validTransect=Transect
sammoa.action.validTransect.tip=Validate the selected transect and all its routes and observations
sammoa.action.validation=Validation
-sammoa.askQuestion.deleteTransect.message=
sammoa.config.category.applications=Application
sammoa.config.category.applications.description=Application
+sammoa.config.category.audio=Audio
+sammoa.config.category.audio.description=Audio configuration
sammoa.config.category.gps=GPS
sammoa.config.category.gps.description=GPS configuration
sammoa.config.category.other=Other
1
0
r516 - trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action
by fdesbois@users.forge.codelutin.com 04 Sep '12
by fdesbois@users.forge.codelutin.com 04 Sep '12
04 Sep '12
Author: fdesbois
Date: 2012-09-04 18:04:55 +0200 (Tue, 04 Sep 2012)
New Revision: 516
Url: http://forge.codelutin.com/repositories/revision/sammoa/516
Log:
Add file header
Modified:
trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/DeleteTransectAction.java
Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/DeleteTransectAction.java
===================================================================
--- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/DeleteTransectAction.java 2012-09-04 16:04:41 UTC (rev 515)
+++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/DeleteTransectAction.java 2012-09-04 16:04:55 UTC (rev 516)
@@ -1,5 +1,29 @@
package fr.ulr.sammoa.ui.swing.flight.action;
+/*
+ * #%L
+ * SAMMOA :: UI Swing
+ * $Id:$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 UMS 3462, Code Lutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
import fr.ulr.sammoa.application.FlightService;
import fr.ulr.sammoa.application.flightController.FlightState;
import fr.ulr.sammoa.ui.swing.flight.FlightUI;
1
0