Ignore:
Timestamp:
2008-03-02T16:10:33+01:00 (16 years ago)
Author:
david
Message:

Reorganise audio interface in light of recent usability comments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r567 r572  
    4444import org.openstreetmap.josm.gui.layer.GpxLayer;
    4545import org.openstreetmap.josm.gui.layer.markerlayer.AudioMarker;
     46import org.openstreetmap.josm.gui.layer.markerlayer.PlayHeadMarker;
    4647import org.openstreetmap.josm.tools.ColorHelper;
    4748import org.openstreetmap.josm.tools.ImageProvider;
     
    6768        private boolean mousePressed = false;
    6869        public GpxLayer fromLayer = null;
    69         private Rectangle audioTracer = null;
     70       
     71        /*
    7072        private Icon audioTracerIcon = null;
    7173        private EastNorth playheadPosition = null;
     
    7375        private static double audioAnimationInterval = 0.0; // seconds
    7476        private static double playheadTime = -1.0;
    75 
     77         */
    7678        public MarkerLayer(GpxData indata, String name, File associatedFile, GpxLayer fromLayer) {
    7779               
     
    161163                        }
    162164                }
    163 
    164                 if (audioTracer != null) {
    165                         Point screen = Main.map.mapView.getPoint(playheadPosition);
    166                         audioTracer.setLocation(screen.x, screen.y);
    167                         audioTracerIcon.paintIcon(Main.map.mapView, g, screen.x, screen.y);
    168                 }
    169         }
    170 
    171         protected void traceAudio() {
    172                 if (timer == null) {
    173                         audioAnimationInterval = Double.parseDouble(Main.pref.get("marker.audioanimationinterval", "1")); //milliseconds
    174                         timer = new Timer((int)(audioAnimationInterval * 1000.0), new ActionListener() {
    175                                 public void actionPerformed(ActionEvent e) {
    176                                         timerAction();
    177                                 }
    178                         });
    179                         timer.start();
    180                 }
    181         }
    182        
    183         /**
    184          * callback for AudioPlayer when position changes
    185          * @param position seconds into the audio stream
    186          */
    187         public void timerAction() {
    188                 AudioMarker recentlyPlayedMarker = AudioMarker.recentlyPlayedMarker();
    189                 if (recentlyPlayedMarker == null)
    190                         return;
    191                 double audioTime = recentlyPlayedMarker.time +
    192                         AudioPlayer.position() -
    193                         recentlyPlayedMarker.offset -
    194                         recentlyPlayedMarker.syncOffset;
    195                 if (Math.abs(audioTime- playheadTime) < audioAnimationInterval)
    196                         return;
    197                 if (fromLayer == null)
    198                         return;
    199                 /* find the pair of track points for this position (adjusted by the syncOffset)
    200                  * and interpolate between them
    201                  */
    202                 WayPoint w1 = null;
    203                 WayPoint w2 = null;
    204 
    205                 for (GpxTrack track : fromLayer.data.tracks) {
    206                         for (Collection<WayPoint> trackseg : track.trackSegs) {
    207                                 for (Iterator<WayPoint> it = trackseg.iterator(); it.hasNext();) {
    208                                         WayPoint w = it.next();
    209                                         if (audioTime < w.time) {
    210                                                 w2 = w;
    211                                                 break;
    212                                         }
    213                                         w1 = w;
    214                                 }
    215                                 if (w2 != null) break;
    216                         }
    217                         if (w2 != null) break;
    218                 }
    219                
    220                 if (w1 == null)
    221                         return;
    222                 playheadPosition = w2 == null ?
    223                         w1.eastNorth :
    224                         w1.eastNorth.interpolate(w2.eastNorth,
    225                                         (audioTime - w1.time)/(w2.time - w1.time));
    226                
    227                 if (audioTracer == null) {
    228                         audioTracerIcon = ImageProvider.getIfAvailable("markers",Main.pref.get("marker.audiotracericon", "audio-tracer"));
    229                         audioTracer = new Rectangle(0, 0, audioTracerIcon.getIconWidth(), audioTracerIcon.getIconHeight());                     
    230                 }
    231                 playheadTime = audioTime;
    232                 Main.map.mapView.repaint();
    233165        }
    234166
     
    249181                for (Marker mkr : data)
    250182                        v.visit(mkr.eastNorth);
    251         }
    252 
    253         public void applyAudio(File wavFile) {
    254                 String uri = "file:".concat(wavFile.getAbsolutePath());
    255                 Collection<Marker> markers = new ArrayList<Marker>();
    256             for (Marker mkr : data) {
    257                 AudioMarker audioMarker = mkr.audioMarkerFromMarker(uri);
    258                 if (audioMarker == null) {
    259                         markers.add(mkr);
    260                 } else {
    261                     markers.add(audioMarker);
    262                 }
    263             }
    264             data.clear();
    265             data.addAll(markers);
    266183        }
    267184
     
    293210                });
    294211
    295                 JMenuItem applyaudio = new JMenuItem(tr("Apply Audio"), ImageProvider.get("applyaudio"));
    296                 applyaudio.putClientProperty("help", "Action/ApplyAudio");
    297                 applyaudio.addActionListener(new ActionListener(){
    298                         public void actionPerformed(ActionEvent e) {
    299                                 String dir = Main.pref.get("markers.lastaudiodirectory");
    300                                 JFileChooser fc = new JFileChooser(dir);
    301                                 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    302                                 fc.setAcceptAllFileFilterUsed(false);
    303                                 fc.setFileFilter(new FileFilter(){
    304                                         @Override public boolean accept(File f) {
    305                                                 return f.isDirectory() || f.getName().toLowerCase().endsWith(".wav");
    306                                         }
    307                                         @Override public String getDescription() {
    308                                                 return tr("Wave Audio files (*.wav)");
    309                                         }
    310                                 });
    311                                 fc.showOpenDialog(Main.parent);
    312                                 File sel = fc.getSelectedFile();
    313                                 if (!fc.getCurrentDirectory().getAbsolutePath().equals(dir))
    314                                         Main.pref.put("markers.lastaudiodirectory", fc.getCurrentDirectory().getAbsolutePath());
    315                                 if (sel == null)
    316                                         return;
    317                                 applyAudio(sel);
    318                                 Main.map.repaint();
    319                         }
    320                 });
    321 
    322212                JMenuItem syncaudio = new JMenuItem(tr("Synchronize Audio"), ImageProvider.get("audio-sync"));
    323213                syncaudio.putClientProperty("help", "Action/SynchronizeAudio");
    324214                syncaudio.addActionListener(new ActionListener(){
    325215                        public void actionPerformed(ActionEvent e) {
    326                                 adjustOffsetsOnAudioMarkers();
     216                                if (! AudioPlayer.paused()) {
     217                                        JOptionPane.showMessageDialog(Main.parent,tr("You need to pause audio at the moment when you hear your synchronization cue."));
     218                                        return;
     219                                }
     220                                AudioMarker recent = AudioMarker.recentlyPlayedMarker();
     221                                if (synchronizeAudioMarkers(recent)) {
     222                                        JOptionPane.showMessageDialog(Main.parent, tr("Audio synchronized at point " + recent.text));
     223                                } else {
     224                                        JOptionPane.showMessageDialog(Main.parent,tr("Unable to synchronize in layer being played."));
     225                                }
    327226                        }
    328227                });
     
    332231                moveaudio.addActionListener(new ActionListener(){
    333232                        public void actionPerformed(ActionEvent e) {
    334                                 makeAudioMarkerAtPlayHead();
     233                                if (! AudioPlayer.paused()) {
     234                                        JOptionPane.showMessageDialog(Main.parent,tr("You need to have paused audio at the point on the track where you want the marker."));
     235                                        return;
     236                                }
     237                                PlayHeadMarker playHeadMarker = Main.map.mapView.playHeadMarker;
     238                                if (playHeadMarker == null)
     239                                        return;
     240                                addAudioMarker(playHeadMarker.time, playHeadMarker.eastNorth);
     241                                Main.map.mapView.repaint();
    335242                        }
    336243                });
     
    344251                components.add(new JSeparator());
    345252                components.add(syncaudio);
    346                 components.add(applyaudio);
    347253                if (Main.pref.getBoolean("marker.traceaudio", true)) {
    348254                        components.add (moveaudio);
     
    354260        }
    355261
    356         private void adjustOffsetsOnAudioMarkers() {
    357                 if (! AudioPlayer.paused()) {
    358                         JOptionPane.showMessageDialog(Main.parent,tr("You need to pause audio at the moment when you hear your synchronization cue."));
    359                         return;
    360                 }
    361                 Marker startMarker = AudioMarker.recentlyPlayedMarker();
    362                 boolean explicitMarker = true;
     262        public boolean synchronizeAudioMarkers(AudioMarker startMarker) {
    363263                if (startMarker != null && ! data.contains(startMarker)) {
    364                         explicitMarker = false;
    365264                        startMarker = null;
    366265                }
     
    368267                        // find the first audioMarker in this layer
    369268                        for (Marker m : data) {
    370                                 if (m.getClass() == AudioMarker.class) {
    371                                         startMarker = m;
     269                                if (m instanceof AudioMarker) {
     270                                        startMarker = (AudioMarker) m;
    372271                                        break;
    373272                                }
    374273                        }
    375274                }
    376                 if (startMarker == null) {
    377                         // still no marker to work from - message?
    378                         JOptionPane.showMessageDialog(Main.parent,tr("No audio marker found in the layer to synchronize with."));
    379                         return;
    380                 }
     275                if (startMarker == null)
     276                        return false;
     277                       
    381278                // apply adjustment to all subsequent audio markers in the layer
    382279                double adjustment = AudioPlayer.position() - startMarker.offset; // in seconds
    383280                boolean seenStart = false;
    384                 URL url = ((AudioMarker)startMarker).url();
     281                URL url = startMarker.url();
    385282                for (Marker m : data) {
    386283                        if (m == startMarker)
     
    392289                        }
    393290                }
    394                
    395                 JOptionPane.showMessageDialog(Main.parent, explicitMarker ?
    396                         tr("Audio synchronized with most recently played marker and subsequent ones (that have the same sound track).") :
    397                         tr("Audio synchronized with audio markers in the layer (that have the same sound track as the first one)."));
    398         }
    399        
    400         private void makeAudioMarkerAtPlayHead() {
    401                 if (! AudioPlayer.paused()) {
    402                         JOptionPane.showMessageDialog(Main.parent,tr("You need to pause audio at the point on the track where you want the marker."));
    403                         return;
    404                 }
     291                return true;
     292        }
     293       
     294        public AudioMarker addAudioMarker(double time, EastNorth en) {
    405295                // find first audio marker to get absolute start time
    406296                double offset = 0.0;
     
    409299                        if (m.getClass() == AudioMarker.class) {
    410300                                am = (AudioMarker)m;
    411                                 offset = playheadTime - am.time;
     301                                offset = time - am.time;
    412302                                break;
    413303                        }
     
    415305                if (am == null) {
    416306                        JOptionPane.showMessageDialog(Main.parent,tr("No existing audio markers in this layer to offset from."));
    417                         return;
     307                        return null;
    418308                }
    419309
    420310                // make our new marker
    421                 AudioMarker newAudioMarker = AudioMarker.create(Main.proj.eastNorth2latlon(playheadPosition),
    422                         AudioMarker.inventName(offset), AudioPlayer.url().toString(), this, playheadTime, offset);
     311                AudioMarker newAudioMarker = AudioMarker.create(Main.proj.eastNorth2latlon(en),
     312                        AudioMarker.inventName(offset), AudioPlayer.url().toString(), this, time, offset);
    423313               
    424314                // insert it at the right place in a copy the collection
     
    440330                                newAudioMarker.adjustOffset(am.syncOffset()); // i.e. same as predecessor                               
    441331                        newData.add(newAudioMarker); // insert at end
    442                         newAudioMarker = null;
    443332                }
    444333               
     
    446335                data.clear();
    447336                data.addAll(newData);
    448                 Main.map.mapView.repaint();
     337                return newAudioMarker;
    449338        }
    450339       
Note: See TracChangeset for help on using the changeset viewer.