Ignore:
Timestamp:
05/19/21 09:01:33 (3 years ago)
Author:
davidb
Message:

A set of changes that spans three things: beat detection, time stretching; and a debug class motivated by the need to look at a canvas redraw issue most notable when a waveform widget is playing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/apollo/widgets/SampledTrack.java

    r1557 r1561  
    2727import javax.sound.sampled.LineUnavailableException;
    2828import javax.sound.sampled.UnsupportedAudioFileException;
     29import javax.swing.ButtonModel;
    2930import javax.swing.JSlider;
    3031import javax.swing.SwingUtilities;
     
    7273import org.expeditee.gio.swing.SwingConversions;
    7374import org.expeditee.gio.swing.SwingMiscManager;
     75import org.expeditee.gui.Browser;
    7476import org.expeditee.gui.DisplayController;
    7577import org.expeditee.gui.Frame;
    7678import org.expeditee.gui.FrameIO;
    7779import org.expeditee.gui.PopupManager;
     80import org.expeditee.gui.PopupManager.ExpandShrinkAnimator;
    7881import org.expeditee.gui.management.ResourceManager;
    7982import org.expeditee.items.ItemParentStateChangedEvent;
     
    101104import be.tarsos.dsp.io.jvm.WaveformWriter;
    102105
     106
     107
    103108/**
    104109 * The sampled track widgets in apollo.
     
    109114public class SampledTrack extends HeavyDutyInteractiveWidget implements TrackModelHandler, EffecientInvalidator, Observer {
    110115
    111         /** The observered subject. Can be null */
     116        /** The observed subject. Can be null */
     117        private SampledTrackModel unityTrackModel = null;
    112118        private SampledTrackModel trackModel = null;
    113119       
     
    144150       
    145151       
    146         /** If a track widget has a data string thaty contains META_SHOULD_INDEX_AUDIO_TAG, then
    147          * the track should not be indexed for searching the audio.... default isdoes not exist
     152        /** If a track widget has a data string that contains META_SHOULD_INDEX_AUDIO_TAG, then
     153         * the track should not be indexed for searching the audio.... default is that it does not exist
    148154         */
    149155        public static final String META_DONT_INDEX_AUDIO_TAG = "dontindexaudio";
     
    170176                                true);
    171177
     178                if (Browser.DEBUG) {
     179                        System.out.println("**** SampleTrack(source,audiobytes,format,mixTemplate): source="+ source);
     180                }               
    172181                // Must set upon construction - always
    173182                localFileName = AudioPathManager.generateLocateFileName("wav");
    174183                updateData(META_LOCALNAME_TAG, META_LOCALNAME_TAG + localFileName);
    175184               
    176                 trackModel = new SampledTrackModel(audioBytes, format, localFileName);
    177                
     185                unityTrackModel = new SampledTrackModel(audioBytes, format, localFileName);
     186                trackModel = unityTrackModel;
     187               
     188                boolean detectBeat = getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG,false);
     189                if (detectBeat) {
     190                        runDetectBeats();
     191                }
     192
    178193                // Ensure that the model is marked as modified so that it will save
    179194                trackModel.setAudioModifiedFlag(true);
    180195               
    181196                trackModel.setName(getStrippedDataString(TrackWidgetCommons.META_NAME_TAG));
    182 
     197               
     198               
    183199                // Create the immutable mix subject
    184200                if (mixTemplate == null) {
     
    222238                                TrackWidgetCommons.CACHE_DEPTH);
    223239               
     240                if (Browser.DEBUG) {
     241                        System.out.println("**** SampleTrack(source,args): source=" + source);
     242                }
     243               
    224244                // Read the metadata
    225245                localFileName = getStrippedDataString(META_LOCALNAME_TAG);
     
    261281                }
    262282        }
     283
     284        private void runDetectBeats()
     285        {
     286                if (Browser.DEBUG) {
     287                        System.out.println("*** runDetectBeats()");
     288                }
     289                try {
     290                        // consider adding support for parameters from data statement
     291                        int size = 512;
     292                        int overlap = 256;
     293                        trackModel.detectBeats(size,overlap);
     294                }
     295                catch (Exception ex) {
     296                        ex.printStackTrace();
     297                }
     298        }
     299
    263300
    264301        private void createGUI() {
     
    281318               
    282319                shouldOmitAudioIndexing = containsDataTrimmedIgnoreCase(META_DONT_INDEX_AUDIO_TAG);
    283 
     320               
     321                boolean beatDetect=getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG,false);
     322                               
    284323                playbackControlPopup = new PlaybackPopup();
     324                playbackControlPopup.beatDetectButton.setSelected(beatDetect);
    285325               
    286326                fulltrackView = (EditableSampledTrackGraphView)_swingComponent;
     
    317357                                if (playbackControlPopup == null) {
    318358                                        playbackControlPopup = new PlaybackPopup();
     359                                                       
    319360                                }
    320361
     
    329370                                       
    330371                                        // Determine where popup should show
    331                                         //int x = SampledTrack.this.getX();
     372                                        int x = SampledTrack.this.getX();
    332373                                        int y = SampledTrack.this.getY() - playbackControlPopup.getFullBounds().getHeight() - 2; // by default show above
    333374                                       
     
    340381                                                animationSource.y = y - 2;
    341382                                        }
    342 
     383                                        animationSource.x = x;
     384                                       
    343385                                        // Animate the popup
    344386                                        playbackControlPopup.getAutoHideTime().setLifetime(TrackWidgetCommons.POPUP_LIFETIME);
    345387                                        PopupManager.getInstance().add(playbackControlPopup);
     388                                       
    346389                                        playbackControlPopup.show();
    347390                                } else {
     
    459502                                }
    460503                               
     504                                else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_S) {
     505                                        // Stop
     506                                        TrackSequence ts = SoundDesk.getInstance().getTrackSequence(trackMix.getChannelID());
     507
     508                                        // reset any paused mark
     509                                        SoundDesk.getInstance().setPaused(trackMix.getChannelID(), false);
     510
     511                                        if (ts != null &&
     512                                                        ts.isPlaying()) {
     513                                                // Stop playback
     514                                                ApolloPlaybackMixer.getInstance().stop(ts);
     515                                        }
     516
     517                                } else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_R) {
     518                                        // rewind
     519
     520                                        trackModel.setSelection(0, 0);
     521                                        SoundDesk.getInstance().setPaused(trackMix.getChannelID(), false);
     522                                }
     523                                else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_B) {
     524
     525                                        boolean detectBeat = getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG,false);
     526                                        boolean toggleDetectBeat = (detectBeat) ? false : true;
     527
     528                                        updateData(TrackWidgetCommons.META_BEAT_DETECT_TAG, TrackWidgetCommons.META_BEAT_DETECT_TAG + toggleDetectBeat);
     529
     530                                        if (toggleDetectBeat) {
     531                                                runDetectBeats();
     532                                        }
     533                                }                       
    461534                                // Toggle pitch-track indexing
    462535                                else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_I) {
     
    753826                data.add(TrackWidgetCommons.META_RUNNINGMSTIME_TAG + getRunningMSTimeFromRawAudio());
    754827
     828                boolean beatDetect=getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG,false);
     829                if (beatDetect) {
     830                        data.add(TrackWidgetCommons.META_BEAT_DETECT_TAG + "true");
     831                }
     832
    755833                return data;
    756834        }
     
    844922                        try {
    845923                               
    846                                 trackModel = TrackModelLoadManager.getInstance().load(f.getPath(), localFileName, this, false);
     924                                unityTrackModel = TrackModelLoadManager.getInstance().load(f.getPath(), localFileName, this, false);
     925                                trackModel = unityTrackModel;
    847926                               
    848927                                if (trackModel == null) { // load operation canceled
     
    850929                                        return LOAD_STATE_INCOMPLETED;
    851930                                       
    852                                 } else if(isImporting) { // ensure that file path is null - since not yet saved
     931                                } else if (isImporting) { // ensure that file path is null - since not yet saved
    853932                                        trackModel.setFilepath(null);
    854933                                       
     
    889968                }
    890969               
     970                boolean beatDetect = getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG, false);
     971                if (beatDetect) {
     972                        runDetectBeats();
     973                }
     974
    891975                initObservers(); // sets default name if non set
    892976               
     
    913997                                        if (tinf == null) {
    914998
    915                                                 // Determine new initation time according to position
     999                                                // Determine new initiation time according to position
    9161000                                                long initTime = (parent != null) ?
    9171001                                                                FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent)
    9181002                                                                : 0;
    9191003
    920                                                 // Keep TrackGraphModel consistant
     1004                                                // Keep TrackGraphModel consistent
    9211005                                                AudioStructureModel.getInstance().onTrackWidgetAnchored(
    9221006                                                                localFileName,
     
    9381022               
    9391023                // Notify layout manager - not really needed but to be extra safe force the daemon
    940                 // to be super consistant
     1024                // to be super consistent
    9411025                FrameLayoutDaemon.getInstance().forceRecheck();
    9421026
     
    11441228        /**
    11451229         * To be called by the swing thread only
    1146          * This is nessessary to avoid runtime memory leaks!!
     1230         * This is necessary to avoid runtime memory leaks!!
    11471231         */
    11481232        private void releaseMemory(boolean onlyIfExpired) {
     
    13211405                                        parent = getParentFrame();
    13221406                                       
    1323                                         // Keep TrackGraphModel consistant
     1407                                        // Keep TrackGraphModel consistent
    13241408                                        AudioStructureModel.getInstance().onTrackWidgetAudioEdited(
    13251409                                                        localFileName,
     
    17491833         * @return
    17501834         *              The initiation time or this track in MS.
    1751          *              null if unavilable.
     1835         *              null if unavailable.
    17521836         */
    17531837        public Mutable.Long getInitiationTimeFromMeta() {
     
    20262110                public PlaybackPopup()
    20272111                {
     2112                        super();
     2113                       
    20282114                        miscButton.setActionCommand("expand");
    20292115                        SwingMiscManager.setJButtonIcon(miscButton, IconRepository.getIcon("expand.png"));
     
    20442130                public void onShow()
    20452131                {
     2132                        // Make sure the popup is in the most up to date position,
     2133                        // relative to the SampledTrack
     2134                        ExpandShrinkAnimator es_animator = (ExpandShrinkAnimator)this.getAnimator();
     2135                       
     2136                        int pcp_x_dim = this.getFullBounds().getWidth();
     2137                        int pcp_y_dim = this.getFullBounds().getHeight();
     2138                       
     2139                        int pcp_x_org = SampledTrack.this.getX();
     2140                        int pcp_y_org = SampledTrack.this.getY() - pcp_y_dim - 2; // by default show above
     2141                       
     2142                        if (pcp_y_org < 0) {
     2143                                // if doesn't fit above, show below
     2144                                pcp_y_org = SampledTrack.this.getY() + SampledTrack.this.getHeight() + 2;
     2145                        }
     2146                       
     2147                        AxisAlignedBoxBounds initial_bounds = new AxisAlignedBoxBounds(pcp_x_org,pcp_y_org,pcp_x_dim,pcp_y_dim);
     2148                       
     2149                        es_animator.setInitialBounds(initial_bounds);
     2150                       
    20462151                        // Listen for volume or mute changed events
    20472152                        trackMix.addObserver(this);
     
    20882193                                SoundDesk.getInstance().setPaused(trackMix.getChannelID(), false);
    20892194                               
    2090                         } else if (e.getSource() == miscButton) {
     2195                        }       
     2196                        else if (e.getSource() == beatDetectButton) {
     2197
     2198                                boolean detectBeat = getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG,false);
     2199                                boolean toggleDetectBeat = (detectBeat) ? false : true;
     2200
     2201                                updateData(TrackWidgetCommons.META_BEAT_DETECT_TAG, TrackWidgetCommons.META_BEAT_DETECT_TAG + toggleDetectBeat);
     2202
     2203                                if (toggleDetectBeat) {
     2204                                        runDetectBeats();
     2205                                }
     2206                        }
     2207                        else if (e.getSource() == miscButton) {
    20912208                                expand(false);
    20922209                        }
     
    22862403                                                        if (stretched_track_model != null) {
    22872404                                                                trackModel = stretched_track_model;
     2405                                                                fulltrackView.setTimeStretchFactor(time_stretch);
    22882406                                                        }
    22892407                                                }
     2408                                                else {
     2409                                                        double prev_time_stretch_factor = fulltrackView.getTimeStretchFactor();
     2410                                                        if (prev_time_stretch_factor != 1.0) {
     2411                                                                trackModel = unityTrackModel;
     2412                                                                fulltrackView.setTimeStretchFactor(1.0);
     2413                                                        }
     2414                                                }
     2415                                        }
     2416                                        else {
     2417                                                trackModel = unityTrackModel;
     2418                                                fulltrackView.setTimeStretchFactor(1.0);
    22902419                                        }
    22912420                                       
     
    24322561                                        );
    24332562                }
     2563               
     2564               
     2565                @Override
     2566                protected void beatDetectChanged() {
     2567
     2568                        ButtonModel buttonModel = beatDetectButton.getModel();
     2569                        boolean isSelected = buttonModel.isSelected();
     2570                        boolean isPressed  = buttonModel.isPressed();
     2571
     2572                        if (Browser.DEBUG) {
     2573                                System.out.println("**** isPressed=" + isPressed + ", isSelected=" + isSelected);
     2574                        }
     2575                       
     2576                        if (isPressed) {
     2577
     2578                                boolean newBeatDetectState = isSelected;
     2579                                boolean curBeatDetectState = getStrippedDataBool(TrackWidgetCommons.META_BEAT_DETECT_TAG,false);
     2580
     2581                                if (Browser.DEBUG) {
     2582                                        System.out.println("**** curBeatDetectState=" + curBeatDetectState + ",  newBeatDetectState=" + newBeatDetectState);
     2583                                }
     2584                               
     2585                                if (newBeatDetectState != curBeatDetectState) {
     2586
     2587                                        // change of state has occurred
     2588                                        updateData(TrackWidgetCommons.META_BEAT_DETECT_TAG, TrackWidgetCommons.META_BEAT_DETECT_TAG + newBeatDetectState);
     2589
     2590                                        if (newBeatDetectState==true) {
     2591                                                runDetectBeats();
     2592                                        }
     2593                                        else {
     2594                                                trackModel.clearBeats();
     2595                                        }
     2596
     2597                                        EditableSampledTrackGraphView thisTrackView = (EditableSampledTrackGraphView)_swingComponent;
     2598                                        thisTrackView.releaseBuffer();
     2599                                        thisTrackView.updateBuffer();
     2600                                }
     2601                        }
     2602                }
    24342603        }
    24352604
Note: See TracChangeset for help on using the changeset viewer.