X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fcorrelate%2FAudioCorrelator.java;fp=src%2Ftim%2Fprune%2Fcorrelate%2FAudioCorrelator.java;h=f60d687db38c2164e37f4cea72f62cecaa9d3234;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/correlate/AudioCorrelator.java b/src/tim/prune/correlate/AudioCorrelator.java new file mode 100644 index 0000000..f60d687 --- /dev/null +++ b/src/tim/prune/correlate/AudioCorrelator.java @@ -0,0 +1,286 @@ +package tim.prune.correlate; + +import java.awt.FlowLayout; +import java.awt.GridLayout; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTable; + +import tim.prune.App; +import tim.prune.DataSubscriber; +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.config.TimezoneHelper; +import tim.prune.data.AudioClip; +import tim.prune.data.AudioList; +import tim.prune.data.DataPoint; +import tim.prune.data.MediaObject; +import tim.prune.data.MediaList; +import tim.prune.data.TimeDifference; +import tim.prune.data.Timestamp; +import tim.prune.data.TimestampUtc; +import tim.prune.undo.UndoCorrelateAudios; + +/** + * Class to manage the automatic correlation of audio clips to points + * which is very similar to the PhotoCorrelator apart from the clip lengths + */ +public class AudioCorrelator extends Correlator +{ + private AudioTimestampSelector _fileTimesSelector = null, _correlTimesSelector = null; + + + /** + * Constructor + * @param inApp App object + */ + public AudioCorrelator(App inApp) { + super(inApp); + } + + /** + * @return name key + */ + public String getNameKey() { + return "function.correlateaudios"; + } + + /** @return type key */ + protected String getMediaTypeKey() { + return "audio"; + } + + /** @return photo list*/ + protected MediaList getMediaList() { + return _app.getTrackInfo().getAudioList(); + } + + + /** + * @return first gui panel including timestamp specification (beginning, middle, end) + */ + protected JPanel makeFirstPanel() + { + // First panel for timestamp stuff + JPanel card1 = new JPanel(); + card1.setLayout(new FlowLayout(FlowLayout.CENTER)); + JPanel grid1 = new JPanel(); + grid1.setLayout(new GridLayout(0, 1)); + _fileTimesSelector = new AudioTimestampSelector("dialog.correlate.filetimes", "dialog.correlate.filetimes2"); + grid1.add(_fileTimesSelector); + _correlTimesSelector = new AudioTimestampSelector("dialog.correlate.correltimes", null); + grid1.add(_correlTimesSelector); + card1.add(grid1); + return card1; + } + + + /** + * @return array of boolean flags denoting availability of cards + */ + protected boolean[] getCardEnabledFlags() + { + boolean[] cards = super.getCardEnabledFlags(); + cards[0] = getAudioLengthAvailability(_app.getTrackInfo().getAudioList()); + return cards; + } + + /** + * @param inAudios AudioList object + * @return true if there are any audio lengths available + */ + private static boolean getAudioLengthAvailability(AudioList inAudios) + { + for (int i=0; i 0) {return true;} + } + return false; + } + + /** + * Create a preview of the correlate action using the selected time difference + * @param inTimeDiff TimeDifference to use for preview + * @param inShowWarning true to show warning if all points out of range + */ + protected void createPreview(TimeDifference inTimeDiff, boolean inShowWarning) + { + TimeDifference timeLimit = parseTimeLimit(); + double angDistLimit = parseDistanceLimit(); + MediaPreviewTableModel model = new MediaPreviewTableModel("dialog.correlate.select.audioname"); + AudioList audios = _app.getTrackInfo().getAudioList(); + // Loop through audios deciding whether to set correlate flag or not + int numAudios = audios.getNumAudios(); + for (int i=0; i 0.0 && correlateAudio) + { + final double angDistPair = DataPoint.calculateRadiansBetween(pair.getPointBefore(), pair.getPointAfter()); + double frac = pair.getFraction(); + if (frac > 0.5) {frac = 1 - frac;} + final double angDistPhoto = angDistPair * frac; + correlateAudio = (angDistPhoto < angDistLimit); + } + // Don't select audios which are already correlated to the same point + if (pair.getSecondsBefore() == 0L && pair.getPointBefore().isDuplicate(audio.getDataPoint())) { + correlateAudio = false; + } + row.setCorrelateFlag(correlateAudio); + model.addRow(row); + } + _previewTable.setModel(model); + // Set distance units + model.setDistanceUnits(getSelectedDistanceUnits()); + // Set column widths + _previewTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + final int[] colWidths = {150, 160, 100, 100, 50}; + for (int i=0; i 0 && secsToAdd != 0) + { + mediaMillis += (secsToAdd * 1000L); + tstamp = new TimestampUtc(mediaMillis); + // Here we create a Utc timestamp but it's only temporary for the correlation + // so it will never have to react to timezone changes + } + } + catch (ClassCastException cce) {} + return tstamp; + } + + /** + * Finish the correlation by modifying the track + * and passing the Undo information back to the App + */ + protected void finishCorrelation() + { + // TODO: Probably should be able to combine this into the Correlator? + PointMediaPair[] pointPairs = getPointPairs(); + if (pointPairs == null || pointPairs.length <= 0) {return;} + + // begin to construct undo information + UndoCorrelateAudios undo = new UndoCorrelateAudios(_app.getTrackInfo()); + // loop over Audios + int arraySize = pointPairs.length; + int i = 0, numAudios = 0; + int numPointsToCreate = 0; + PointMediaPair pair = null; + for (i=0; i 0) + { + // make new array for added points + DataPoint[] addedPoints = new DataPoint[numPointsToCreate]; + int pointNum = 0; + DataPoint pointToAdd = null; + for (i=0; i 0L) + { + // interpolate point + pointToAdd = DataPoint.interpolate(pair.getPointBefore(), pair.getPointAfter(), pair.getFraction()); + } + if (pointToAdd != null) + { + // link audio to point + pointToAdd.setAudio((AudioClip) pair.getMedia()); + pair.getMedia().setDataPoint(pointToAdd); + // set to start of segment so not joined in track + pointToAdd.setSegmentStart(true); + // add to point array + addedPoints[pointNum] = pointToAdd; + pointNum++; + } + } + } + // expand track + _app.getTrackInfo().getTrack().appendPoints(addedPoints); + } + + // send undo information back to controlling app + undo.setNumAudiosCorrelated(numAudios); + _app.completeFunction(undo, ("" + numAudios + " " + + (numAudios==1?I18nManager.getText("confirm.correlateaudios.single"):I18nManager.getText("confirm.correlateaudios.multi")))); + // observers already informed by track update if new points created + if (numPointsToCreate == 0) { + UpdateMessageBroker.informSubscribers(DataSubscriber.SELECTION_CHANGED); + } + } +}