mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-22 15:20:15 +02:00
Merge branch 'master' into HEAD
This commit is contained in:
commit
250a2ea12a
55
images/Help.xpm
Normal file
55
images/Help.xpm
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* XPM */
|
||||||
|
static const char * Help_xpm[] = {
|
||||||
|
"21 21 31 1",
|
||||||
|
" c None",
|
||||||
|
". c #6699FF",
|
||||||
|
"+ c #8CB2FE",
|
||||||
|
"@ c #CDDDFE",
|
||||||
|
"# c #F0F5FE",
|
||||||
|
"$ c #F9FAFE",
|
||||||
|
"% c #E4ECFE",
|
||||||
|
"& c #A4C2FE",
|
||||||
|
"* c #6698FE",
|
||||||
|
"= c #FFFFFF",
|
||||||
|
"- c #A9C5FE",
|
||||||
|
"; c #DAE6FE",
|
||||||
|
"> c #95B8FE",
|
||||||
|
", c #6D9DFE",
|
||||||
|
"' c #71A0FE",
|
||||||
|
") c #BFD4FE",
|
||||||
|
"! c #E9F0FE",
|
||||||
|
"~ c #F7F9FE",
|
||||||
|
"{ c #90B4FE",
|
||||||
|
"] c #C8DAFE",
|
||||||
|
"^ c #78A5FE",
|
||||||
|
"/ c #EEF3FE",
|
||||||
|
"( c #E3ECFE",
|
||||||
|
"_ c #6F9FFE",
|
||||||
|
": c #7CA7FE",
|
||||||
|
"< c #EDF2FE",
|
||||||
|
"[ c #E6EEFE",
|
||||||
|
"} c #DBE7FE",
|
||||||
|
"| c #87AEFE",
|
||||||
|
"1 c #FBFCFE",
|
||||||
|
"2 c #6799FE",
|
||||||
|
" ..... ",
|
||||||
|
" ......... ",
|
||||||
|
" ............. ",
|
||||||
|
" ............... ",
|
||||||
|
" .....+@#$%&*..... ",
|
||||||
|
" .....======-..... ",
|
||||||
|
" ......;>,')=!...... ",
|
||||||
|
" ..........,=~...... ",
|
||||||
|
"...........{=].......",
|
||||||
|
"..........^/(_.......",
|
||||||
|
".........:<['........",
|
||||||
|
".........}=|.........",
|
||||||
|
".........1=2.........",
|
||||||
|
" ........==......... ",
|
||||||
|
" ................... ",
|
||||||
|
" .......==........ ",
|
||||||
|
" .......==........ ",
|
||||||
|
" ............... ",
|
||||||
|
" ............. ",
|
||||||
|
" ......... ",
|
||||||
|
" ..... "};
|
@ -3,6 +3,7 @@
|
|||||||
;type analyze
|
;type analyze
|
||||||
;categories "http://lv2plug.in/ns/lv2core#AnalyserPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#AnalyserPlugin"
|
||||||
;name "Silence Finder..."
|
;name "Silence Finder..."
|
||||||
|
;manpage "Silence_Finder"
|
||||||
;action "Finding silence..."
|
;action "Finding silence..."
|
||||||
;info "Adds point labels in areas of silence according to the specified\nlevel and duration of silence. If too many silences are detected,\nincrease the silence level and duration; if too few are detected,\nreduce the level and duration."
|
;info "Adds point labels in areas of silence according to the specified\nlevel and duration of silence. If too many silences are detected,\nincrease the silence level and duration; if too few are detected,\nreduce the level and duration."
|
||||||
;author "Alex S. Brown"
|
;author "Alex S. Brown"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type analyze
|
;type analyze
|
||||||
;categories "http://lv2plug.in/ns/lv2core#AnalyserPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#AnalyserPlugin"
|
||||||
;name "Sound Finder..."
|
;name "Sound Finder..."
|
||||||
|
;manpage "Sound_Finder"
|
||||||
;action "Finding sound..."
|
;action "Finding sound..."
|
||||||
;info "Adds region labels for areas of sound according to the specified level\nand duration of surrounding silence. If too many labels are produced,\nincrease the silence level and duration; if too few are produced,\nreduce the level and duration."
|
;info "Adds region labels for areas of sound according to the specified level\nand duration of surrounding silence. If too many labels are produced,\nincrease the silence level and duration; if too few are produced,\nreduce the level and duration."
|
||||||
;author "Jeremy R. Brown"
|
;author "Jeremy R. Brown"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type process spectral
|
;type process spectral
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "Spectral edit parametric EQ..."
|
;name "Spectral edit parametric EQ..."
|
||||||
|
;manpage "Spectral_edit_parametric_EQ"
|
||||||
;action "Filtering..."
|
;action "Filtering..."
|
||||||
;author "Paul Licameli"
|
;author "Paul Licameli"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type process spectral
|
;type process spectral
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "Spectral edit shelves..."
|
;name "Spectral edit shelves..."
|
||||||
|
;manpage "Spectral_edit_shelves"
|
||||||
;action "Filtering..."
|
;action "Filtering..."
|
||||||
;author "Paul Licameli"
|
;author "Paul Licameli"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type process
|
;type process
|
||||||
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
|
||||||
;name "Studio Fade Out"
|
;name "Studio Fade Out"
|
||||||
|
;manpage "Fades#studio_fadeout"
|
||||||
;action "Applying Fade..."
|
;action "Applying Fade..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
;preview selection
|
;preview selection
|
||||||
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
|
||||||
;name "Adjustable Fade..."
|
;name "Adjustable Fade..."
|
||||||
|
;manpage "Adjustable_Fade"
|
||||||
|
;debug false
|
||||||
;action "Applying Fade..."
|
;action "Applying Fade..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type analyze
|
;type analyze
|
||||||
;categories "http://audacityteam.org/namespace#OnsetDetector"
|
;categories "http://audacityteam.org/namespace#OnsetDetector"
|
||||||
;name "Beat Finder..."
|
;name "Beat Finder..."
|
||||||
|
;manpage "Beat_Finder"
|
||||||
;action "Finding beats..."
|
;action "Finding beats..."
|
||||||
;author "Audacity"
|
;author "Audacity"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type process
|
;type process
|
||||||
;preview enabled
|
;preview enabled
|
||||||
;name "Clip Fix..."
|
;name "Clip Fix..."
|
||||||
|
;manpage "Clip_Fix"
|
||||||
;action "Reconstructing clips..."
|
;action "Reconstructing clips..."
|
||||||
;author "Benjamin Schwartz and Steve Daulton"
|
;author "Benjamin Schwartz and Steve Daulton"
|
||||||
;copyright "Licensing confirmed under terms of the GNU General Public License version 2"
|
;copyright "Licensing confirmed under terms of the GNU General Public License version 2"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
;mergeclips 1
|
;mergeclips 1
|
||||||
;restoresplits 0
|
;restoresplits 0
|
||||||
;name "Crossfade Clips"
|
;name "Crossfade Clips"
|
||||||
|
;manpage "Crossfade_Clips"
|
||||||
;action "Crossfading..."
|
;action "Crossfading..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
;version 4
|
;version 4
|
||||||
;type process
|
;type process
|
||||||
;name "Crossfade Tracks..."
|
;name "Crossfade Tracks..."
|
||||||
|
;manpage "Crossfade_Tracks"
|
||||||
|
;debug disabled
|
||||||
;action "Crossfading..."
|
;action "Crossfading..."
|
||||||
;preview selection
|
;preview selection
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
@ -69,4 +71,6 @@ audio clip, fade in, otherwise fade out."
|
|||||||
(setf out-dist (min out-dist (abs (- end (second (nth i clips)))))))
|
(setf out-dist (min out-dist (abs (- end (second (nth i clips)))))))
|
||||||
(if (< in-dist out-dist) 'in 'out)))
|
(if (< in-dist out-dist) 'in 'out)))
|
||||||
|
|
||||||
(crossfade type direction curve)
|
(if (< (length (get '*selection* 'tracks)) 2)
|
||||||
|
"Error.\nSelect 2 (or more) tracks to crossfade."
|
||||||
|
(crossfade type direction curve))
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
;preview linear
|
;preview linear
|
||||||
;categories "http://lv2plug.in/ns/lv2core#DelayPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#DelayPlugin"
|
||||||
;name "Delay..."
|
;name "Delay..."
|
||||||
|
;manpage "Delay"
|
||||||
;action "Applying Delay Effect..."
|
;action "Applying Delay Effect..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
;version 4
|
;version 4
|
||||||
;type analyze
|
;type analyze
|
||||||
;name "Regular Interval Labels..."
|
;name "Regular Interval Labels..."
|
||||||
|
;manpage "Regular_Interval_Labels"
|
||||||
;action "Adding equally-spaced labels to the label track..."
|
;action "Adding equally-spaced labels to the label track..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
;type process
|
;type process
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "High Pass Filter..."
|
;name "High Pass Filter..."
|
||||||
|
;manpage "High_Pass_Filter"
|
||||||
|
;debug disabled
|
||||||
;action "Performing High Pass Filter..."
|
;action "Performing High Pass Filter..."
|
||||||
;author "Dominic Mazzoni"
|
;author "Dominic Mazzoni"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
;type process
|
;type process
|
||||||
;categories "http://lv2plug.in/ns/lv2core/#DynamicsPlugin"
|
;categories "http://lv2plug.in/ns/lv2core/#DynamicsPlugin"
|
||||||
;name "Limiter..."
|
;name "Limiter..."
|
||||||
|
;manpage "Limiter"
|
||||||
|
;debug false
|
||||||
;action "Limiting..."
|
;action "Limiting..."
|
||||||
;preview enabled
|
;preview enabled
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
;type process
|
;type process
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "Low Pass Filter..."
|
;name "Low Pass Filter..."
|
||||||
|
;manpage "Low_Pass_Filter"
|
||||||
|
;debug disabled
|
||||||
;action "Performing Low Pass Filter..."
|
;action "Performing Low Pass Filter..."
|
||||||
;author "Dominic Mazzoni"
|
;author "Dominic Mazzoni"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,28 +3,27 @@
|
|||||||
;type process
|
;type process
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "Notch Filter..."
|
;name "Notch Filter..."
|
||||||
|
;manpage "Notch_Filter"
|
||||||
|
;debug false
|
||||||
;action "Applying Notch Filter..."
|
;action "Applying Notch Filter..."
|
||||||
;author "Steve Daulton and Bill Wharrie"
|
;author "Steve Daulton and Bill Wharrie"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
|
||||||
;; notch.ny by Steve Daulton and Bill Wharrie, September 2010.
|
;; notch.ny by Steve Daulton and Bill Wharrie
|
||||||
;; Last updated August 2015.
|
|
||||||
;; Released under terms of the GNU General Public License version 2:
|
;; Released under terms of the GNU General Public License version 2:
|
||||||
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html .
|
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html .
|
||||||
|
|
||||||
|
|
||||||
;control frequency "Frequency (Hz)" float-text "" 60 0 nil
|
;control frequency "Frequency (Hz)" float-text "" 60 0 nil
|
||||||
;control q "Q (higher value reduces width)" float-text "" 1 0.1 nil
|
;control q "Q (higher value reduces width)" float-text "" 1 0.1 1000
|
||||||
|
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
((< frequency 0.1) "Frequency must be at least 0.1 Hz.")
|
((< frequency 0.1) "Frequency must be at least 0.1 Hz.")
|
||||||
((>= frequency (/ *sound-srate* 2.0))
|
((>= frequency (/ *sound-srate* 2.0))
|
||||||
(format nil "Error:~%~%Frequency (~a Hz) is too high for track sample rate.~%~%~
|
(format nil "Error:~%~%Frequency (~a Hz) is too high for track sample rate.~%~%~
|
||||||
Track sample rate is ~a Hz~%~
|
Track sample rate is ~a Hz.~%~
|
||||||
Frequency must be less than ~a Hz."
|
Frequency must be less than ~a Hz."
|
||||||
frequency
|
frequency
|
||||||
*sound-srate*
|
*sound-srate*
|
||||||
(/ *sound-srate* 2.0)))
|
(/ *sound-srate* 2.0)))
|
||||||
((< q 0.1) "Q must be at least 0.1.")
|
|
||||||
(T (notch2 *track* frequency q)))
|
(T (notch2 *track* frequency q)))
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type generate
|
;type generate
|
||||||
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
|
||||||
;name "Pluck..."
|
;name "Pluck..."
|
||||||
|
;manpage "Pluck"
|
||||||
;preview linear
|
;preview linear
|
||||||
;action "Generating pluck sound..."
|
;action "Generating pluck sound..."
|
||||||
;info "MIDI values for C notes: 36, 48, 60 [middle C], 72, 84, 96."
|
;info "MIDI values for C notes: 36, 48, 60 [middle C], 72, 84, 96."
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type generate
|
;type generate
|
||||||
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
|
||||||
;name "Rhythm Track..."
|
;name "Rhythm Track..."
|
||||||
|
;manpage "Rhythm_Track"
|
||||||
;preview linear
|
;preview linear
|
||||||
;action "Generating Rhythm..."
|
;action "Generating Rhythm..."
|
||||||
;author "Dominic Mazzoni"
|
;author "Dominic Mazzoni"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "Risset Drum..."
|
;name "Risset Drum..."
|
||||||
|
;manpage "Risset_Drum"
|
||||||
;action "Generating Risset Drum..."
|
;action "Generating Risset Drum..."
|
||||||
;author "Steven Jones"
|
;author "Steven Jones"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
;version 3
|
;version 3
|
||||||
;type analyze
|
;type analyze
|
||||||
;name "Sample Data Export..."
|
;name "Sample Data Export..."
|
||||||
|
;manpage "Sample_Data_Export"
|
||||||
;action "Analyzing..."
|
;action "Analyzing..."
|
||||||
;maxlen 1000001
|
;maxlen 1000001
|
||||||
;categories "http://lv2plug.in/ns/lv2core#AnalyserPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#AnalyserPlugin"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
;version 4
|
;version 4
|
||||||
;type generate
|
;type generate
|
||||||
;name "Sample Data Import..."
|
;name "Sample Data Import..."
|
||||||
|
;manpage "Sample_Data_Import"
|
||||||
;action "Reading and rendering samples..."
|
;action "Reading and rendering samples..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
;preview linear
|
;preview linear
|
||||||
;categories "http://lv2plug.in/ns/lv2core#ModulatorPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#ModulatorPlugin"
|
||||||
;name "Tremolo..."
|
;name "Tremolo..."
|
||||||
|
;manpage "Tremolo"
|
||||||
|
;debug disabled
|
||||||
;action "Applying Tremolo..."
|
;action "Applying Tremolo..."
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
@ -18,11 +20,8 @@
|
|||||||
|
|
||||||
;control wave "Waveform type" choice "sine,triangle,sawtooth,inverse sawtooth,square" 0
|
;control wave "Waveform type" choice "sine,triangle,sawtooth,inverse sawtooth,square" 0
|
||||||
;control phase "Starting phase (degrees)" int "" 0 -180 180
|
;control phase "Starting phase (degrees)" int "" 0 -180 180
|
||||||
;control wet "Wet level (percent)" int "" 40 0 100
|
;control wet "Wet level (percent)" int "" 40 1 100
|
||||||
;control lfo "Frequency (Hz)" real "" 4 0 10
|
;control lfo "Frequency (Hz)" float-text "" 4 0.001 1000
|
||||||
|
|
||||||
; Limit to sensible range
|
|
||||||
(setq lfo (min 1000 (max lfo (/ (get-duration 1)))))
|
|
||||||
|
|
||||||
; Convert % to linear
|
; Convert % to linear
|
||||||
(setq wet (/ wet 200.0))
|
(setq wet (/ wet 200.0))
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type process
|
;type process
|
||||||
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
|
||||||
;name "Vocal Reduction and Isolation..."
|
;name "Vocal Reduction and Isolation..."
|
||||||
|
;manpage "Vocal_Reduction_and_Isolation"
|
||||||
;action "Applying Action..."
|
;action "Applying Action..."
|
||||||
;author "Robert Haenggi"
|
;author "Robert Haenggi"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
;type process
|
;type process
|
||||||
;preview linear
|
;preview linear
|
||||||
;name "Vocal Remover..."
|
;name "Vocal Remover..."
|
||||||
|
;manpage "Vocal_Remover"
|
||||||
;action "Removing center-panned audio..."
|
;action "Removing center-panned audio..."
|
||||||
;info "For reducing center-panned vocals"
|
;info "For reducing center-panned vocals"
|
||||||
;author "Steve Daulton"
|
;author "Steve Daulton"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
;preview enabled
|
;preview enabled
|
||||||
;categories "http://lv2plug.in/ns/lv2core#SpectralPlugin"
|
;categories "http://lv2plug.in/ns/lv2core#SpectralPlugin"
|
||||||
;name "Vocoder..."
|
;name "Vocoder..."
|
||||||
|
;manpage "Vocoder"
|
||||||
;action "Processing Vocoder..."
|
;action "Processing Vocoder..."
|
||||||
;author "Edgar-RFT"
|
;author "Edgar-RFT"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
@ -85,11 +85,6 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpMic, wxImage( 25, 25 ), wxT("Mic"));
|
DEFINE_IMAGE( bmpMic, wxImage( 25, 25 ), wxT("Mic"));
|
||||||
DEFINE_IMAGE( bmpSpeaker, wxImage( 25, 25 ), wxT("Speaker"));
|
DEFINE_IMAGE( bmpSpeaker, wxImage( 25, 25 ), wxT("Speaker"));
|
||||||
|
|
||||||
DEFINE_IMAGE( bmpPinnedPlayHead, wxImage( 27, 27 ), wxT("PinnedPlayHead"));
|
|
||||||
DEFINE_IMAGE( bmpUnpinnedPlayHead, wxImage( 27, 27 ), wxT("UnpinnedPlayHead"));
|
|
||||||
DEFINE_IMAGE( bmpPinnedRecordHead, wxImage( 27, 27 ), wxT("PinnedRecordHead"));
|
|
||||||
DEFINE_IMAGE( bmpUnpinnedRecordHead, wxImage( 27, 27 ), wxT("UnpinnedRecordHead"));
|
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagPaired );
|
SET_THEME_FLAGS( resFlagPaired );
|
||||||
DEFINE_IMAGE( bmpZoomFit, wxImage( 27, 27 ), wxT("ZoomFit"));
|
DEFINE_IMAGE( bmpZoomFit, wxImage( 27, 27 ), wxT("ZoomFit"));
|
||||||
DEFINE_IMAGE( bmpZoomFitDisabled, wxImage( 27, 27 ), wxT("ZoomFitDisabled"));
|
DEFINE_IMAGE( bmpZoomFitDisabled, wxImage( 27, 27 ), wxT("ZoomFitDisabled"));
|
||||||
@ -135,6 +130,8 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpTnSelectSoundDisabled, wxImage( 24, 24 ), wxT("TnSelectSoundDisabled"));
|
DEFINE_IMAGE( bmpTnSelectSoundDisabled, wxImage( 24, 24 ), wxT("TnSelectSoundDisabled"));
|
||||||
DEFINE_IMAGE( bmpTnSelectSilence, wxImage( 24, 24 ), wxT("TnSelectSilence"));
|
DEFINE_IMAGE( bmpTnSelectSilence, wxImage( 24, 24 ), wxT("TnSelectSilence"));
|
||||||
DEFINE_IMAGE( bmpTnSelectSilenceDisabled, wxImage( 24, 24 ), wxT("TnSelectSilenceDisabled"));
|
DEFINE_IMAGE( bmpTnSelectSilenceDisabled, wxImage( 24, 24 ), wxT("TnSelectSilenceDisabled"));
|
||||||
|
DEFINE_IMAGE( bmpOptions, wxImage( 24, 24 ), wxT("Options"));
|
||||||
|
DEFINE_IMAGE( bmpOptionsDisabled, wxImage( 24, 24 ), wxT("OptionsDisabled"));
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagNone );
|
SET_THEME_FLAGS( resFlagNone );
|
||||||
DEFINE_IMAGE( bmpLabelGlyph0, wxImage( 15, 23 ), wxT("LabelGlyph0"));
|
DEFINE_IMAGE( bmpLabelGlyph0, wxImage( 15, 23 ), wxT("LabelGlyph0"));
|
||||||
@ -161,13 +158,21 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpPostfishLoop, wxImage( 29, 17 ), wxT("PostfishLoop"));
|
DEFINE_IMAGE( bmpPostfishLoop, wxImage( 29, 17 ), wxT("PostfishLoop"));
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagNone );
|
SET_THEME_FLAGS( resFlagNone );
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpDockDown, wxImage( 15, 55 ), wxT("DockDown"));
|
DEFINE_IMAGE( bmpDockDown, wxImage( 15, 55 ), wxT("DockDown"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpDockDownShort, wxImage( 15, 27 ), wxT("DockDownShort"));
|
DEFINE_IMAGE( bmpDockDownShort, wxImage( 15, 27 ), wxT("DockDownShort"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpDockOver, wxImage( 15, 55 ), wxT("DockOver"));
|
DEFINE_IMAGE( bmpDockOver, wxImage( 15, 55 ), wxT("DockOver"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpDockOverShort, wxImage( 15, 27 ), wxT("DockOverShort"));
|
DEFINE_IMAGE( bmpDockOverShort, wxImage( 15, 27 ), wxT("DockOverShort"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpDockUp, wxImage( 15, 55 ), wxT("DockUp"));
|
DEFINE_IMAGE( bmpDockUp, wxImage( 15, 55 ), wxT("DockUp"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpDockUpShort, wxImage( 15, 27 ), wxT("DockUpShort"));
|
DEFINE_IMAGE( bmpDockUpShort, wxImage( 15, 27 ), wxT("DockUpShort"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpPinnedPlayRecordHead, wxImage( 27, 27 ), wxT("PinnedPlayRecordHead"));
|
DEFINE_IMAGE( bmpPinnedPlayRecordHead, wxImage( 27, 27 ), wxT("PinnedPlayRecordHead"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpUnpinnedPlayRecordHead, wxImage( 27, 27 ), wxT("UnpinnedPlayRecordHead"));
|
DEFINE_IMAGE( bmpUnpinnedPlayRecordHead, wxImage( 27, 27 ), wxT("UnpinnedPlayRecordHead"));
|
||||||
|
|
||||||
DEFINE_IMAGE( bmpSyncLockSelTile, wxImage(20, 22), wxT("SyncLockSelTile"));
|
DEFINE_IMAGE( bmpSyncLockSelTile, wxImage(20, 22), wxT("SyncLockSelTile"));
|
||||||
@ -176,7 +181,6 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpSyncLockTracksUp, wxImage( 20, 20 ), wxT("SyncLockTracksUp"));
|
DEFINE_IMAGE( bmpSyncLockTracksUp, wxImage( 20, 20 ), wxT("SyncLockTracksUp"));
|
||||||
DEFINE_IMAGE( bmpSyncLockTracksDisabled, wxImage( 20, 20 ), wxT("SyncLockTracksDisabled"));
|
DEFINE_IMAGE( bmpSyncLockTracksDisabled, wxImage( 20, 20 ), wxT("SyncLockTracksDisabled"));
|
||||||
DEFINE_IMAGE( bmpToggleScrubRuler, wxImage( 20, 20 ), wxT("ToggleScrubRuler"));
|
DEFINE_IMAGE( bmpToggleScrubRuler, wxImage( 20, 20 ), wxT("ToggleScrubRuler"));
|
||||||
// DEFINE_IMAGE( bmpSliderThumb, wxImage( 11, 14 ), wxT("SliderThumb"));
|
|
||||||
DEFINE_IMAGE( bmpSyncLockIcon, wxImage(12, 12), wxT("SyncLockIcon"));
|
DEFINE_IMAGE( bmpSyncLockIcon, wxImage(12, 12), wxT("SyncLockIcon"));
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagNewLine );
|
SET_THEME_FLAGS( resFlagNewLine );
|
||||||
@ -189,7 +193,9 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
|
|
||||||
SET_THEME_FLAGS( resFlagNone );
|
SET_THEME_FLAGS( resFlagNone );
|
||||||
DEFINE_IMAGE( bmpSliderThumb, wxImage( 11, 20 ), wxT("SliderThumb"));
|
DEFINE_IMAGE( bmpSliderThumb, wxImage( 11, 20 ), wxT("SliderThumb"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpSlider, wxImage( 80, 20 ), wxT("Slider"));
|
DEFINE_IMAGE( bmpSlider, wxImage( 80, 20 ), wxT("Slider"));
|
||||||
|
SET_THEME_FLAGS( resFlagSkip );
|
||||||
DEFINE_IMAGE( bmpHiliteSlider, wxImage( 80, 20 ), wxT("HiliteSlider"));
|
DEFINE_IMAGE( bmpHiliteSlider, wxImage( 80, 20 ), wxT("HiliteSlider"));
|
||||||
DEFINE_IMAGE( bmpUpButtonExpandSel, wxImage( 96, 18 ), wxT("UpButtonExpandSel"));
|
DEFINE_IMAGE( bmpUpButtonExpandSel, wxImage( 96, 18 ), wxT("UpButtonExpandSel"));
|
||||||
DEFINE_IMAGE( bmpDownButtonExpandSel, wxImage( 96, 18 ), wxT("DownButtonExpandSel"));
|
DEFINE_IMAGE( bmpDownButtonExpandSel, wxImage( 96, 18 ), wxT("DownButtonExpandSel"));
|
||||||
@ -206,8 +212,6 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpUpButtonSmall, wxImage( 27, 27 ), wxT("UpButtonSmall"));
|
DEFINE_IMAGE( bmpUpButtonSmall, wxImage( 27, 27 ), wxT("UpButtonSmall"));
|
||||||
DEFINE_IMAGE( bmpDownButtonSmall, wxImage( 27, 27 ), wxT("DownButtonSmall"));
|
DEFINE_IMAGE( bmpDownButtonSmall, wxImage( 27, 27 ), wxT("DownButtonSmall"));
|
||||||
DEFINE_IMAGE( bmpHiliteButtonSmall, wxImage( 27, 27 ), wxT("HiliteButtonSmall"));
|
DEFINE_IMAGE( bmpHiliteButtonSmall, wxImage( 27, 27 ), wxT("HiliteButtonSmall"));
|
||||||
//DEFINE_IMAGE( bmpVolumeSlider, wxImage( 100, 28 ), wxT("VolumeSlider"));
|
|
||||||
//DEFINE_IMAGE( bmpVolumeSliderThumb, wxImage( 10, 28 ), wxT("VolumeSliderThumb"));
|
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagNone );
|
SET_THEME_FLAGS( resFlagNone );
|
||||||
DEFINE_IMAGE( bmpMacUpButton, wxImage( 36, 36 ), wxT("MacUpButton"));
|
DEFINE_IMAGE( bmpMacUpButton, wxImage( 36, 36 ), wxT("MacUpButton"));
|
||||||
@ -216,8 +220,6 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpMacUpButtonSmall, wxImage( 27, 27 ), wxT("MacUpButtonSmall"));
|
DEFINE_IMAGE( bmpMacUpButtonSmall, wxImage( 27, 27 ), wxT("MacUpButtonSmall"));
|
||||||
DEFINE_IMAGE( bmpMacDownButtonSmall, wxImage( 27, 27 ), wxT("MacDownButtonSmall"));
|
DEFINE_IMAGE( bmpMacDownButtonSmall, wxImage( 27, 27 ), wxT("MacDownButtonSmall"));
|
||||||
DEFINE_IMAGE( bmpMacHiliteButtonSmall, wxImage( 27, 27 ), wxT("MacHiliteButtonSmall"));
|
DEFINE_IMAGE( bmpMacHiliteButtonSmall, wxImage( 27, 27 ), wxT("MacHiliteButtonSmall"));
|
||||||
DEFINE_IMAGE( bmpMacSlider, wxImage( 100, 28 ), wxT("MacSlider"));
|
|
||||||
DEFINE_IMAGE( bmpMacSliderThumb, wxImage( 17, 28 ), wxT("MacSliderThumb"));
|
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagInternal );
|
SET_THEME_FLAGS( resFlagInternal );
|
||||||
DEFINE_IMAGE( bmpRecoloredUpLarge, wxImage( 48, 48 ), wxT("RecoloredUpLarge"));
|
DEFINE_IMAGE( bmpRecoloredUpLarge, wxImage( 48, 48 ), wxT("RecoloredUpLarge"));
|
||||||
@ -241,19 +243,7 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpTopFrequencyCursor, wxImage( 32, 32 ), wxT("TopFrequencyCursor"));
|
DEFINE_IMAGE( bmpTopFrequencyCursor, wxImage( 32, 32 ), wxT("TopFrequencyCursor"));
|
||||||
DEFINE_IMAGE( bmpBandWidthCursor, wxImage(32, 32), wxT("BandWidthCursor"));
|
DEFINE_IMAGE( bmpBandWidthCursor, wxImage(32, 32), wxT("BandWidthCursor"));
|
||||||
|
|
||||||
|
//SET_THEME_FLAGS( resFlagNewLine );
|
||||||
|
|
||||||
/*
|
|
||||||
DEFINE_IMAGE( bmpToolBarToggle, wxImage( 43, 35 ), wxT("ToolBarToggle"));
|
|
||||||
DEFINE_IMAGE( bmpToolBarTarget, wxImage( 17, 26 ), wxT("ToolBarTarget"));
|
|
||||||
DEFINE_IMAGE( bmpToolBarGrabber, wxImage( 17, 8 ), wxT("ToolBarGrabber"));
|
|
||||||
DEFINE_IMAGE( bmpArrow, wxImage( 9, 16 ), wxT("Arrow"));
|
|
||||||
DEFINE_IMAGE( bmpUploadFile, wxImage( 16, 16 ), wxT("UploadFile"));
|
|
||||||
DEFINE_IMAGE( bmpUploadFolder, wxImage( 16, 16 ), wxT("UploadFolder"));
|
|
||||||
DEFINE_IMAGE( bmpUploadMp3, wxImage( 16, 16 ), wxT("UploadMp3"));
|
|
||||||
DEFINE_IMAGE( bmpUploadUp, wxImage( 16, 16 ), wxT("UploadUp"));
|
|
||||||
*/
|
|
||||||
SET_THEME_FLAGS( resFlagNewLine );
|
|
||||||
|
|
||||||
// DA: The logo with name xpm has a different width.
|
// DA: The logo with name xpm has a different width.
|
||||||
#ifdef EXPERIMENTAL_DA
|
#ifdef EXPERIMENTAL_DA
|
||||||
@ -264,9 +254,11 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
|
|
||||||
#define LOGOWITHNAME_HEIGHT 200
|
#define LOGOWITHNAME_HEIGHT 200
|
||||||
|
|
||||||
|
SET_THEME_FLAGS( resFlagSkip | resFlagNewLine );
|
||||||
DEFINE_IMAGE( bmpAudacityLogo, wxImage( 215, 190 ), wxT("AudacityLogo"));
|
DEFINE_IMAGE( bmpAudacityLogo, wxImage( 215, 190 ), wxT("AudacityLogo"));
|
||||||
DEFINE_IMAGE( bmpAudacityLogo48x48, wxImage( 48, 48 ), wxT("AudacityLogo48x48"));
|
DEFINE_IMAGE( bmpAudacityLogo48x48, wxImage( 48, 48 ), wxT("AudacityLogo48x48"));
|
||||||
|
|
||||||
|
|
||||||
DEFINE_COLOUR( clrBlank, wxColour( 64, 64, 64), wxT("Blank"));
|
DEFINE_COLOUR( clrBlank, wxColour( 64, 64, 64), wxT("Blank"));
|
||||||
DEFINE_COLOUR( clrUnselected, wxColour( 30, 30, 30), wxT("Unselected"));
|
DEFINE_COLOUR( clrUnselected, wxColour( 30, 30, 30), wxT("Unselected"));
|
||||||
DEFINE_COLOUR( clrSelected, wxColour( 93, 65, 93), wxT("Selected"));
|
DEFINE_COLOUR( clrSelected, wxColour( 93, 65, 93), wxT("Selected"));
|
||||||
|
@ -1508,15 +1508,26 @@ bool AudacityApp::OnInit()
|
|||||||
|
|
||||||
AudacityProject *project;
|
AudacityProject *project;
|
||||||
{
|
{
|
||||||
|
// Bug 718: Position splash screen on same screen
|
||||||
|
// as where Audacity project will appear.
|
||||||
|
wxRect wndRect;
|
||||||
|
bool bMaximized = false;
|
||||||
|
bool bIconized = false;
|
||||||
|
GetNextWindowPlacement(&wndRect, &bMaximized, &bIconized);
|
||||||
|
|
||||||
wxSplashScreen temporarywindow(
|
wxSplashScreen temporarywindow(
|
||||||
logo,
|
logo,
|
||||||
wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT,
|
wxSPLASH_NO_CENTRE | wxSPLASH_NO_TIMEOUT,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
wxID_ANY,
|
wxID_ANY,
|
||||||
wxDefaultPosition,
|
wxDefaultPosition,
|
||||||
wxDefaultSize,
|
wxDefaultSize,
|
||||||
wxSTAY_ON_TOP);
|
wxSTAY_ON_TOP);
|
||||||
|
// Possibly move it on to the second screen...
|
||||||
|
temporarywindow.SetPosition( wndRect.GetTopLeft() );
|
||||||
|
// Centered on whichever screen it is on.
|
||||||
|
temporarywindow.Center();
|
||||||
temporarywindow.SetTitle(_("Audacity is starting up..."));
|
temporarywindow.SetTitle(_("Audacity is starting up..."));
|
||||||
SetTopWindow(&temporarywindow);
|
SetTopWindow(&temporarywindow);
|
||||||
|
|
||||||
|
@ -2130,7 +2130,7 @@ void AudioIO::PrepareMidiIterator(bool send, double offset)
|
|||||||
// Iterator not yet intialized, must add each track...
|
// Iterator not yet intialized, must add each track...
|
||||||
for (i = 0; i < nTracks; i++) {
|
for (i = 0; i < nTracks; i++) {
|
||||||
NoteTrack *t = mMidiPlaybackTracks[i];
|
NoteTrack *t = mMidiPlaybackTracks[i];
|
||||||
Alg_seq_ptr seq = t->GetSequence();
|
Alg_seq_ptr seq = &t->GetSeq();
|
||||||
// mark sequence tracks as "in use" since we're handing this
|
// mark sequence tracks as "in use" since we're handing this
|
||||||
// off to another thread and want to make sure nothing happens
|
// off to another thread and want to make sure nothing happens
|
||||||
// to the data until playback finishes. This is just a sanity check.
|
// to the data until playback finishes. This is just a sanity check.
|
||||||
@ -2387,7 +2387,7 @@ void AudioIO::StopStream()
|
|||||||
int nTracks = mMidiPlaybackTracks.size();
|
int nTracks = mMidiPlaybackTracks.size();
|
||||||
for (int i = 0; i < nTracks; i++) {
|
for (int i = 0; i < nTracks; i++) {
|
||||||
NoteTrack *t = mMidiPlaybackTracks[i];
|
NoteTrack *t = mMidiPlaybackTracks[i];
|
||||||
Alg_seq_ptr seq = t->GetSequence();
|
Alg_seq_ptr seq = &t->GetSeq();
|
||||||
seq->set_in_use(false);
|
seq->set_in_use(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -933,14 +933,15 @@ void Envelope::InsertSpace( double t0, double tlen )
|
|||||||
point.SetT( point.GetT() + tlen );
|
point.SetT( point.GetT() + tlen );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// increase track len, before insert or replace,
|
||||||
|
// since it range chacks the values.
|
||||||
|
mTrackLen += tlen;
|
||||||
// Preserve the right-side limit.
|
// Preserve the right-side limit.
|
||||||
if ( 1 + range.first < range.second )
|
if ( 1 + range.first < range.second )
|
||||||
// There was a control point already.
|
// There was a control point already.
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
InsertOrReplaceRelative( t0 + tlen, val );
|
InsertOrReplaceRelative( t0 + tlen, val );
|
||||||
|
|
||||||
mTrackLen += tlen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Envelope::Reassign(double when, double value)
|
int Envelope::Reassign(double when, double value)
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
* This returns the string path to where the user may have put plug-ins
|
* This returns the string path to where the user may have put plug-ins
|
||||||
* if they don't have system admin rights. Under default settings, it's
|
* if they don't have system admin rights. Under default settings, it's
|
||||||
* <DataDir>/Plug-Ins/ */
|
* <DataDir>/Plug-Ins/ */
|
||||||
static wxString PlugInDir();
|
static wxString PlugInDir(); // Windows and Mac only
|
||||||
static wxString ThemeDir();
|
static wxString ThemeDir();
|
||||||
static wxString ThemeComponentsDir();
|
static wxString ThemeComponentsDir();
|
||||||
static wxString ThemeCachePng();
|
static wxString ThemeCachePng();
|
||||||
|
@ -493,6 +493,9 @@ FreqWindow::FreqWindow(wxWindow * parent, wxWindowID id,
|
|||||||
|
|
||||||
Layout();
|
Layout();
|
||||||
Fit();
|
Fit();
|
||||||
|
// Bug 1607:
|
||||||
|
Center();
|
||||||
|
|
||||||
SetMinSize(GetSize());
|
SetMinSize(GetSize());
|
||||||
mAlgChoice->SetFocus();
|
mAlgChoice->SetFocus();
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,7 @@ for drawing different aspects of the label and its text box.
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/brush.h>
|
#include <wx/brush.h>
|
||||||
@ -473,7 +474,9 @@ void LabelTrack::ComputeLayout(const wxRect & r, const ZoomInfo &zoomInfo) const
|
|||||||
// Initially none of the rows have been used.
|
// Initially none of the rows have been used.
|
||||||
// So set a value that is less than any valid value.
|
// So set a value that is less than any valid value.
|
||||||
{
|
{
|
||||||
const int xStart = zoomInfo.TimeToPosition(0.0, r.x) - 100;
|
// Bug 502: With dragging left of zeros, labels can be in
|
||||||
|
// negative space. So set least possible value as starting point.
|
||||||
|
const int xStart = INT_MIN;
|
||||||
for (auto &x : xUsed)
|
for (auto &x : xUsed)
|
||||||
x = xStart;
|
x = xStart;
|
||||||
}
|
}
|
||||||
|
@ -461,6 +461,7 @@ void Lyrics::OnKeyEvent(wxKeyEvent & event)
|
|||||||
{
|
{
|
||||||
AudacityProject *project = GetActiveProject();
|
AudacityProject *project = GetActiveProject();
|
||||||
project->GetCommandManager()->FilterKeyEvent(project, event, true);
|
project->GetCommandManager()->FilterKeyEvent(project, event, true);
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lyrics::OnPaint(wxPaintEvent & WXUNUSED(event))
|
void Lyrics::OnPaint(wxPaintEvent & WXUNUSED(event))
|
||||||
|
@ -130,6 +130,7 @@ LyricsWindow::LyricsWindow(AudacityProject *parent):
|
|||||||
wxCommandEventHandler(LyricsWindow::OnTimer),
|
wxCommandEventHandler(LyricsWindow::OnTimer),
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
|
Center();
|
||||||
}
|
}
|
||||||
|
|
||||||
LyricsWindow::~LyricsWindow()
|
LyricsWindow::~LyricsWindow()
|
||||||
|
297
src/Menus.cpp
297
src/Menus.cpp
@ -999,7 +999,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
c->AddSeparator();
|
c->AddSeparator();
|
||||||
c->AddCheck(wxT("MoveSelectionWithTracks"), _("&Move Selection with Tracks (on/off)"),
|
c->AddCheck(wxT("MoveSelectionWithTracks"), _("&Move Selection with Tracks (on/off)"),
|
||||||
FN(OnMoveSelectionWithTracks),
|
FN(OnMoveSelectionWithTracks),
|
||||||
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), 1L),
|
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), 0L),
|
||||||
AlwaysEnabledFlag, AlwaysEnabledFlag);
|
AlwaysEnabledFlag, AlwaysEnabledFlag);
|
||||||
c->EndSubMenu();
|
c->EndSubMenu();
|
||||||
|
|
||||||
@ -1240,7 +1240,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
// Ext-Bar Menu
|
// Ext-Bar Menu
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
c->BeginMenu("Ext-Bar");
|
c->BeginMenu("Ext-&Bar");
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -1399,7 +1399,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
c->SetDefaultFlags(AlwaysEnabledFlag, AlwaysEnabledFlag);
|
c->SetDefaultFlags(AlwaysEnabledFlag, AlwaysEnabledFlag);
|
||||||
c->BeginMenu("Ext-Command");
|
c->BeginMenu("Ext-Co&mmand");
|
||||||
|
|
||||||
c->AddGlobalCommand(wxT("PrevWindow"), _("Move backward thru active windows"), FN(PrevWindow), wxT("Alt+Shift+F6"));
|
c->AddGlobalCommand(wxT("PrevWindow"), _("Move backward thru active windows"), FN(PrevWindow), wxT("Alt+Shift+F6"));
|
||||||
c->AddGlobalCommand(wxT("NextWindow"), _("Move forward thru active windows"), FN(NextWindow), wxT("Alt+F6"));
|
c->AddGlobalCommand(wxT("NextWindow"), _("Move forward thru active windows"), FN(NextWindow), wxT("Alt+F6"));
|
||||||
@ -1438,8 +1438,8 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
c->AddItem(wxT("CursorLongJumpLeft"), _("Cursor Long Jump Left"), FN(OnCursorLongJumpLeft), wxT("Shift+,"));
|
c->AddItem(wxT("CursorLongJumpLeft"), _("Cursor Long Jump Left"), FN(OnCursorLongJumpLeft), wxT("Shift+,"));
|
||||||
c->AddItem(wxT("CursorLongJumpRight"), _("Cursor Long Jump Right"), FN(OnCursorLongJumpRight), wxT("Shift+."));
|
c->AddItem(wxT("CursorLongJumpRight"), _("Cursor Long Jump Right"), FN(OnCursorLongJumpRight), wxT("Shift+."));
|
||||||
|
|
||||||
c->AddItem(wxT("ClipLeft"), _("Clip Left"), FN(OnClipLeft), wxT(""));
|
c->AddItem(wxT("ClipLeft"), _("Clip Left"), FN(OnClipLeft), wxT("\twantKeyup"));
|
||||||
c->AddItem(wxT("ClipRight"), _("Clip Right"), FN(OnClipRight), wxT(""));
|
c->AddItem(wxT("ClipRight"), _("Clip Right"), FN(OnClipRight), wxT("\twantKeyup"));
|
||||||
c->EndSubMenu();
|
c->EndSubMenu();
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -2082,7 +2082,7 @@ void AudacityProject::SelectAllIfNone()
|
|||||||
auto flags = GetUpdateFlags();
|
auto flags = GetUpdateFlags();
|
||||||
if(!(flags & TracksSelectedFlag) ||
|
if(!(flags & TracksSelectedFlag) ||
|
||||||
(mViewInfo.selectedRegion.isPoint()))
|
(mViewInfo.selectedRegion.isPoint()))
|
||||||
OnSelectAll();
|
OnSelectSomething();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::StopIfPaused()
|
void AudacityProject::StopIfPaused()
|
||||||
@ -3081,14 +3081,55 @@ void AudacityProject::OnSelContractRight(const wxEvent * evt)
|
|||||||
OnCursorLeft( true, true, bKeyUp );
|
OnCursorLeft( true, true, bKeyUp );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnClipLeft()
|
void AudacityProject::DoClipLeftOrRight(bool right, bool keyUp )
|
||||||
{
|
{
|
||||||
mTrackPanel->OnClipMove(false);
|
if (keyUp) {
|
||||||
|
GetUndoManager()->StopConsolidating();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &panel = *GetTrackPanel();
|
||||||
|
|
||||||
|
auto amount = TrackPanel::OnClipMove
|
||||||
|
( mViewInfo, panel.GetFocusedTrack(),
|
||||||
|
*GetTracks(), IsSyncLocked(), right );
|
||||||
|
|
||||||
|
panel.ScrollIntoView(mViewInfo.selectedRegion.t0());
|
||||||
|
panel.Refresh(false);
|
||||||
|
|
||||||
|
if (amount != 0.0) {
|
||||||
|
wxString message = right? _("Time shifted clips to the right") :
|
||||||
|
_("Time shifted clips to the left");
|
||||||
|
|
||||||
|
// The following use of the UndoPush flags is so that both a single
|
||||||
|
// keypress (keydown, then keyup), and holding down a key
|
||||||
|
// (multiple keydowns followed by a keyup) result in a single
|
||||||
|
// entry in Audacity's history dialog.
|
||||||
|
PushState(message, _("Time-Shift"), UndoPush::CONSOLIDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( amount == 0.0 )
|
||||||
|
panel.MessageForScreenReader( _("clip not moved"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnClipRight()
|
void AudacityProject::OnClipLeft(const wxEvent* evt)
|
||||||
{
|
{
|
||||||
mTrackPanel->OnClipMove(true);
|
if (evt)
|
||||||
|
DoClipLeftOrRight( false, evt->GetEventType() == wxEVT_KEY_UP );
|
||||||
|
else { // called from menu, so simulate keydown and keyup
|
||||||
|
DoClipLeftOrRight( false, false );
|
||||||
|
DoClipLeftOrRight( false, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnClipRight(const wxEvent* evt)
|
||||||
|
{
|
||||||
|
if (evt)
|
||||||
|
DoClipLeftOrRight( true, evt->GetEventType() == wxEVT_KEY_UP );
|
||||||
|
else { // called from menu, so simulate keydown and keyup
|
||||||
|
DoClipLeftOrRight( true, false );
|
||||||
|
DoClipLeftOrRight( true, true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//this pops up a dialog which allows the left selection to be set.
|
//this pops up a dialog which allows the left selection to be set.
|
||||||
@ -5374,20 +5415,87 @@ void AudacityProject::OnSplitNew()
|
|||||||
RedrawProject();
|
RedrawProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnSelectAll()
|
int AudacityProject::CountSelectedWaveTracks()
|
||||||
{
|
{
|
||||||
TrackListIterator iter(GetTracks());
|
TrackListIterator iter(GetTracks());
|
||||||
|
|
||||||
Track *t = iter.First();
|
Track *t = iter.First();
|
||||||
while (t) {
|
|
||||||
t->SetSelected(true);
|
int count =0;
|
||||||
t = iter.Next();
|
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||||
|
if( (t->GetKind() == Track::Wave) && t->GetSelected() )
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AudacityProject::CountSelectedTracks()
|
||||||
|
{
|
||||||
|
TrackListIterator iter(GetTracks());
|
||||||
|
Track *t = iter.First();
|
||||||
|
|
||||||
|
int count =0;
|
||||||
|
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||||
|
if( t->GetSelected() )
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnSelectTimeAndTracks(bool bAllTime, bool bAllTracks)
|
||||||
|
{
|
||||||
|
if( bAllTime )
|
||||||
mViewInfo.selectedRegion.setTimes(
|
mViewInfo.selectedRegion.setTimes(
|
||||||
mTracks->GetMinOffset(), mTracks->GetEndTime());
|
mTracks->GetMinOffset(), mTracks->GetEndTime());
|
||||||
|
|
||||||
ModifyState(false);
|
if( bAllTracks ){
|
||||||
|
TrackListIterator iter(GetTracks());
|
||||||
|
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||||
|
t->SetSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModifyState(false);
|
||||||
|
mTrackPanel->Refresh(false);
|
||||||
|
if (mMixerBoard)
|
||||||
|
mMixerBoard->Refresh(false);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnSelectAllTime()
|
||||||
|
{
|
||||||
|
OnSelectTimeAndTracks( true, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnSelectAllTracks()
|
||||||
|
{
|
||||||
|
OnSelectTimeAndTracks( false, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnSelectAll()
|
||||||
|
{
|
||||||
|
OnSelectTimeAndTracks( true, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function selects all tracks if no tracks selected,
|
||||||
|
// and all time if no time selected.
|
||||||
|
// There is an argument for making it just count wave tracks,
|
||||||
|
// However you could then not select a label and cut it,
|
||||||
|
// without this function selecting all tracks.
|
||||||
|
void AudacityProject::OnSelectSomething()
|
||||||
|
{
|
||||||
|
bool bTime = mViewInfo.selectedRegion.isPoint();
|
||||||
|
bool bTracks = CountSelectedTracks() == 0;
|
||||||
|
|
||||||
|
if( bTime || bTracks )
|
||||||
|
OnSelectTimeAndTracks(bTime,bTracks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::SelectNone()
|
||||||
|
{
|
||||||
|
TrackListIterator iter(GetTracks());
|
||||||
|
Track *t = iter.First();
|
||||||
|
while (t) {
|
||||||
|
t->SetSelected(false);
|
||||||
|
t = iter.Next();
|
||||||
|
}
|
||||||
mTrackPanel->Refresh(false);
|
mTrackPanel->Refresh(false);
|
||||||
if (mMixerBoard)
|
if (mMixerBoard)
|
||||||
mMixerBoard->Refresh(false);
|
mMixerBoard->Refresh(false);
|
||||||
@ -5524,6 +5632,8 @@ AudacityProject::FoundClip AudacityProject::FindNextClip(const WaveTrack* wt, do
|
|||||||
result.waveTrack = wt;
|
result.waveTrack = wt;
|
||||||
const auto clips = wt->SortedClipArray();
|
const auto clips = wt->SortedClipArray();
|
||||||
|
|
||||||
|
t0 = AdjustForFindingStartTimes(clips, t0);
|
||||||
|
|
||||||
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
||||||
return clip->GetStartTime() == t0; });
|
return clip->GetStartTime() == t0; });
|
||||||
if (p != clips.end() && (*p)->GetEndTime() > t1) {
|
if (p != clips.end() && (*p)->GetEndTime() > t1) {
|
||||||
@ -5552,6 +5662,8 @@ AudacityProject::FoundClip AudacityProject::FindPrevClip(const WaveTrack* wt, do
|
|||||||
result.waveTrack = wt;
|
result.waveTrack = wt;
|
||||||
const auto clips = wt->SortedClipArray();
|
const auto clips = wt->SortedClipArray();
|
||||||
|
|
||||||
|
t0 = AdjustForFindingStartTimes(clips, t0);
|
||||||
|
|
||||||
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
auto p = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
||||||
return clip->GetStartTime() == t0; });
|
return clip->GetStartTime() == t0; });
|
||||||
if (p != clips.end() && (*p)->GetEndTime() < t1) {
|
if (p != clips.end() && (*p)->GetEndTime() < t1) {
|
||||||
@ -5677,10 +5789,10 @@ void AudacityProject::OnSelectClip(bool next)
|
|||||||
|
|
||||||
message += temp;
|
message += temp;
|
||||||
}
|
}
|
||||||
if (result.waveTrack->GetNumClips() > 1 || nTracksSearched == 1) {
|
temp.Printf(wxT("%d %s %d %s "), result.index + 1, _("of"), result.waveTrack->GetNumClips(),
|
||||||
temp.Printf(wxT("%d %s %d "), result.index + 1, _("of"), result.waveTrack->GetNumClips());
|
result.waveTrack->GetNumClips() == 1 ? _("clip") : _("clips"));
|
||||||
message += temp;
|
message += temp;
|
||||||
}
|
|
||||||
message += wxT(", ");
|
message += wxT(", ");
|
||||||
}
|
}
|
||||||
mTrackPanel->MessageForScreenReader(message);
|
mTrackPanel->MessageForScreenReader(message);
|
||||||
@ -5719,20 +5831,6 @@ void AudacityProject::OnSelectSyncLockSel()
|
|||||||
mMixerBoard->Refresh(false);
|
mMixerBoard->Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnSelectAllTracks()
|
|
||||||
{
|
|
||||||
TrackListIterator iter(GetTracks());
|
|
||||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
|
||||||
t->SetSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ModifyState(false);
|
|
||||||
|
|
||||||
mTrackPanel->Refresh(false);
|
|
||||||
if (mMixerBoard)
|
|
||||||
mMixerBoard->Refresh(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// View Menu
|
// View Menu
|
||||||
//
|
//
|
||||||
@ -6527,27 +6625,18 @@ AudacityProject::FoundClipBoundary AudacityProject::FindNextClipBoundary(const W
|
|||||||
{
|
{
|
||||||
AudacityProject::FoundClipBoundary result{};
|
AudacityProject::FoundClipBoundary result{};
|
||||||
result.waveTrack = wt;
|
result.waveTrack = wt;
|
||||||
|
|
||||||
const auto clips = wt->SortedClipArray();
|
const auto clips = wt->SortedClipArray();
|
||||||
|
double timeStart = AdjustForFindingStartTimes(clips, time);
|
||||||
|
double timeEnd = AdjustForFindingEndTimes(clips, time);
|
||||||
|
|
||||||
auto pStart = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
auto pStart = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
||||||
return clip->GetStartTime() > time; });
|
return clip->GetStartTime() > timeStart; });
|
||||||
auto pEnd = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
auto pEnd = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
||||||
return clip->GetEndTime() > time; });
|
return clip->GetEndTime() > timeEnd; });
|
||||||
|
|
||||||
if (pStart != clips.end() && pEnd != clips.end()) {
|
if (pStart != clips.end() && pEnd != clips.end()) {
|
||||||
if ((*pStart)->GetStartTime() < (*pEnd)->GetEndTime()) {
|
if ((*pEnd)->SharesBoundaryWithNextClip(*pStart)) {
|
||||||
result.nFound = 1;
|
// boundary between two clips which are immediately next to each other.
|
||||||
result.time = (*pStart)->GetStartTime();
|
|
||||||
result.index1 = std::distance(clips.begin(), pStart);
|
|
||||||
result.clipStart1 = true;
|
|
||||||
}
|
|
||||||
else if ((*pStart)->GetStartTime() > (*pEnd)->GetEndTime()) {
|
|
||||||
result.nFound = 1;
|
|
||||||
result.time = (*pEnd)->GetEndTime();
|
|
||||||
result.index1 = std::distance(clips.begin(), pEnd);
|
|
||||||
result.clipStart1 = false;
|
|
||||||
}
|
|
||||||
else { // both the end of one clip and the start of the next clip
|
|
||||||
result.nFound = 2;
|
result.nFound = 2;
|
||||||
result.time = (*pEnd)->GetEndTime();
|
result.time = (*pEnd)->GetEndTime();
|
||||||
result.index1 = std::distance(clips.begin(), pEnd);
|
result.index1 = std::distance(clips.begin(), pEnd);
|
||||||
@ -6555,6 +6644,18 @@ AudacityProject::FoundClipBoundary AudacityProject::FindNextClipBoundary(const W
|
|||||||
result.index2 = std::distance(clips.begin(), pStart);
|
result.index2 = std::distance(clips.begin(), pStart);
|
||||||
result.clipStart2 = true;
|
result.clipStart2 = true;
|
||||||
}
|
}
|
||||||
|
else if ((*pStart)->GetStartTime() < (*pEnd)->GetEndTime()) {
|
||||||
|
result.nFound = 1;
|
||||||
|
result.time = (*pStart)->GetStartTime();
|
||||||
|
result.index1 = std::distance(clips.begin(), pStart);
|
||||||
|
result.clipStart1 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.nFound = 1;
|
||||||
|
result.time = (*pEnd)->GetEndTime();
|
||||||
|
result.index1 = std::distance(clips.begin(), pEnd);
|
||||||
|
result.clipStart1 = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (pEnd != clips.end()) {
|
else if (pEnd != clips.end()) {
|
||||||
result.nFound = 1;
|
result.nFound = 1;
|
||||||
@ -6570,34 +6671,37 @@ AudacityProject::FoundClipBoundary AudacityProject::FindPrevClipBoundary(const W
|
|||||||
{
|
{
|
||||||
AudacityProject::FoundClipBoundary result{};
|
AudacityProject::FoundClipBoundary result{};
|
||||||
result.waveTrack = wt;
|
result.waveTrack = wt;
|
||||||
|
|
||||||
const auto clips = wt->SortedClipArray();
|
const auto clips = wt->SortedClipArray();
|
||||||
|
double timeStart = AdjustForFindingStartTimes(clips, time);
|
||||||
|
double timeEnd = AdjustForFindingEndTimes(clips, time);
|
||||||
|
|
||||||
auto pStart = std::find_if(clips.rbegin(), clips.rend(), [&] (const WaveClip* const& clip) {
|
auto pStart = std::find_if(clips.rbegin(), clips.rend(), [&] (const WaveClip* const& clip) {
|
||||||
return clip->GetStartTime() < time; });
|
return clip->GetStartTime() < timeStart; });
|
||||||
auto pEnd = std::find_if(clips.rbegin(), clips.rend(), [&] (const WaveClip* const& clip) {
|
auto pEnd = std::find_if(clips.rbegin(), clips.rend(), [&] (const WaveClip* const& clip) {
|
||||||
return clip->GetEndTime() < time; });
|
return clip->GetEndTime() < timeEnd; });
|
||||||
|
|
||||||
if (pStart != clips.rend() && pEnd != clips.rend()) {
|
if (pStart != clips.rend() && pEnd != clips.rend()) {
|
||||||
if ((*pStart)->GetStartTime() > (*pEnd)->GetEndTime()) {
|
if ((*pEnd)->SharesBoundaryWithNextClip(*pStart)) {
|
||||||
result.nFound = 1;
|
// boundary between two clips which are immediately next to each other.
|
||||||
result.time = (*pStart)->GetStartTime();
|
result.nFound = 2;
|
||||||
result.index1 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pStart);
|
|
||||||
result.clipStart1 = true;
|
|
||||||
}
|
|
||||||
else if ((*pStart)->GetStartTime() < (*pEnd)->GetEndTime()) {
|
|
||||||
result.nFound = 1;
|
|
||||||
result.time = (*pEnd)->GetEndTime();
|
|
||||||
result.index1 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pEnd);
|
|
||||||
result.clipStart1 = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.nFound = 2; // both the start of one clip and the end of the previous clip
|
|
||||||
result.time = (*pStart)->GetStartTime();
|
result.time = (*pStart)->GetStartTime();
|
||||||
result.index1 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pStart);
|
result.index1 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pStart);
|
||||||
result.clipStart1 = true;
|
result.clipStart1 = true;
|
||||||
result.index2 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pEnd);
|
result.index2 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pEnd);
|
||||||
result.clipStart2 = false;
|
result.clipStart2 = false;
|
||||||
}
|
}
|
||||||
|
else if ((*pStart)->GetStartTime() > (*pEnd)->GetEndTime()) {
|
||||||
|
result.nFound = 1;
|
||||||
|
result.time = (*pStart)->GetStartTime();
|
||||||
|
result.index1 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pStart);
|
||||||
|
result.clipStart1 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.nFound = 1;
|
||||||
|
result.time = (*pEnd)->GetEndTime();
|
||||||
|
result.index1 = static_cast<int>(clips.size()) - 1 - std::distance(clips.rbegin(), pEnd);
|
||||||
|
result.clipStart1 = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (pStart != clips.rend()) {
|
else if (pStart != clips.rend()) {
|
||||||
result.nFound = 1;
|
result.nFound = 1;
|
||||||
@ -6609,6 +6713,42 @@ AudacityProject::FoundClipBoundary AudacityProject::FindPrevClipBoundary(const W
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When two clips are immediately next to each other, the GetEndTime() of the first clip and the
|
||||||
|
// GetStartTime() of the second clip may not be exactly equal due to rounding errors. When searching
|
||||||
|
// for the next/prev start time from a given time, the following function adjusts that given time if
|
||||||
|
// necessary to take this into account. If the given time is the end time of the first of two clips which
|
||||||
|
// are next to each other, then the given time is changed to the start time of the second clip.
|
||||||
|
// This ensures that the correct next/prev start time is found.
|
||||||
|
double AudacityProject::AdjustForFindingStartTimes(const std::vector<const WaveClip*> & clips, double time)
|
||||||
|
{
|
||||||
|
auto q = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
||||||
|
return clip->GetEndTime() == time; });
|
||||||
|
if (q != clips.end() && q + 1 != clips.end() &&
|
||||||
|
(*q)->SharesBoundaryWithNextClip(*(q+1))) {
|
||||||
|
time = (*(q+1))->GetStartTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When two clips are immediately next to each other, the GetEndTime() of the first clip and the
|
||||||
|
// GetStartTime() of the second clip may not be exactly equal due to rounding errors. When searching
|
||||||
|
// for the next/prev end time from a given time, the following function adjusts that given time if
|
||||||
|
// necessary to take this into account. If the given time is the start time of the second of two clips which
|
||||||
|
// are next to each other, then the given time is changed to the end time of the first clip.
|
||||||
|
// This ensures that the correct next/prev end time is found.
|
||||||
|
double AudacityProject::AdjustForFindingEndTimes(const std::vector<const WaveClip*>& clips, double time)
|
||||||
|
{
|
||||||
|
auto q = std::find_if(clips.begin(), clips.end(), [&] (const WaveClip* const& clip) {
|
||||||
|
return clip->GetStartTime() == time; });
|
||||||
|
if (q != clips.end() && q != clips.begin() &&
|
||||||
|
(*(q - 1))->SharesBoundaryWithNextClip(*q)) {
|
||||||
|
time = (*(q-1))->GetEndTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
int AudacityProject::FindClipBoundaries(double time, bool next, std::vector<FoundClipBoundary>& finalResults)
|
int AudacityProject::FindClipBoundaries(double time, bool next, std::vector<FoundClipBoundary>& finalResults)
|
||||||
{
|
{
|
||||||
const TrackList* tracks = GetTracks();
|
const TrackList* tracks = GetTracks();
|
||||||
@ -6664,7 +6804,8 @@ void AudacityProject::OnCursorPrevClipBoundary()
|
|||||||
void AudacityProject::OnCursorClipBoundary(bool next)
|
void AudacityProject::OnCursorClipBoundary(bool next)
|
||||||
{
|
{
|
||||||
std::vector<FoundClipBoundary> results;
|
std::vector<FoundClipBoundary> results;
|
||||||
int nTracksSearched = FindClipBoundaries(mViewInfo.selectedRegion.t0(), next, results);
|
int nTracksSearched = FindClipBoundaries(next ? mViewInfo.selectedRegion.t1() :
|
||||||
|
mViewInfo.selectedRegion.t0(), next, results);
|
||||||
|
|
||||||
if (results.size() > 0) {
|
if (results.size() > 0) {
|
||||||
// note that if there is more than one result, each has the same time value.
|
// note that if there is more than one result, each has the same time value.
|
||||||
@ -6697,10 +6838,11 @@ wxString AudacityProject::ClipBoundaryMessage(int nTracksSearched, const std::ve
|
|||||||
message += temp;
|
message += temp;
|
||||||
}
|
}
|
||||||
message += (result.clipStart1 ? _("start") : _("end")) + wxT(" ");
|
message += (result.clipStart1 ? _("start") : _("end")) + wxT(" ");
|
||||||
if (result.waveTrack->GetNumClips() > 1 ) {
|
|
||||||
temp.Printf(wxT("%d %s %d "), result.index1 + 1, _("of"), result.waveTrack->GetNumClips());
|
temp.Printf(wxT("%d %s %d %s "), result.index1 + 1, _("of"), result.waveTrack->GetNumClips(),
|
||||||
|
result.waveTrack->GetNumClips() == 1 ? _("clip") : _("clips"));
|
||||||
message += temp;
|
message += temp;
|
||||||
}
|
|
||||||
if (result.nFound == 2) {
|
if (result.nFound == 2) {
|
||||||
temp.Printf(wxT("%s %s %d "), _("and"), result.clipStart2 ? _("start") : _("end"),
|
temp.Printf(wxT("%s %s %d "), _("and"), result.clipStart2 ? _("start") : _("end"),
|
||||||
result.index2 + 1);
|
result.index2 + 1);
|
||||||
@ -6892,7 +7034,7 @@ void AudacityProject::OnAlignNoSync(int index)
|
|||||||
void AudacityProject::OnAlign(int index)
|
void AudacityProject::OnAlign(int index)
|
||||||
{
|
{
|
||||||
bool bMoveWith;
|
bool bMoveWith;
|
||||||
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, true);
|
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, false);
|
||||||
HandleAlign(index, bMoveWith);
|
HandleAlign(index, bMoveWith);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -7098,14 +7240,6 @@ void AudacityProject::OnScoreAlign()
|
|||||||
// Make a copy of the note track in case alignment is canceled or fails
|
// Make a copy of the note track in case alignment is canceled or fails
|
||||||
auto holder = nt->Duplicate();
|
auto holder = nt->Duplicate();
|
||||||
auto alignedNoteTrack = static_cast<NoteTrack*>(holder.get());
|
auto alignedNoteTrack = static_cast<NoteTrack*>(holder.get());
|
||||||
// Duplicate() on note tracks serializes seq to a buffer, but we need
|
|
||||||
// the seq, so Duplicate again and discard the track with buffer. The
|
|
||||||
// test is here in case Duplicate() is changed in the future.
|
|
||||||
if (alignedNoteTrack->GetSequence() == NULL) {
|
|
||||||
holder = alignedNoteTrack->Duplicate();
|
|
||||||
alignedNoteTrack = static_cast<NoteTrack*>(holder.get());
|
|
||||||
wxASSERT(alignedNoteTrack->GetSequence());
|
|
||||||
}
|
|
||||||
// Remove offset from NoteTrack because audio is
|
// Remove offset from NoteTrack because audio is
|
||||||
// mixed starting at zero and incorporating clip offsets.
|
// mixed starting at zero and incorporating clip offsets.
|
||||||
if (alignedNoteTrack->GetOffset() < 0) {
|
if (alignedNoteTrack->GetOffset() < 0) {
|
||||||
@ -7145,7 +7279,7 @@ void AudacityProject::OnScoreAlign()
|
|||||||
#ifndef SKIP_ACTUAL_SCORE_ALIGNMENT
|
#ifndef SKIP_ACTUAL_SCORE_ALIGNMENT
|
||||||
result = scorealign((void *) &mix, &mixer_process,
|
result = scorealign((void *) &mix, &mixer_process,
|
||||||
2 /* channels */, 44100.0 /* srate */, endTime,
|
2 /* channels */, 44100.0 /* srate */, endTime,
|
||||||
alignedNoteTrack->GetSequence(), &progress, params);
|
&alignedNoteTrack->GetSeq(), &progress, params);
|
||||||
#else
|
#else
|
||||||
result = SA_SUCCESS;
|
result = SA_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
@ -7398,7 +7532,7 @@ int AudacityProject::DoAddLabel(const SelectedRegion ®ion, bool preserveFocus
|
|||||||
void AudacityProject::OnMoveSelectionWithTracks()
|
void AudacityProject::OnMoveSelectionWithTracks()
|
||||||
{
|
{
|
||||||
bool bMoveWith;
|
bool bMoveWith;
|
||||||
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, true);
|
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, false);
|
||||||
gPrefs->Write(wxT("/GUI/MoveSelectionWithTracks"), !bMoveWith);
|
gPrefs->Write(wxT("/GUI/MoveSelectionWithTracks"), !bMoveWith);
|
||||||
gPrefs->Flush();
|
gPrefs->Flush();
|
||||||
|
|
||||||
@ -7878,6 +8012,7 @@ void AudacityProject::OnResample()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetUndoManager()->StopConsolidating();
|
||||||
RedrawProject();
|
RedrawProject();
|
||||||
|
|
||||||
// Need to reset
|
// Need to reset
|
||||||
|
17
src/Menus.h
17
src/Menus.h
@ -160,8 +160,10 @@ void OnSelExtendRight(const wxEvent * evt);
|
|||||||
void OnSelContractLeft(const wxEvent * evt);
|
void OnSelContractLeft(const wxEvent * evt);
|
||||||
void OnSelContractRight(const wxEvent * evt);
|
void OnSelContractRight(const wxEvent * evt);
|
||||||
|
|
||||||
void OnClipLeft();
|
public:
|
||||||
void OnClipRight();
|
void DoClipLeftOrRight(bool right, bool keyUp );
|
||||||
|
void OnClipLeft(const wxEvent* evt);
|
||||||
|
void OnClipRight(const wxEvent* evt);
|
||||||
|
|
||||||
void OnCursorShortJumpLeft();
|
void OnCursorShortJumpLeft();
|
||||||
void OnCursorShortJumpRight();
|
void OnCursorShortJumpRight();
|
||||||
@ -275,8 +277,16 @@ void OnSplitLabels();
|
|||||||
void OnJoinLabels();
|
void OnJoinLabels();
|
||||||
void OnDisjoinLabels();
|
void OnDisjoinLabels();
|
||||||
|
|
||||||
|
void OnSelectTimeAndTracks(bool bAllTime, bool bAllTracks);
|
||||||
|
void OnSelectAllTime();
|
||||||
|
void OnSelectAllTracks();
|
||||||
void OnSelectAll();
|
void OnSelectAll();
|
||||||
|
void OnSelectSomething();
|
||||||
void OnSelectNone();
|
void OnSelectNone();
|
||||||
|
private:
|
||||||
|
int CountSelectedWaveTracks();
|
||||||
|
int CountSelectedTracks();
|
||||||
|
public:
|
||||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||||
void OnToggleSpectralSelection();
|
void OnToggleSpectralSelection();
|
||||||
void DoNextPeakFrequency(bool up);
|
void DoNextPeakFrequency(bool up);
|
||||||
@ -303,7 +313,6 @@ void OnSelectNextClip();
|
|||||||
void OnSelectClip(bool next);
|
void OnSelectClip(bool next);
|
||||||
void OnSelectCursorStoredCursor();
|
void OnSelectCursorStoredCursor();
|
||||||
void OnSelectSyncLockSel();
|
void OnSelectSyncLockSel();
|
||||||
void OnSelectAllTracks();
|
|
||||||
|
|
||||||
// View Menu
|
// View Menu
|
||||||
|
|
||||||
@ -411,6 +420,8 @@ typedef struct FoundClipBoundary {
|
|||||||
} FoundClipBoundary;
|
} FoundClipBoundary;
|
||||||
FoundClipBoundary FindNextClipBoundary(const WaveTrack* wt, double time);
|
FoundClipBoundary FindNextClipBoundary(const WaveTrack* wt, double time);
|
||||||
FoundClipBoundary FindPrevClipBoundary(const WaveTrack* wt, double time);
|
FoundClipBoundary FindPrevClipBoundary(const WaveTrack* wt, double time);
|
||||||
|
double AdjustForFindingStartTimes(const std::vector<const WaveClip*>& clips, double time);
|
||||||
|
double AdjustForFindingEndTimes(const std::vector<const WaveClip*>& clips, double time);
|
||||||
int FindClipBoundaries(double time, bool next, std::vector<FoundClipBoundary>& results);
|
int FindClipBoundaries(double time, bool next, std::vector<FoundClipBoundary>& results);
|
||||||
void OnCursorNextClipBoundary();
|
void OnCursorNextClipBoundary();
|
||||||
void OnCursorPrevClipBoundary();
|
void OnCursorPrevClipBoundary();
|
||||||
|
@ -776,11 +776,9 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
|
|||||||
// Have to refresh all tracks.
|
// Have to refresh all tracks.
|
||||||
mMixerBoard->UpdateMute();
|
mMixerBoard->UpdateMute();
|
||||||
mMixerBoard->UpdateSolo();
|
mMixerBoard->UpdateSolo();
|
||||||
mProject->RedrawProject();
|
|
||||||
}
|
}
|
||||||
else
|
// Bug 509: Must repaint all, as many tracks can change with one Solo change.
|
||||||
// Update only the changed track.
|
mProject->RedrawProject();
|
||||||
mProject->RefreshTPTrack(mTrack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1512,7 +1510,8 @@ MixerBoardFrame::MixerBoardFrame(AudacityProject* parent)
|
|||||||
#endif
|
#endif
|
||||||
SetIcon(ic);
|
SetIcon(ic);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Center();
|
||||||
}
|
}
|
||||||
|
|
||||||
MixerBoardFrame::~MixerBoardFrame()
|
MixerBoardFrame::~MixerBoardFrame()
|
||||||
|
@ -95,7 +95,9 @@ public:
|
|||||||
// PluginManager use
|
// PluginManager use
|
||||||
bool DiscoverProviders();
|
bool DiscoverProviders();
|
||||||
|
|
||||||
|
// Seems we don't currently use FindAllPlugins
|
||||||
void FindAllPlugins(PluginIDList & providers, wxArrayString & paths);
|
void FindAllPlugins(PluginIDList & providers, wxArrayString & paths);
|
||||||
|
|
||||||
wxArrayString FindPluginsForProvider(const PluginID & provider, const wxString & path);
|
wxArrayString FindPluginsForProvider(const PluginID & provider, const wxString & path);
|
||||||
bool RegisterPlugin(const PluginID & provider, const wxString & path);
|
bool RegisterPlugin(const PluginID & provider, const wxString & path);
|
||||||
|
|
||||||
|
@ -127,15 +127,35 @@ NoteTrack::~NoteTrack()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Alg_seq &NoteTrack::GetSeq() const
|
||||||
|
{
|
||||||
|
if (!mSeq) {
|
||||||
|
if (!mSerializationBuffer)
|
||||||
|
mSeq = std::make_unique<Alg_seq>();
|
||||||
|
else {
|
||||||
|
std::unique_ptr<Alg_track> alg_track
|
||||||
|
{ Alg_seq::unserialize
|
||||||
|
( mSerializationBuffer.get(), mSerializationLength ) };
|
||||||
|
wxASSERT(alg_track->get_type() == 's');
|
||||||
|
mSeq.reset( static_cast<Alg_seq*>(alg_track.release()) );
|
||||||
|
|
||||||
|
// Preserve the invariant that at most one of the representations is
|
||||||
|
// valid
|
||||||
|
mSerializationBuffer.reset();
|
||||||
|
mSerializationLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wxASSERT(mSeq);
|
||||||
|
return *mSeq;
|
||||||
|
}
|
||||||
|
|
||||||
Track::Holder NoteTrack::Duplicate() const
|
Track::Holder NoteTrack::Duplicate() const
|
||||||
{
|
{
|
||||||
auto duplicate = std::make_unique<NoteTrack>(mDirManager);
|
auto duplicate = std::make_unique<NoteTrack>(mDirManager);
|
||||||
duplicate->Init(*this);
|
duplicate->Init(*this);
|
||||||
// Duplicate on NoteTrack moves data from mSeq to mSerializationBuffer
|
// The duplicate begins life in serialized state. Often the duplicate is
|
||||||
// and from mSerializationBuffer to mSeq on alternate calls. Duplicate
|
// pushed on the Undo stack. Then we want to un-serialize it (or a further
|
||||||
// to the undo stack and Duplicate back to the project should result
|
// copy) only on demand after an Undo.
|
||||||
// in serialized blobs on the undo stack and traversable data in the
|
|
||||||
// project object.
|
|
||||||
if (mSeq) {
|
if (mSeq) {
|
||||||
SonifyBeginSerialize();
|
SonifyBeginSerialize();
|
||||||
wxASSERT(!mSerializationBuffer);
|
wxASSERT(!mSerializationBuffer);
|
||||||
@ -145,15 +165,19 @@ Track::Holder NoteTrack::Duplicate() const
|
|||||||
&duplicate->mSerializationLength);
|
&duplicate->mSerializationLength);
|
||||||
duplicate->mSerializationBuffer.reset( (char*)buffer );
|
duplicate->mSerializationBuffer.reset( (char*)buffer );
|
||||||
SonifyEndSerialize();
|
SonifyEndSerialize();
|
||||||
} else if (mSerializationBuffer) {
|
}
|
||||||
SonifyBeginUnserialize();
|
else if (mSerializationBuffer) {
|
||||||
|
// Copy already serialized data.
|
||||||
wxASSERT(!mSeq);
|
wxASSERT(!mSeq);
|
||||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(mSerializationBuffer.get(),
|
duplicate->mSerializationLength = this->mSerializationLength;
|
||||||
mSerializationLength) };
|
duplicate->mSerializationBuffer.reset
|
||||||
wxASSERT(alg_track->get_type() == 's');
|
( new char[ this->mSerializationLength ] );
|
||||||
duplicate->mSeq.reset(static_cast<Alg_seq*>(alg_track.release()));
|
memcpy( duplicate->mSerializationBuffer.get(),
|
||||||
SonifyEndUnserialize();
|
this->mSerializationBuffer.get(), this->mSerializationLength );
|
||||||
} else wxFAIL_MSG("neither mSeq nor mSerializationBuffer were present"); // bug if neither mSeq nor mSerializationBuffer
|
}
|
||||||
|
else {
|
||||||
|
// We are duplicating a default-constructed NoteTrack, and that's okay
|
||||||
|
}
|
||||||
// copy some other fields here
|
// copy some other fields here
|
||||||
duplicate->SetBottomNote(mBottomNote);
|
duplicate->SetBottomNote(mBottomNote);
|
||||||
duplicate->SetPitchHeight(mPitchHeight);
|
duplicate->SetPitchHeight(mPitchHeight);
|
||||||
@ -180,7 +204,7 @@ double NoteTrack::GetStartTime() const
|
|||||||
|
|
||||||
double NoteTrack::GetEndTime() const
|
double NoteTrack::GetEndTime() const
|
||||||
{
|
{
|
||||||
return GetStartTime() + (mSeq ? mSeq->get_real_dur() : 0.0);
|
return GetStartTime() + GetSeq().get_real_dur();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -188,25 +212,13 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1,
|
|||||||
const TimeWarper &warper,
|
const TimeWarper &warper,
|
||||||
double semitones)
|
double semitones)
|
||||||
{
|
{
|
||||||
// Since this is a duplicate and duplicates convert mSeq to
|
|
||||||
// a text string for saving as XML, we probably have to
|
|
||||||
// duplicate again to get back an mSeq
|
|
||||||
double offset = this->GetOffset(); // track is shifted this amount
|
double offset = this->GetOffset(); // track is shifted this amount
|
||||||
if (!mSeq) { // replace saveme with an (unserialized) duplicate
|
auto &seq = GetSeq();
|
||||||
Track::Holder unt{ Duplicate() };
|
seq.convert_to_seconds(); // make sure time units are right
|
||||||
const auto nt = static_cast<NoteTrack*>(unt.get());
|
|
||||||
wxASSERT(!mSeq && nt->mSeq && !nt->mSerializationBuffer);
|
|
||||||
// swap mSeq and Buffer between this and nt
|
|
||||||
nt->mSerializationBuffer = std::move(mSerializationBuffer);
|
|
||||||
nt->mSerializationLength = mSerializationLength;
|
|
||||||
mSerializationLength = 0;
|
|
||||||
mSeq = std::move(nt->mSeq);
|
|
||||||
}
|
|
||||||
mSeq->convert_to_seconds(); // make sure time units are right
|
|
||||||
t1 -= offset; // adjust time range to compensate for track offset
|
t1 -= offset; // adjust time range to compensate for track offset
|
||||||
t0 -= offset;
|
t0 -= offset;
|
||||||
if (t1 > mSeq->get_dur()) { // make sure t0, t1 are within sequence
|
if (t1 > seq.get_dur()) { // make sure t0, t1 are within sequence
|
||||||
t1 = mSeq->get_dur();
|
t1 = seq.get_dur();
|
||||||
if (t0 >= t1) return;
|
if (t0 >= t1) return;
|
||||||
}
|
}
|
||||||
Alg_iterator iter(mSeq.get(), false);
|
Alg_iterator iter(mSeq.get(), false);
|
||||||
@ -219,8 +231,8 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1,
|
|||||||
}
|
}
|
||||||
iter.end();
|
iter.end();
|
||||||
// now, use warper to warp the tempo map
|
// now, use warper to warp the tempo map
|
||||||
mSeq->convert_to_beats(); // beats remain the same
|
seq.convert_to_beats(); // beats remain the same
|
||||||
Alg_time_map_ptr map = mSeq->get_time_map();
|
Alg_time_map_ptr map = seq.get_time_map();
|
||||||
map->insert_beat(t0, map->time_to_beat(t0));
|
map->insert_beat(t0, map->time_to_beat(t0));
|
||||||
map->insert_beat(t1, map->time_to_beat(t1));
|
map->insert_beat(t1, map->time_to_beat(t1));
|
||||||
int i, len = map->length();
|
int i, len = map->length();
|
||||||
@ -229,7 +241,7 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1,
|
|||||||
beat.time = warper.Warp(beat.time + offset) - offset;
|
beat.time = warper.Warp(beat.time + offset) - offset;
|
||||||
}
|
}
|
||||||
// about to redisplay, so might as well convert back to time now
|
// about to redisplay, so might as well convert back to time now
|
||||||
mSeq->convert_to_seconds();
|
seq.convert_to_seconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws the midi channel toggle buttons within the given rect.
|
// Draws the midi channel toggle buttons within the given rect.
|
||||||
@ -348,11 +360,6 @@ void NoteTrack::SetSequence(std::unique_ptr<Alg_seq> &&seq)
|
|||||||
mSeq = std::move(seq);
|
mSeq = std::move(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
Alg_seq* NoteTrack::GetSequence()
|
|
||||||
{
|
|
||||||
return mSeq.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NoteTrack::PrintSequence()
|
void NoteTrack::PrintSequence()
|
||||||
{
|
{
|
||||||
FILE *debugOutput;
|
FILE *debugOutput;
|
||||||
@ -360,6 +367,8 @@ void NoteTrack::PrintSequence()
|
|||||||
debugOutput = fopen("debugOutput.txt", "wt");
|
debugOutput = fopen("debugOutput.txt", "wt");
|
||||||
fprintf(debugOutput, "Importing MIDI...\n");
|
fprintf(debugOutput, "Importing MIDI...\n");
|
||||||
|
|
||||||
|
// This is called for debugging purposes. Do not compute mSeq on demand
|
||||||
|
// with GetSeq()
|
||||||
if (mSeq) {
|
if (mSeq) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@ -416,15 +425,23 @@ Track::Holder NoteTrack::Cut(double t0, double t1)
|
|||||||
THROW_INCONSISTENCY_EXCEPTION;
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
|
||||||
double len = t1-t0;
|
double len = t1-t0;
|
||||||
|
//auto delta = -(
|
||||||
|
//( std::min( t1, GetEndTime() ) ) - ( std::max( t0, GetStartTime() ) )
|
||||||
|
//);
|
||||||
|
|
||||||
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
|
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
|
||||||
|
|
||||||
newTrack->Init(*this);
|
newTrack->Init(*this);
|
||||||
|
|
||||||
mSeq->convert_to_seconds();
|
auto &seq = GetSeq();
|
||||||
newTrack->mSeq.reset(mSeq->cut(t0 - GetOffset(), len, false));
|
seq.convert_to_seconds();
|
||||||
|
newTrack->mSeq.reset(seq.cut(t0 - GetOffset(), len, false));
|
||||||
newTrack->SetOffset(GetOffset());
|
newTrack->SetOffset(GetOffset());
|
||||||
|
|
||||||
|
// Not needed
|
||||||
|
// Alg_seq::cut seems to handle this
|
||||||
|
//AddToDuration( delta );
|
||||||
|
|
||||||
// What should be done with the rest of newTrack's members?
|
// What should be done with the rest of newTrack's members?
|
||||||
//(mBottomNote, mDirManager, mLastMidiPosition,
|
//(mBottomNote, mDirManager, mLastMidiPosition,
|
||||||
// mSerializationBuffer, mSerializationLength, mVisibleChannels)
|
// mSerializationBuffer, mSerializationLength, mVisibleChannels)
|
||||||
@ -444,8 +461,9 @@ Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
|
|||||||
|
|
||||||
newTrack->Init(*this);
|
newTrack->Init(*this);
|
||||||
|
|
||||||
mSeq->convert_to_seconds();
|
auto &seq = GetSeq();
|
||||||
newTrack->mSeq.reset(mSeq->copy(t0 - GetOffset(), len, false));
|
seq.convert_to_seconds();
|
||||||
|
newTrack->mSeq.reset(seq.copy(t0 - GetOffset(), len, false));
|
||||||
newTrack->SetOffset(GetOffset());
|
newTrack->SetOffset(GetOffset());
|
||||||
|
|
||||||
// What should be done with the rest of newTrack's members?
|
// What should be done with the rest of newTrack's members?
|
||||||
@ -460,13 +478,23 @@ bool NoteTrack::Trim(double t0, double t1)
|
|||||||
{
|
{
|
||||||
if (t1 < t0)
|
if (t1 < t0)
|
||||||
return false;
|
return false;
|
||||||
mSeq->convert_to_seconds();
|
auto &seq = GetSeq();
|
||||||
|
//auto delta = -(
|
||||||
|
//( GetEndTime() - std::min( GetEndTime(), t1 ) ) +
|
||||||
|
//( std::max(t0, GetStartTime()) - GetStartTime() )
|
||||||
|
//);
|
||||||
|
seq.convert_to_seconds();
|
||||||
// DELETE way beyond duration just in case something is out there:
|
// DELETE way beyond duration just in case something is out there:
|
||||||
mSeq->clear(t1 - GetOffset(), mSeq->get_dur() + 10000.0, false);
|
seq.clear(t1 - GetOffset(), seq.get_dur() + 10000.0, false);
|
||||||
// Now that stuff beyond selection is cleared, clear before selection:
|
// Now that stuff beyond selection is cleared, clear before selection:
|
||||||
mSeq->clear(0.0, t0 - GetOffset(), false);
|
seq.clear(0.0, t0 - GetOffset(), false);
|
||||||
// want starting time to be t0
|
// want starting time to be t0
|
||||||
SetOffset(t0);
|
SetOffset(t0);
|
||||||
|
|
||||||
|
// Not needed
|
||||||
|
// Alg_seq::clear seems to handle this
|
||||||
|
//AddToDuration( delta );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,8 +505,15 @@ void NoteTrack::Clear(double t0, double t1)
|
|||||||
|
|
||||||
double len = t1-t0;
|
double len = t1-t0;
|
||||||
|
|
||||||
if (mSeq)
|
auto &seq = GetSeq();
|
||||||
mSeq->clear(t0 - GetOffset(), len, false);
|
//auto delta = -(
|
||||||
|
//( std::min( t1, GetEndTime() ) ) - ( std::max( t0, GetStartTime() ) )
|
||||||
|
//);
|
||||||
|
seq.clear(t0 - GetOffset(), len, false);
|
||||||
|
|
||||||
|
// Not needed
|
||||||
|
// Alg_seq::clear seems to handle this
|
||||||
|
// AddToDuration( delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteTrack::Paste(double t, const Track *src)
|
void NoteTrack::Paste(double t, const Track *src)
|
||||||
@ -497,19 +532,27 @@ void NoteTrack::Paste(double t, const Track *src)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
NoteTrack* other = (NoteTrack*)src;
|
NoteTrack* other = (NoteTrack*)src;
|
||||||
if (other->mSeq == NULL)
|
|
||||||
// THROW_INCONSISTENCY_EXCEPTION; // ?
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!mSeq)
|
double delta = 0.0;
|
||||||
mSeq = std::make_unique<Alg_seq>();
|
auto &seq = GetSeq();
|
||||||
|
auto offset = other->GetOffset();
|
||||||
if (other->GetOffset() > 0) {
|
if ( offset > 0 ) {
|
||||||
mSeq->convert_to_seconds();
|
seq.convert_to_seconds();
|
||||||
mSeq->insert_silence(t - GetOffset(), other->GetOffset());
|
seq.insert_silence( t - GetOffset(), offset );
|
||||||
t += other->GetOffset();
|
t += offset;
|
||||||
|
// Is this needed or does Alg_seq::insert_silence take care of it?
|
||||||
|
//delta += offset;
|
||||||
}
|
}
|
||||||
mSeq->paste(t - GetOffset(), other->mSeq.get());
|
|
||||||
|
// This seems to be needed:
|
||||||
|
delta += std::max( 0.0, t - GetEndTime() );
|
||||||
|
|
||||||
|
// This, not:
|
||||||
|
//delta += other->GetSeq().get_real_dur();
|
||||||
|
|
||||||
|
seq.paste(t - GetOffset(), &other->GetSeq());
|
||||||
|
|
||||||
|
AddToDuration( delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteTrack::Silence(double t0, double t1)
|
void NoteTrack::Silence(double t0, double t1)
|
||||||
@ -519,20 +562,25 @@ void NoteTrack::Silence(double t0, double t1)
|
|||||||
|
|
||||||
auto len = t1 - t0;
|
auto len = t1 - t0;
|
||||||
|
|
||||||
mSeq->convert_to_seconds();
|
auto &seq = GetSeq();
|
||||||
|
seq.convert_to_seconds();
|
||||||
// XXX: do we want to set the all param?
|
// XXX: do we want to set the all param?
|
||||||
// If it's set, then it seems like notes are silenced if they start or end in the range,
|
// If it's set, then it seems like notes are silenced if they start or end in the range,
|
||||||
// otherwise only if they start in the range. --Poke
|
// otherwise only if they start in the range. --Poke
|
||||||
mSeq->silence(t0 - GetOffset(), len, false);
|
seq.silence(t0 - GetOffset(), len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteTrack::InsertSilence(double t, double len)
|
void NoteTrack::InsertSilence(double t, double len)
|
||||||
{
|
{
|
||||||
if (len <= 0)
|
if (len < 0)
|
||||||
THROW_INCONSISTENCY_EXCEPTION;
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
|
||||||
mSeq->convert_to_seconds();
|
auto &seq = GetSeq();
|
||||||
mSeq->insert_silence(t - GetOffset(), len);
|
seq.convert_to_seconds();
|
||||||
|
seq.insert_silence(t - GetOffset(), len);
|
||||||
|
|
||||||
|
// is this needed?
|
||||||
|
// AddToDuration( len );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this function to manipulate the underlying sequence data. This is
|
// Call this function to manipulate the underlying sequence data. This is
|
||||||
@ -540,51 +588,61 @@ void NoteTrack::InsertSilence(double t, double len)
|
|||||||
bool NoteTrack::Shift(double t) // t is always seconds
|
bool NoteTrack::Shift(double t) // t is always seconds
|
||||||
{
|
{
|
||||||
if (t > 0) {
|
if (t > 0) {
|
||||||
|
auto &seq = GetSeq();
|
||||||
// insert an even number of measures
|
// insert an even number of measures
|
||||||
mSeq->convert_to_beats();
|
seq.convert_to_beats();
|
||||||
// get initial tempo
|
// get initial tempo
|
||||||
double tempo = mSeq->get_tempo(0.0);
|
double tempo = seq.get_tempo(0.0);
|
||||||
double beats_per_measure = mSeq->get_bar_len(0.0);
|
double beats_per_measure = seq.get_bar_len(0.0);
|
||||||
int m = ROUND(t * tempo / beats_per_measure);
|
int m = ROUND(t * tempo / beats_per_measure);
|
||||||
// need at least 1 measure, so if we rounded down to zero, fix it
|
// need at least 1 measure, so if we rounded down to zero, fix it
|
||||||
if (m == 0) m = 1;
|
if (m == 0) m = 1;
|
||||||
// compute NEW tempo so that m measures at NEW tempo take t seconds
|
// compute NEW tempo so that m measures at NEW tempo take t seconds
|
||||||
tempo = beats_per_measure * m / t; // in beats per second
|
tempo = beats_per_measure * m / t; // in beats per second
|
||||||
mSeq->insert_silence(0.0, beats_per_measure * m);
|
seq.insert_silence(0.0, beats_per_measure * m);
|
||||||
mSeq->set_tempo(tempo * 60.0 /* bpm */, 0.0, beats_per_measure * m);
|
seq.set_tempo(tempo * 60.0 /* bpm */, 0.0, beats_per_measure * m);
|
||||||
mSeq->write("afterShift.gro");
|
seq.write("afterShift.gro");
|
||||||
} else if (t < 0) {
|
} else if (t < 0) {
|
||||||
mSeq->convert_to_seconds();
|
auto &seq = GetSeq();
|
||||||
mSeq->clear(0, t, true);
|
seq.convert_to_seconds();
|
||||||
|
seq.clear(0, t, true);
|
||||||
} else { // offset is zero, no modifications
|
} else { // offset is zero, no modifications
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double NoteTrack::NearestBeatTime(double time, double *beat) const
|
QuantizedTimeAndBeat NoteTrack::NearestBeatTime( double time ) const
|
||||||
{
|
{
|
||||||
wxASSERT(mSeq);
|
|
||||||
// Alg_seq knows nothing about offset, so remove offset time
|
// Alg_seq knows nothing about offset, so remove offset time
|
||||||
double seq_time = time - GetOffset();
|
double seq_time = time - GetOffset();
|
||||||
seq_time = mSeq->nearest_beat_time(seq_time, beat);
|
double beat;
|
||||||
|
auto &seq = GetSeq();
|
||||||
|
seq_time = seq.nearest_beat_time(seq_time, &beat);
|
||||||
// add the offset back in to get "actual" audacity track time
|
// add the offset back in to get "actual" audacity track time
|
||||||
return seq_time + GetOffset();
|
return { seq_time + GetOffset(), beat };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoteTrack::StretchRegion(double t0, double t1, double dur)
|
void NoteTrack::AddToDuration( double delta )
|
||||||
{
|
{
|
||||||
wxASSERT(mSeq);
|
auto &seq = GetSeq();
|
||||||
// Alg_seq::stretch_region uses beats, so we translate time
|
#if 0
|
||||||
// to beats first:
|
// PRL: Would this be better ?
|
||||||
t0 -= GetOffset();
|
seq.set_real_dur( seq.get_real_dur() + delta );
|
||||||
t1 -= GetOffset();
|
#else
|
||||||
double b0 = mSeq->get_time_map()->time_to_beat(t0);
|
seq.convert_to_seconds();
|
||||||
double b1 = mSeq->get_time_map()->time_to_beat(t1);
|
seq.set_dur( seq.get_dur() + delta );
|
||||||
bool result = mSeq->stretch_region(b0, b1, dur);
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NoteTrack::StretchRegion
|
||||||
|
( QuantizedTimeAndBeat t0, QuantizedTimeAndBeat t1, double newDur )
|
||||||
|
{
|
||||||
|
auto &seq = GetSeq();
|
||||||
|
bool result = seq.stretch_region( t0.second, t1.second, newDur );
|
||||||
if (result) {
|
if (result) {
|
||||||
mSeq->convert_to_seconds();
|
const auto oldDur = t1.first - t0.first;
|
||||||
mSeq->set_dur(mSeq->get_dur() + dur - (t1 - t0));
|
AddToDuration( newDur - oldDur );
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -604,24 +662,21 @@ Alg_seq *NoteTrack::MakeExportableSeq(std::unique_ptr<Alg_seq> &cleanup) const
|
|||||||
cleanup.reset();
|
cleanup.reset();
|
||||||
double offset = GetOffset();
|
double offset = GetOffset();
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return mSeq.get();
|
return &GetSeq();
|
||||||
// make a copy, deleting events that are shifted before time 0
|
// make a copy, deleting events that are shifted before time 0
|
||||||
double start = -offset;
|
double start = -offset;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
// notes that begin before "start" are not included even if they
|
// notes that begin before "start" are not included even if they
|
||||||
// extend past "start" (because "all" parameter is set to false)
|
// extend past "start" (because "all" parameter is set to false)
|
||||||
cleanup.reset( mSeq->copy(start, mSeq->get_dur() - start, false) );
|
cleanup.reset( GetSeq().copy(start, GetSeq().get_dur() - start, false) );
|
||||||
auto seq = cleanup.get();
|
auto seq = cleanup.get();
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
{
|
{
|
||||||
// Cheat a little
|
|
||||||
NoteTrack *pMutable = const_cast< NoteTrack * >(this);
|
|
||||||
|
|
||||||
// swap cleanup and mSeq so that Shift operates on the NEW copy
|
// swap cleanup and mSeq so that Shift operates on the NEW copy
|
||||||
swap(pMutable->mSeq, cleanup);
|
swap( this->mSeq, cleanup );
|
||||||
auto cleanup2 = finally( [&] { swap(pMutable->mSeq, cleanup); } );
|
auto cleanup2 = finally( [&] { swap( this->mSeq, cleanup ); } );
|
||||||
|
|
||||||
pMutable->Shift(offset);
|
const_cast< NoteTrack *>( this )->Shift(offset);
|
||||||
}
|
}
|
||||||
#ifdef OLD_CODE
|
#ifdef OLD_CODE
|
||||||
// now shift events by offset. This must be done with an integer
|
// now shift events by offset. This must be done with an integer
|
||||||
@ -664,27 +719,28 @@ Alg_seq *NoteTrack::MakeExportableSeq(std::unique_ptr<Alg_seq> &cleanup) const
|
|||||||
seq->set_tempo(bps * 60.0, 0, beats_per_measure * n);
|
seq->set_tempo(bps * 60.0, 0, beats_per_measure * n);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
auto &mySeq = GetSeq();
|
||||||
// if offset is negative, it might not be a multiple of beats, but
|
// if offset is negative, it might not be a multiple of beats, but
|
||||||
// we want to preserve the relative positions of measures. I.e. we
|
// we want to preserve the relative positions of measures. I.e. we
|
||||||
// should shift barlines and time signatures as well as notes.
|
// should shift barlines and time signatures as well as notes.
|
||||||
// Insert a time signature at the first bar-line if necessary.
|
// Insert a time signature at the first bar-line if necessary.
|
||||||
|
|
||||||
// Translate start from seconds to beats and call it beat:
|
// Translate start from seconds to beats and call it beat:
|
||||||
double beat = mSeq->get_time_map()->time_to_beat(start);
|
double beat = mySeq.get_time_map()->time_to_beat(start);
|
||||||
// Find the time signature in mSeq in effect at start (beat):
|
// Find the time signature in mySeq in effect at start (beat):
|
||||||
int i = mSeq->time_sig.find_beat(beat);
|
int i = mySeq.time_sig.find_beat(beat);
|
||||||
// i is where you would insert a NEW time sig at beat,
|
// i is where you would insert a NEW time sig at beat,
|
||||||
// Case 1: beat coincides with a time sig at i. Time signature
|
// Case 1: beat coincides with a time sig at i. Time signature
|
||||||
// at beat means that there is a barline at beat, so when beat
|
// at beat means that there is a barline at beat, so when beat
|
||||||
// is shifted to 0, the relative barline positions are preserved
|
// is shifted to 0, the relative barline positions are preserved
|
||||||
if (mSeq->time_sig.length() > 0 &&
|
if (mySeq.time_sig.length() > 0 &&
|
||||||
within(beat, mSeq->time_sig[i].beat, ALG_EPS)) {
|
within(beat, mySeq.time_sig[i].beat, ALG_EPS)) {
|
||||||
// beat coincides with time signature change, so offset must
|
// beat coincides with time signature change, so offset must
|
||||||
// be a multiple of beats
|
// be a multiple of beats
|
||||||
/* do nothing */ ;
|
/* do nothing */ ;
|
||||||
// Case 2: there is no time signature before beat.
|
// Case 2: there is no time signature before beat.
|
||||||
} else if (i == 0 && (mSeq->time_sig.length() == 0 ||
|
} else if (i == 0 && (mySeq.time_sig.length() == 0 ||
|
||||||
mSeq->time_sig[i].beat > beat)) {
|
mySeq.time_sig[i].beat > beat)) {
|
||||||
// If beat does not fall on an implied barline, we need to
|
// If beat does not fall on an implied barline, we need to
|
||||||
// insert a time signature.
|
// insert a time signature.
|
||||||
double measures = beat / 4.0;
|
double measures = beat / 4.0;
|
||||||
@ -701,7 +757,7 @@ Alg_seq *NoteTrack::MakeExportableSeq(std::unique_ptr<Alg_seq> &cleanup) const
|
|||||||
// Case 3: i-1 must be the effective time sig position
|
// Case 3: i-1 must be the effective time sig position
|
||||||
} else {
|
} else {
|
||||||
i -= 1; // index the time signature in effect at beat
|
i -= 1; // index the time signature in effect at beat
|
||||||
Alg_time_sig_ptr tsp = &(mSeq->time_sig[i]);
|
Alg_time_sig_ptr tsp = &(mySeq.time_sig[i]);
|
||||||
double beats_per_measure = (tsp->num * 4) / tsp->den;
|
double beats_per_measure = (tsp->num * 4) / tsp->den;
|
||||||
double measures = (beat - tsp->beat) / beats_per_measure;
|
double measures = (beat - tsp->beat) / beats_per_measure;
|
||||||
int imeasures = ROUND(measures);
|
int imeasures = ROUND(measures);
|
||||||
@ -737,12 +793,13 @@ bool NoteTrack::ExportAllegro(const wxString &f) const
|
|||||||
double offset = GetOffset();
|
double offset = GetOffset();
|
||||||
bool in_seconds;
|
bool in_seconds;
|
||||||
gPrefs->Read(wxT("/FileFormats/AllegroStyle"), &in_seconds, true);
|
gPrefs->Read(wxT("/FileFormats/AllegroStyle"), &in_seconds, true);
|
||||||
|
auto &seq = GetSeq();
|
||||||
if (in_seconds) {
|
if (in_seconds) {
|
||||||
mSeq->convert_to_seconds();
|
seq.convert_to_seconds();
|
||||||
} else {
|
} else {
|
||||||
mSeq->convert_to_beats();
|
seq.convert_to_beats();
|
||||||
}
|
}
|
||||||
return mSeq->write(f.mb_str(), offset);
|
return seq.write(f.mb_str(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -810,28 +867,15 @@ void NoteTrack::WriteXML(XMLWriter &xmlFile) const
|
|||||||
// may throw
|
// may throw
|
||||||
{
|
{
|
||||||
std::ostringstream data;
|
std::ostringstream data;
|
||||||
// Normally, Duplicate is called in pairs -- once to put NoteTrack
|
|
||||||
// on the Undo stack, and again to move from the Undo stack to an
|
|
||||||
// "active" editable state. For efficiency, we do not do a "real"
|
|
||||||
// Duplicate followed by serialization into a binary blob. Instead,
|
|
||||||
// we combine the Duplicate with serialization or unserialization.
|
|
||||||
// Serialization and Unserialization happen on alternate calls to
|
|
||||||
// Duplicate and (usually) produce the right results at the right
|
|
||||||
// time.
|
|
||||||
// It turns out that this optimized Duplicate is a little too
|
|
||||||
// clever. There is at least one case where a track can be duplicated
|
|
||||||
// and then AutoSave'd. (E.g. do an "Insert Silence" effect on a
|
|
||||||
// NoteTrack.) In this case, mSeq will be NULL. To avoid a crash
|
|
||||||
// and perform WriteXML, we may need to restore NoteTracks from binary
|
|
||||||
// blobs to regular data structures (with an Alg_seq member).
|
|
||||||
Track::Holder holder;
|
Track::Holder holder;
|
||||||
const NoteTrack *saveme = this;
|
const NoteTrack *saveme = this;
|
||||||
if (!mSeq) { // replace saveme with an (unserialized) duplicate
|
if (!mSeq) {
|
||||||
|
// replace saveme with an (unserialized) duplicate, which is
|
||||||
|
// destroyed at end of function.
|
||||||
holder = Duplicate();
|
holder = Duplicate();
|
||||||
saveme = static_cast<NoteTrack*>(holder.get());
|
saveme = static_cast<NoteTrack*>(holder.get());
|
||||||
wxASSERT(saveme->mSeq);
|
|
||||||
}
|
}
|
||||||
saveme->mSeq->write(data, true);
|
saveme->GetSeq().write(data, true);
|
||||||
xmlFile.StartTag(wxT("notetrack"));
|
xmlFile.StartTag(wxT("notetrack"));
|
||||||
xmlFile.WriteAttr(wxT("name"), saveme->mName);
|
xmlFile.WriteAttr(wxT("name"), saveme->mName);
|
||||||
this->NoteTrackBase::WriteXMLAttributes(xmlFile);
|
this->NoteTrackBase::WriteXMLAttributes(xmlFile);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#ifndef __AUDACITY_NOTETRACK__
|
#ifndef __AUDACITY_NOTETRACK__
|
||||||
#define __AUDACITY_NOTETRACK__
|
#define __AUDACITY_NOTETRACK__
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include "Audacity.h"
|
#include "Audacity.h"
|
||||||
#include "Experimental.h"
|
#include "Experimental.h"
|
||||||
@ -58,12 +59,12 @@ using NoteTrackBase =
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
using QuantizedTimeAndBeat = std::pair< double, double >;
|
||||||
|
|
||||||
class AUDACITY_DLL_API NoteTrack final
|
class AUDACITY_DLL_API NoteTrack final
|
||||||
: public NoteTrackBase
|
: public NoteTrackBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
friend class TrackArtist;
|
|
||||||
|
|
||||||
NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
|
NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
|
||||||
virtual ~NoteTrack();
|
virtual ~NoteTrack();
|
||||||
|
|
||||||
@ -76,6 +77,8 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
double GetStartTime() const override;
|
double GetStartTime() const override;
|
||||||
double GetEndTime() const override;
|
double GetEndTime() const override;
|
||||||
|
|
||||||
|
Alg_seq &GetSeq() const;
|
||||||
|
|
||||||
void WarpAndTransposeNotes(double t0, double t1,
|
void WarpAndTransposeNotes(double t0, double t1,
|
||||||
const TimeWarper &warper, double semitones);
|
const TimeWarper &warper, double semitones);
|
||||||
|
|
||||||
@ -83,7 +86,6 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
bool LabelClick(const wxRect &rect, int x, int y, bool right);
|
bool LabelClick(const wxRect &rect, int x, int y, bool right);
|
||||||
|
|
||||||
void SetSequence(std::unique_ptr<Alg_seq> &&seq);
|
void SetSequence(std::unique_ptr<Alg_seq> &&seq);
|
||||||
Alg_seq* GetSequence();
|
|
||||||
void PrintSequence();
|
void PrintSequence();
|
||||||
|
|
||||||
Alg_seq *MakeExportableSeq(std::unique_ptr<Alg_seq> &cleanup) const;
|
Alg_seq *MakeExportableSeq(std::unique_ptr<Alg_seq> &cleanup) const;
|
||||||
@ -112,8 +114,9 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
void SetVelocity(float velocity) { mVelocity = velocity; }
|
void SetVelocity(float velocity) { mVelocity = velocity; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
double NearestBeatTime(double time, double *beat) const;
|
QuantizedTimeAndBeat NearestBeatTime( double time ) const;
|
||||||
bool StretchRegion(double b0, double b1, double dur);
|
bool StretchRegion
|
||||||
|
( QuantizedTimeAndBeat t0, QuantizedTimeAndBeat t1, double newDur );
|
||||||
|
|
||||||
int GetBottomNote() const { return mBottomNote; }
|
int GetBottomNote() const { return mBottomNote; }
|
||||||
int GetPitchHeight() const { return mPitchHeight; }
|
int GetPitchHeight() const { return mPitchHeight; }
|
||||||
@ -204,21 +207,17 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
else
|
else
|
||||||
mVisibleChannels = CHANNEL_BIT(c);
|
mVisibleChannels = CHANNEL_BIT(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Alg_seq> mSeq; // NULL means no sequence
|
void AddToDuration( double delta );
|
||||||
// when Duplicate() is called, assume that it is to put a copy
|
|
||||||
// of the track into the undo stack or to redo/copy from the
|
// These are mutable to allow NoteTrack to switch details of representation
|
||||||
// stack to the project object. We want copies to the stack
|
// in logically const methods
|
||||||
// to be serialized (therefore compact) representations, so
|
// At most one of the two pointers is not null at any time.
|
||||||
// copy will set mSeq to NULL and serialize to the following
|
// Both are null in a newly constructed NoteTrack.
|
||||||
// variables. If this design is correct, the track will be
|
mutable std::unique_ptr<Alg_seq> mSeq;
|
||||||
// duplicated again (in the event of redo) back to the project
|
mutable std::unique_ptr<char[]> mSerializationBuffer;
|
||||||
// at which point we will unserialize the data back to the
|
mutable long mSerializationLength;
|
||||||
// mSeq variable. (TrackArtist should check to make sure this
|
|
||||||
// flip-flop from mSeq to mSerializationBuffer happened an
|
|
||||||
// even number of times, otherwise mSeq will be NULL).
|
|
||||||
mutable std::unique_ptr<char[]> mSerializationBuffer; // NULL means no buffer
|
|
||||||
long mSerializationLength;
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
float mVelocity; // velocity offset
|
float mVelocity; // velocity offset
|
||||||
|
@ -1437,11 +1437,13 @@ void PluginManager::FindFilesInPathList(const wxString & pattern,
|
|||||||
|
|
||||||
wxArrayString paths;
|
wxArrayString paths;
|
||||||
|
|
||||||
// Add the "per-user" plug-ins directory
|
// Add the "per-user" plug-ins directory Windows / Mac
|
||||||
|
#if defined(__WXMAC__) || defined(__WXMSW__)
|
||||||
{
|
{
|
||||||
const wxFileName &ff = FileNames::PlugInDir();
|
const wxFileName &ff = FileNames::PlugInDir();
|
||||||
paths.Add(ff.GetFullPath());
|
paths.Add(ff.GetFullPath());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Add the "Audacity" plug-ins directory
|
// Add the "Audacity" plug-ins directory
|
||||||
wxFileName ff = PlatformCompatibility::GetExecutablePath();
|
wxFileName ff = PlatformCompatibility::GetExecutablePath();
|
||||||
|
@ -2052,8 +2052,10 @@ void AudacityProject::UpdateLayout()
|
|||||||
if (!mTrackPanel)
|
if (!mTrackPanel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mToolManager->LayoutToolBars();
|
// Layout first to get our new width,
|
||||||
|
// Then and only then we can arrange the toolbars.
|
||||||
Layout();
|
Layout();
|
||||||
|
mToolManager->LayoutToolBars();
|
||||||
|
|
||||||
// Retrieve size of this projects window
|
// Retrieve size of this projects window
|
||||||
wxSize mainsz = GetSize();
|
wxSize mainsz = GetSize();
|
||||||
@ -2107,7 +2109,6 @@ void AudacityProject::RefreshAllTitles(bool bShowProjectNumbers )
|
|||||||
|
|
||||||
void AudacityProject::OnIconize(wxIconizeEvent &event)
|
void AudacityProject::OnIconize(wxIconizeEvent &event)
|
||||||
{
|
{
|
||||||
|
|
||||||
int VisibleProjectCount = 0;
|
int VisibleProjectCount = 0;
|
||||||
|
|
||||||
//JKC: On Iconizing we get called twice. Don't know
|
//JKC: On Iconizing we get called twice. Don't know
|
||||||
@ -2311,7 +2312,9 @@ bool AudacityProject::TryToMakeActionAllowed
|
|||||||
if( (MissingFlags & ~( TimeSelectedFlag | WaveTracksSelectedFlag)) )
|
if( (MissingFlags & ~( TimeSelectedFlag | WaveTracksSelectedFlag)) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
OnSelectAll();
|
// This was 'OnSelectAll'. Changing it to OnSelectSomething means if
|
||||||
|
// selecting all tracks is enough, we just do that.
|
||||||
|
OnSelectSomething();
|
||||||
flags = GetUpdateFlags();
|
flags = GetUpdateFlags();
|
||||||
bAllowed = ((flags & mask) == (flagsRqd & mask));
|
bAllowed = ((flags & mask) == (flagsRqd & mask));
|
||||||
return bAllowed;
|
return bAllowed;
|
||||||
@ -2319,7 +2322,19 @@ bool AudacityProject::TryToMakeActionAllowed
|
|||||||
|
|
||||||
void AudacityProject::OnMenu(wxCommandEvent & event)
|
void AudacityProject::OnMenu(wxCommandEvent & event)
|
||||||
{
|
{
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
// Bug 1642: We can arrive here with bogus menu IDs, which we
|
||||||
|
// proceed to process. So if bogus, don't.
|
||||||
|
// The bogus menu IDs are probably generated by controls on the TrackPanel,
|
||||||
|
// such as the Project Rate.
|
||||||
|
// 17000 is the magic number at which we start our menu.
|
||||||
|
// This code would probably NOT be OK on Mac, since we assign
|
||||||
|
// some specific ID numbers.
|
||||||
|
if( event.GetId() < 17000){
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
bool handled = mCommandManager.HandleMenuID(event.GetId(),
|
bool handled = mCommandManager.HandleMenuID(event.GetId(),
|
||||||
GetUpdateFlags(),
|
GetUpdateFlags(),
|
||||||
NoFlagsSpecifed);
|
NoFlagsSpecifed);
|
||||||
@ -4607,19 +4622,6 @@ void AudacityProject::Clear()
|
|||||||
RedrawProject();
|
RedrawProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::SelectNone()
|
|
||||||
{
|
|
||||||
TrackListIterator iter(GetTracks());
|
|
||||||
Track *t = iter.First();
|
|
||||||
while (t) {
|
|
||||||
t->SetSelected(false);
|
|
||||||
t = iter.Next();
|
|
||||||
}
|
|
||||||
mTrackPanel->Refresh(false);
|
|
||||||
if (mMixerBoard)
|
|
||||||
mMixerBoard->Refresh(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function called by other zoom methods
|
// Utility function called by other zoom methods
|
||||||
void AudacityProject::Zoom(double level)
|
void AudacityProject::Zoom(double level)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +100,7 @@ class UndoManager;
|
|||||||
enum class UndoPush : unsigned char;
|
enum class UndoPush : unsigned char;
|
||||||
|
|
||||||
class Track;
|
class Track;
|
||||||
|
class WaveClip;
|
||||||
|
|
||||||
AudacityProject *CreateNewAudacityProject();
|
AudacityProject *CreateNewAudacityProject();
|
||||||
AUDACITY_DLL_API AudacityProject *GetActiveProject();
|
AUDACITY_DLL_API AudacityProject *GetActiveProject();
|
||||||
|
@ -120,7 +120,7 @@ ScreenFramePtr mFrame;
|
|||||||
void OpenScreenshotTools()
|
void OpenScreenshotTools()
|
||||||
{
|
{
|
||||||
if (!mFrame) {
|
if (!mFrame) {
|
||||||
mFrame = ScreenFramePtr{ safenew ScreenFrame(NULL, -1) };
|
mFrame = ScreenFramePtr{ safenew ScreenFrame(wxGetApp().GetTopWindow(), -1) };
|
||||||
}
|
}
|
||||||
mFrame->Show();
|
mFrame->Show();
|
||||||
mFrame->Raise();
|
mFrame->Raise();
|
||||||
@ -298,6 +298,7 @@ ScreenFrame::ScreenFrame(wxWindow * parent, wxWindowID id)
|
|||||||
// The monitoring will switch off temporarily
|
// The monitoring will switch off temporarily
|
||||||
// because we've switched monitor mid play.
|
// because we've switched monitor mid play.
|
||||||
mContext.GetProject()->GetToolManager()->Reset();
|
mContext.GetProject()->GetToolManager()->Reset();
|
||||||
|
Center();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenFrame::~ScreenFrame()
|
ScreenFrame::~ScreenFrame()
|
||||||
|
@ -103,14 +103,20 @@ for registering for changes.
|
|||||||
#include <wx/notebook.h>
|
#include <wx/notebook.h>
|
||||||
#include <wx/treectrl.h>
|
#include <wx/treectrl.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/bmpbuttn.h>
|
||||||
#include "Internat.h"
|
#include "Internat.h"
|
||||||
#include "Experimental.h"
|
#include "Experimental.h"
|
||||||
#include "Shuttle.h"
|
#include "Shuttle.h"
|
||||||
#include "WrappedType.h"
|
#include "WrappedType.h"
|
||||||
#include "widgets/wxPanelWrapper.h"
|
#include "widgets/wxPanelWrapper.h"
|
||||||
|
|
||||||
|
#include "../images/Help.xpm"
|
||||||
|
|
||||||
ShuttleGuiBase::ShuttleGuiBase(wxWindow * pParent, teShuttleMode ShuttleMode )
|
ShuttleGuiBase::ShuttleGuiBase(wxWindow * pParent, teShuttleMode ShuttleMode )
|
||||||
{
|
{
|
||||||
|
// Suppress warnings about the header file
|
||||||
|
wxUnusedVar(Help_xpm);
|
||||||
|
|
||||||
wxASSERT( (pParent != NULL ) || ( ShuttleMode != eIsCreating));
|
wxASSERT( (pParent != NULL ) || ( ShuttleMode != eIsCreating));
|
||||||
|
|
||||||
mpParent = pParent;
|
mpParent = pParent;
|
||||||
@ -2168,7 +2174,11 @@ std::unique_ptr<wxSizer> CreateStdButtonSizer(wxWindow *parent, long buttons, wx
|
|||||||
|
|
||||||
if( buttons & eHelpButton )
|
if( buttons & eHelpButton )
|
||||||
{
|
{
|
||||||
bs->AddButton(safenew wxButton(parent, wxID_HELP));
|
// Replace standard Help button with smaller icon button.
|
||||||
|
// bs->AddButton(safenew wxButton(parent, wxID_HELP));
|
||||||
|
b = new wxBitmapButton(parent, wxID_HELP, Help_xpm);
|
||||||
|
b->SetToolTip( _("Help") );
|
||||||
|
bs->AddButton( b );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buttons & ePreviewButton)
|
if (buttons & ePreviewButton)
|
||||||
|
@ -490,6 +490,7 @@ void ThemeBase::RegisterImage( int &iIndex, const wxImage &Image, const wxString
|
|||||||
|
|
||||||
mBitmapNames.Add( Name );
|
mBitmapNames.Add( Name );
|
||||||
mBitmapFlags.Add( mFlow.mFlags );
|
mBitmapFlags.Add( mFlow.mFlags );
|
||||||
|
mFlow.mFlags &= ~resFlagSkip;
|
||||||
iIndex = mBitmaps.GetCount()-1;
|
iIndex = mBitmaps.GetCount()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +542,7 @@ void FlowPacker::GetNextPosition( int xSize, int ySize )
|
|||||||
xSize += 2*mBorderWidth;
|
xSize += 2*mBorderWidth;
|
||||||
ySize += 2*mBorderWidth;
|
ySize += 2*mBorderWidth;
|
||||||
// if the height has increased, then we are on a NEW group.
|
// if the height has increased, then we are on a NEW group.
|
||||||
if(( ySize > myHeight )||(mFlags != mOldFlags ))
|
if(( ySize > myHeight )||(((mFlags ^ mOldFlags )& ~resFlagSkip)!=0))
|
||||||
{
|
{
|
||||||
SetNewGroup( ((mFlags & resFlagPaired)!=0) ? 2 : 1 );
|
SetNewGroup( ((mFlags & resFlagPaired)!=0) ? 2 : 1 );
|
||||||
myHeight = ySize;
|
myHeight = ySize;
|
||||||
@ -690,9 +691,12 @@ void ThemeBase::CreateImageCache( bool bBinarySave )
|
|||||||
{
|
{
|
||||||
mFlow.GetNextPosition( SrcImage.GetWidth(), SrcImage.GetHeight());
|
mFlow.GetNextPosition( SrcImage.GetWidth(), SrcImage.GetHeight());
|
||||||
ImageCache.SetRGB( mFlow.Rect(), 0xf2, 0xb0, 0x27 );
|
ImageCache.SetRGB( mFlow.Rect(), 0xf2, 0xb0, 0x27 );
|
||||||
|
if( (mFlow.mFlags & resFlagSkip) == 0 )
|
||||||
PasteSubImage( &ImageCache, &SrcImage,
|
PasteSubImage( &ImageCache, &SrcImage,
|
||||||
mFlow.mxPos + mFlow.mBorderWidth,
|
mFlow.mxPos + mFlow.mBorderWidth,
|
||||||
mFlow.myPos + mFlow.mBorderWidth);
|
mFlow.myPos + mFlow.mBorderWidth);
|
||||||
|
else
|
||||||
|
ImageCache.SetRGB( mFlow.RectInner(), 1,1,1);
|
||||||
#ifdef IMAGE_MAP
|
#ifdef IMAGE_MAP
|
||||||
// No href in html. Uses title not alt.
|
// No href in html. Uses title not alt.
|
||||||
wxRect R( mFlow.Rect() );
|
wxRect R( mFlow.Rect() );
|
||||||
@ -753,12 +757,14 @@ void ThemeBase::CreateImageCache( bool bBinarySave )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
// Deliberate policy to use the fast/cheap blocky pixel-multiplication
|
// Deliberate policy to use the fast/cheap blocky pixel-multiplication
|
||||||
// algorithm, as this introduces no artifacts on repeated scale up/down.
|
// algorithm, as this introduces no artifacts on repeated scale up/down.
|
||||||
ImageCache.Rescale(
|
ImageCache.Rescale(
|
||||||
ImageCache.GetWidth() * 4,
|
ImageCache.GetWidth()*4,
|
||||||
ImageCache.GetHeight() *4,
|
ImageCache.GetHeight()*4,
|
||||||
wxIMAGE_QUALITY_NEAREST );
|
wxIMAGE_QUALITY_NEAREST );
|
||||||
|
#endif
|
||||||
if( !ImageCache.SaveFile( FileName, wxBITMAP_TYPE_PNG ))
|
if( !ImageCache.SaveFile( FileName, wxBITMAP_TYPE_PNG ))
|
||||||
{
|
{
|
||||||
wxMessageBox(
|
wxMessageBox(
|
||||||
|
@ -41,7 +41,8 @@ enum teResourceFlags
|
|||||||
resFlagPaired =0x01,
|
resFlagPaired =0x01,
|
||||||
resFlagCursor =0x02,
|
resFlagCursor =0x02,
|
||||||
resFlagNewLine = 0x04,
|
resFlagNewLine = 0x04,
|
||||||
resFlagInternal = 0x08 // For image manipulation. Don't save or load.
|
resFlagInternal = 0x08, // For image manipulation. Don't save or load.
|
||||||
|
resFlagSkip = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
enum teThemeType
|
enum teThemeType
|
||||||
|
@ -250,7 +250,7 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler
|
|||||||
bool IsSyncLockSelected() const;
|
bool IsSyncLockSelected() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioTrack /* not final */ : public Track
|
class AUDACITY_DLL_API AudioTrack /* not final */ : public Track
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AudioTrack(const std::shared_ptr<DirManager> &projDirManager)
|
AudioTrack(const std::shared_ptr<DirManager> &projDirManager)
|
||||||
@ -265,7 +265,7 @@ public:
|
|||||||
{ return false; }
|
{ return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayableTrack /* not final */ : public AudioTrack
|
class AUDACITY_DLL_API PlayableTrack /* not final */ : public AudioTrack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayableTrack(const std::shared_ptr<DirManager> &projDirManager)
|
PlayableTrack(const std::shared_ptr<DirManager> &projDirManager)
|
||||||
|
@ -273,7 +273,7 @@ TrackArtist::TrackArtist()
|
|||||||
|
|
||||||
mdBrange = ENV_DB_RANGE;
|
mdBrange = ENV_DB_RANGE;
|
||||||
mShowClipping = false;
|
mShowClipping = false;
|
||||||
mSampleDisplay = 0;
|
mSampleDisplay = 1;// Stem plots by default.
|
||||||
UpdatePrefs();
|
UpdatePrefs();
|
||||||
|
|
||||||
SetColours();
|
SetColours();
|
||||||
@ -2730,7 +2730,7 @@ void TrackArtist::DrawNoteBackground(const NoteTrack *track, wxDC &dc,
|
|||||||
int left = TIME_TO_X(track->GetOffset());
|
int left = TIME_TO_X(track->GetOffset());
|
||||||
if (left < sel.x) left = sel.x; // clip on left
|
if (left < sel.x) left = sel.x; // clip on left
|
||||||
|
|
||||||
int right = TIME_TO_X(track->GetOffset() + track->mSeq->get_real_dur());
|
int right = TIME_TO_X(track->GetOffset() + track->GetSeq().get_real_dur());
|
||||||
if (right > sel.x + sel.width) right = sel.x + sel.width; // clip on right
|
if (right > sel.x + sel.width) right = sel.x + sel.width; // clip on right
|
||||||
|
|
||||||
// need overlap between MIDI data and the background region
|
// need overlap between MIDI data and the background region
|
||||||
@ -2772,7 +2772,7 @@ void TrackArtist::DrawNoteBackground(const NoteTrack *track, wxDC &dc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// draw bar lines
|
// draw bar lines
|
||||||
Alg_seq_ptr seq = track->mSeq.get();
|
Alg_seq_ptr seq = &track->GetSeq();
|
||||||
// We assume that sliding a NoteTrack around slides the barlines
|
// We assume that sliding a NoteTrack around slides the barlines
|
||||||
// along with the notes. This means that when we write out a track
|
// along with the notes. This means that when we write out a track
|
||||||
// as Allegro or MIDI without the offset, we'll need to insert an
|
// as Allegro or MIDI without the offset, we'll need to insert an
|
||||||
@ -2824,19 +2824,7 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track,
|
|||||||
const double h = X_TO_TIME(rect.x);
|
const double h = X_TO_TIME(rect.x);
|
||||||
const double h1 = X_TO_TIME(rect.x + rect.width);
|
const double h1 = X_TO_TIME(rect.x + rect.width);
|
||||||
|
|
||||||
Alg_seq_ptr seq = track->mSeq.get();
|
Alg_seq_ptr seq = &track->GetSeq();
|
||||||
if (!seq) {
|
|
||||||
wxASSERT(track->mSerializationBuffer);
|
|
||||||
// JKC: Previously this indirected via seq->, a NULL pointer.
|
|
||||||
// This was actually OK, since unserialize is a static function.
|
|
||||||
// Alg_seq:: is clearer.
|
|
||||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(track->mSerializationBuffer.get(),
|
|
||||||
track->mSerializationLength) };
|
|
||||||
wxASSERT(alg_track->get_type() == 's');
|
|
||||||
const_cast<NoteTrack*>(track)->mSeq.reset(seq = static_cast<Alg_seq*>(alg_track.release()));
|
|
||||||
track->mSerializationBuffer.reset();
|
|
||||||
}
|
|
||||||
wxASSERT(seq);
|
|
||||||
|
|
||||||
if (!track->GetSelected())
|
if (!track->GetSelected())
|
||||||
sel0 = sel1 = 0.0;
|
sel0 = sel1 = 0.0;
|
||||||
@ -3214,7 +3202,7 @@ void TrackArtist::UpdatePrefs()
|
|||||||
{
|
{
|
||||||
mdBrange = gPrefs->Read(ENV_DB_KEY, mdBrange);
|
mdBrange = gPrefs->Read(ENV_DB_KEY, mdBrange);
|
||||||
mShowClipping = gPrefs->Read(wxT("/GUI/ShowClipping"), mShowClipping);
|
mShowClipping = gPrefs->Read(wxT("/GUI/ShowClipping"), mShowClipping);
|
||||||
gPrefs->Read(wxT("/GUI/SampleView"), &mSampleDisplay, 0);
|
gPrefs->Read(wxT("/GUI/SampleView"), &mSampleDisplay, 1);
|
||||||
SetColours();
|
SetColours();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
101
src/TrackPanel.h
101
src/TrackPanel.h
@ -155,6 +155,25 @@ private:
|
|||||||
const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
|
const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
|
||||||
|
|
||||||
|
|
||||||
|
struct ClipMoveState {
|
||||||
|
WaveClip *capturedClip {};
|
||||||
|
bool capturedClipIsSelection {};
|
||||||
|
TrackArray trackExclusions {};
|
||||||
|
double hSlideAmount {};
|
||||||
|
TrackClipArray capturedClipArray {};
|
||||||
|
wxInt64 snapLeft { -1 }, snapRight { -1 };
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
capturedClip = nullptr;
|
||||||
|
capturedClipIsSelection = false;
|
||||||
|
trackExclusions.clear();
|
||||||
|
hSlideAmount = 0;
|
||||||
|
capturedClipArray.clear();
|
||||||
|
snapLeft = snapRight = -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
|
class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -256,7 +275,9 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
|
|||||||
// (ignoring any fisheye)
|
// (ignoring any fisheye)
|
||||||
virtual double GetScreenEndTime() const;
|
virtual double GetScreenEndTime() const;
|
||||||
|
|
||||||
virtual void OnClipMove(bool right);
|
static double OnClipMove
|
||||||
|
(ViewInfo &viewInfo, Track *track,
|
||||||
|
TrackList &trackList, bool syncLocked, bool right);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual MixerBoard* GetMixerBoard();
|
virtual MixerBoard* GetMixerBoard();
|
||||||
@ -299,20 +320,33 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
|
|||||||
// part shrinks, keeping the leftmost and rightmost boundaries
|
// part shrinks, keeping the leftmost and rightmost boundaries
|
||||||
// fixed.
|
// fixed.
|
||||||
enum StretchEnum {
|
enum StretchEnum {
|
||||||
|
stretchNone = 0, // false value!
|
||||||
stretchLeft,
|
stretchLeft,
|
||||||
stretchCenter,
|
stretchCenter,
|
||||||
stretchRight
|
stretchRight
|
||||||
};
|
};
|
||||||
StretchEnum mStretchMode; // remembers what to drag
|
struct StretchState {
|
||||||
bool mStretching; // true between mouse down and mouse up
|
StretchEnum mMode { stretchCenter }; // remembers what to drag
|
||||||
bool mStretched; // true after drag has pushed state
|
|
||||||
double mStretchStart; // time of initial mouse position, quantized
|
using QuantizedTimeAndBeat = std::pair< double, double >;
|
||||||
// to the nearest beat
|
|
||||||
double mStretchSel0; // initial sel0 (left) quantized to nearest beat
|
bool mStretching {}; // true between mouse down and mouse up
|
||||||
double mStretchSel1; // initial sel1 (left) quantized to nearest beat
|
double mOrigT0 {};
|
||||||
double mStretchLeftBeats; // how many beats from left to cursor
|
double mOrigT1 {};
|
||||||
double mStretchRightBeats; // how many beats from cursor to right
|
QuantizedTimeAndBeat mBeatCenter { 0, 0 };
|
||||||
virtual bool HitTestStretch(Track *track, const wxRect &rect, const wxMouseEvent & event);
|
QuantizedTimeAndBeat mBeat0 { 0, 0 };
|
||||||
|
QuantizedTimeAndBeat mBeat1 { 0, 0 };
|
||||||
|
double mLeftBeats {}; // how many beats from left to cursor
|
||||||
|
double mRightBeats {}; // how many beats from cursor to right
|
||||||
|
} mStretchState;
|
||||||
|
|
||||||
|
virtual StretchEnum HitTestStretch
|
||||||
|
( const Track *track, const wxRect &rect, const wxMouseEvent & event,
|
||||||
|
StretchState *pState = nullptr );
|
||||||
|
wxCursor *ChooseStretchCursor( StretchEnum mode );
|
||||||
|
static StretchEnum ChooseStretchMode
|
||||||
|
( const wxMouseEvent &event, const wxRect &rect, const ViewInfo &viewInfo,
|
||||||
|
const NoteTrack *nt, StretchState *pState = nullptr );
|
||||||
virtual void Stretch(int mouseXCoordinate, int trackLeftEdge, Track *pTrack);
|
virtual void Stretch(int mouseXCoordinate, int trackLeftEdge, Track *pTrack);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -383,10 +417,16 @@ protected:
|
|||||||
virtual void HandleSlide(wxMouseEvent & event);
|
virtual void HandleSlide(wxMouseEvent & event);
|
||||||
virtual void StartSlide(wxMouseEvent &event);
|
virtual void StartSlide(wxMouseEvent &event);
|
||||||
virtual void DoSlide(wxMouseEvent &event);
|
virtual void DoSlide(wxMouseEvent &event);
|
||||||
virtual void DoSlideHorizontal();
|
static void DoSlideHorizontal
|
||||||
virtual void CreateListOfCapturedClips(double clickTime);
|
( ClipMoveState &state, TrackList &trackList, Track &capturedTrack );
|
||||||
virtual void AddClipsToCaptured(Track *t, bool withinSelection);
|
static void CreateListOfCapturedClips
|
||||||
virtual void AddClipsToCaptured(Track *t, double t0, double t1);
|
( ClipMoveState &state, const ViewInfo &viewInfo, Track &capturedTrack,
|
||||||
|
TrackList &trackList, bool syncLocked, double clickTime );
|
||||||
|
static void AddClipsToCaptured
|
||||||
|
( ClipMoveState &state, const ViewInfo &viewInfo,
|
||||||
|
Track *t, bool withinSelection );
|
||||||
|
static void AddClipsToCaptured
|
||||||
|
( ClipMoveState &state, Track *t, double t0, double t1 );
|
||||||
|
|
||||||
// AS: Handle zooming into tracks
|
// AS: Handle zooming into tracks
|
||||||
virtual void HandleZoom(wxMouseEvent & event);
|
virtual void HandleZoom(wxMouseEvent & event);
|
||||||
@ -658,10 +698,7 @@ protected:
|
|||||||
|
|
||||||
Track *mCapturedTrack;
|
Track *mCapturedTrack;
|
||||||
Envelope *mCapturedEnvelope;
|
Envelope *mCapturedEnvelope;
|
||||||
WaveClip *mCapturedClip;
|
ClipMoveState mClipMoveState;
|
||||||
TrackClipArray mCapturedClipArray;
|
|
||||||
TrackArray mTrackExclusions;
|
|
||||||
bool mCapturedClipIsSelection;
|
|
||||||
WaveTrackLocation mCapturedTrackLocation;
|
WaveTrackLocation mCapturedTrackLocation;
|
||||||
wxRect mCapturedTrackLocationRect;
|
wxRect mCapturedTrackLocationRect;
|
||||||
wxRect mCapturedRect;
|
wxRect mCapturedRect;
|
||||||
@ -678,10 +715,6 @@ protected:
|
|||||||
wxBaseArrayDouble mSlideSnapToPoints;
|
wxBaseArrayDouble mSlideSnapToPoints;
|
||||||
wxArrayInt mSlideSnapLinePixels;
|
wxArrayInt mSlideSnapLinePixels;
|
||||||
|
|
||||||
// The amount that clips are sliding horizontally; this allows
|
|
||||||
// us to undo the slide and then slide it by another amount
|
|
||||||
double mHSlideAmount;
|
|
||||||
|
|
||||||
bool mDidSlideVertically;
|
bool mDidSlideVertically;
|
||||||
|
|
||||||
bool mRedrawAfterStop;
|
bool mRedrawAfterStop;
|
||||||
@ -702,10 +735,28 @@ protected:
|
|||||||
// are the horizontal index of pixels to display user feedback
|
// are the horizontal index of pixels to display user feedback
|
||||||
// guidelines so the user knows when such snapping is taking place.
|
// guidelines so the user knows when such snapping is taking place.
|
||||||
std::unique_ptr<SnapManager> mSnapManager;
|
std::unique_ptr<SnapManager> mSnapManager;
|
||||||
wxInt64 mSnapLeft;
|
wxInt64 mSnapLeft { -1 };
|
||||||
wxInt64 mSnapRight;
|
wxInt64 mSnapRight { -1 };
|
||||||
bool mSnapPreferRightEdge;
|
bool mSnapPreferRightEdge;
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxInt64 GetSnapLeft () const
|
||||||
|
{
|
||||||
|
if ( mMouseCapture == IsSliding )
|
||||||
|
return mClipMoveState.snapLeft ;
|
||||||
|
else
|
||||||
|
return mSnapLeft ;
|
||||||
|
}
|
||||||
|
wxInt64 GetSnapRight() const
|
||||||
|
{
|
||||||
|
if ( mMouseCapture == IsSliding )
|
||||||
|
return mClipMoveState.snapRight;
|
||||||
|
else
|
||||||
|
return mSnapRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
NumericConverter mConverter;
|
NumericConverter mConverter;
|
||||||
|
|
||||||
WaveTrack * mDrawingTrack; // Keeps track of which track you are drawing on between events cf. HandleDraw()
|
WaveTrack * mDrawingTrack; // Keeps track of which track you are drawing on between events cf. HandleDraw()
|
||||||
|
@ -61,7 +61,6 @@ UndoManager::UndoManager()
|
|||||||
{
|
{
|
||||||
current = -1;
|
current = -1;
|
||||||
saved = -1;
|
saved = -1;
|
||||||
consolidationCount = 0;
|
|
||||||
ResetODChangesFlag();
|
ResetODChangesFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +256,9 @@ void UndoManager::PushState(const TrackList * l,
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
// If consolidate is set to true, group up to 3 identical operations.
|
if ( ((flags & UndoPush::CONSOLIDATE) != UndoPush::MINIMAL) &&
|
||||||
if (((flags & UndoPush::CONSOLIDATE) != UndoPush::MINIMAL) && lastAction == longDescription &&
|
lastAction == longDescription &&
|
||||||
consolidationCount < 2) {
|
mayConsolidate ) {
|
||||||
consolidationCount++;
|
|
||||||
ModifyState(l, selectedRegion, tags);
|
ModifyState(l, selectedRegion, tags);
|
||||||
// MB: If the "saved" state was modified by ModifyState, reset
|
// MB: If the "saved" state was modified by ModifyState, reset
|
||||||
// it so that UnsavedChanges returns true.
|
// it so that UnsavedChanges returns true.
|
||||||
@ -270,7 +268,7 @@ void UndoManager::PushState(const TrackList * l,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
consolidationCount = 0;
|
mayConsolidate = true;
|
||||||
|
|
||||||
i = current + 1;
|
i = current + 1;
|
||||||
while (i < stack.size()) {
|
while (i < stack.size()) {
|
||||||
@ -319,7 +317,7 @@ const UndoState &UndoManager::SetStateTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastAction = wxT("");
|
lastAction = wxT("");
|
||||||
consolidationCount = 0;
|
mayConsolidate = false;
|
||||||
|
|
||||||
return stack[current]->state;
|
return stack[current]->state;
|
||||||
}
|
}
|
||||||
@ -333,7 +331,7 @@ const UndoState &UndoManager::Undo(SelectedRegion *selectedRegion)
|
|||||||
*selectedRegion = stack[current]->state.selectedRegion;
|
*selectedRegion = stack[current]->state.selectedRegion;
|
||||||
|
|
||||||
lastAction = wxT("");
|
lastAction = wxT("");
|
||||||
consolidationCount = 0;
|
mayConsolidate = false;
|
||||||
|
|
||||||
return stack[current]->state;
|
return stack[current]->state;
|
||||||
}
|
}
|
||||||
@ -360,7 +358,7 @@ const UndoState &UndoManager::Redo(SelectedRegion *selectedRegion)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
lastAction = wxT("");
|
lastAction = wxT("");
|
||||||
consolidationCount = 0;
|
mayConsolidate = false;
|
||||||
|
|
||||||
return stack[current]->state;
|
return stack[current]->state;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,9 @@
|
|||||||
|
|
||||||
UndoManager can also automatically consolidate actions into
|
UndoManager can also automatically consolidate actions into
|
||||||
a single state change. If the "consolidate" argument to
|
a single state change. If the "consolidate" argument to
|
||||||
PushState is true, then up to 3 identical events in a row
|
PushState is true, then new changes may accumulate into the most
|
||||||
will result in one PushState and 2 ModifyStates.
|
recent Undo state, if descriptions match and if no Undo or Redo or rollback
|
||||||
|
operation intervened since that state was pushed.
|
||||||
|
|
||||||
Undo() temporarily moves down one state and returns the track
|
Undo() temporarily moves down one state and returns the track
|
||||||
hierarchy. If another PushState is called, the redo information
|
hierarchy. If another PushState is called, the redo information
|
||||||
@ -107,6 +108,8 @@ class AUDACITY_DLL_API UndoManager {
|
|||||||
unsigned int GetNumStates();
|
unsigned int GetNumStates();
|
||||||
unsigned int GetCurrentState();
|
unsigned int GetCurrentState();
|
||||||
|
|
||||||
|
void StopConsolidating() { mayConsolidate = false; }
|
||||||
|
|
||||||
void GetShortDescription(unsigned int n, wxString *desc);
|
void GetShortDescription(unsigned int n, wxString *desc);
|
||||||
// Return value must first be calculated by CalculateSpaceUsage():
|
// Return value must first be calculated by CalculateSpaceUsage():
|
||||||
wxLongLong_t GetLongDescription(unsigned int n, wxString *desc, wxString *size);
|
wxLongLong_t GetLongDescription(unsigned int n, wxString *desc, wxString *size);
|
||||||
@ -143,7 +146,7 @@ class AUDACITY_DLL_API UndoManager {
|
|||||||
UndoStack stack;
|
UndoStack stack;
|
||||||
|
|
||||||
wxString lastAction;
|
wxString lastAction;
|
||||||
int consolidationCount;
|
bool mayConsolidate { false };
|
||||||
|
|
||||||
SpaceArray space;
|
SpaceArray space;
|
||||||
unsigned long long mClipboardSpaceUsage {};
|
unsigned long long mClipboardSpaceUsage {};
|
||||||
|
@ -1948,3 +1948,17 @@ void WaveClip::Resample(int rate, ProgressDialog *progress)
|
|||||||
mRate = rate;
|
mRate = rate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used by commands which interact with clips using the keyboard.
|
||||||
|
// When two clips are immediately next to each other, the GetEndTime()
|
||||||
|
// of the first clip and the GetStartTime() of the second clip may not
|
||||||
|
// be exactly equal due to rounding errors.
|
||||||
|
bool WaveClip::SharesBoundaryWithNextClip(const WaveClip* next) const
|
||||||
|
{
|
||||||
|
double endThis = GetRate() * GetOffset() + GetNumSamples().as_double();
|
||||||
|
double startNext = next->GetRate() * next->GetOffset();
|
||||||
|
|
||||||
|
// given that a double has about 15 significant digits, using a criterion
|
||||||
|
// of half a sample should be safe in all normal usage.
|
||||||
|
return fabs(startNext - endThis) < 0.5;
|
||||||
|
}
|
||||||
|
@ -378,6 +378,9 @@ public:
|
|||||||
bool GetIsPlaceholder() const { return mIsPlaceholder; }
|
bool GetIsPlaceholder() const { return mIsPlaceholder; }
|
||||||
void SetIsPlaceholder(bool val) { mIsPlaceholder = val; }
|
void SetIsPlaceholder(bool val) { mIsPlaceholder = val; }
|
||||||
|
|
||||||
|
// used by commands which interact with clips using the keyboard
|
||||||
|
bool SharesBoundaryWithNextClip(const WaveClip* next) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Cache of values to colour pixels of Spectrogram - used by TrackArtist
|
// Cache of values to colour pixels of Spectrogram - used by TrackArtist
|
||||||
mutable std::unique_ptr<SpecPxCache> mSpecPxCache;
|
mutable std::unique_ptr<SpecPxCache> mSpecPxCache;
|
||||||
|
@ -2212,15 +2212,27 @@ WaveClip* WaveTrack::GetClipAtSample(sampleCount sample)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When the time is both the end of a clip and the start of the next clip, the
|
||||||
|
// latter clip is returned.
|
||||||
WaveClip* WaveTrack::GetClipAtTime(double time)
|
WaveClip* WaveTrack::GetClipAtTime(double time)
|
||||||
{
|
{
|
||||||
// When the time is both the end of a clip and the start of the next clip, the
|
|
||||||
// latter clip is returned.
|
|
||||||
const auto clips = SortedClipArray();
|
const auto clips = SortedClipArray();
|
||||||
auto result = std::find_if(clips.rbegin(), clips.rend(), [&] (WaveClip* const& clip) {
|
auto p = std::find_if(clips.rbegin(), clips.rend(), [&] (WaveClip* const& clip) {
|
||||||
return time >= clip->GetStartTime() && time <= clip->GetEndTime(); });
|
return time >= clip->GetStartTime() && time <= clip->GetEndTime(); });
|
||||||
|
|
||||||
return result != clips.rend() ? *result : nullptr;
|
// When two clips are immediately next to each other, the GetEndTime() of the first clip
|
||||||
|
// and the GetStartTime() of the second clip may not be exactly equal due to rounding errors.
|
||||||
|
// If "time" is the end time of the first of two such clips, and the end time is slightly
|
||||||
|
// less than the start time of the second clip, then the first rather than the
|
||||||
|
// second clip is found by the above code. So correct this.
|
||||||
|
if (p != clips.rend() & p != clips.rbegin() &&
|
||||||
|
time == (*p)->GetEndTime() &&
|
||||||
|
(*p)->SharesBoundaryWithNextClip(*(p-1))) {
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p != clips.rend() ? *p : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Envelope* WaveTrack::GetEnvelopeAtX(int xcoord)
|
Envelope* WaveTrack::GetEnvelopeAtX(int xcoord)
|
||||||
|
@ -448,7 +448,7 @@ void CommandManager::PurgeData()
|
|||||||
mCommandIDHash.clear();
|
mCommandIDHash.clear();
|
||||||
|
|
||||||
mCurrentMenuName = COMMAND;
|
mCurrentMenuName = COMMAND;
|
||||||
mCurrentID = 0;
|
mCurrentID = 17000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1204,12 +1204,17 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
|
|||||||
{
|
{
|
||||||
wxWindow * pWnd = wxWindow::FindFocus();
|
wxWindow * pWnd = wxWindow::FindFocus();
|
||||||
wxWindow * pTrackPanel = (wxWindow*)GetActiveProject()->GetTrackPanel();
|
wxWindow * pTrackPanel = (wxWindow*)GetActiveProject()->GetTrackPanel();
|
||||||
|
bool bIntercept = pWnd != pTrackPanel;
|
||||||
|
// Intercept keys from windows that are NOT panels
|
||||||
|
if( bIntercept ){
|
||||||
|
bIntercept = pWnd && ( dynamic_cast<wxPanel*>(pWnd) == NULL );
|
||||||
|
}
|
||||||
//wxLogDebug("Focus: %p TrackPanel: %p", pWnd, pTrackPanel );
|
//wxLogDebug("Focus: %p TrackPanel: %p", pWnd, pTrackPanel );
|
||||||
// We allow the keystrokes below to be handled by wxWidgets controls IF we are
|
// We allow the keystrokes below to be handled by wxWidgets controls IF we are
|
||||||
// in some sub window rather than in the TrackPanel itself.
|
// in some sub window rather than in the TrackPanel itself.
|
||||||
// Otherwise they will go to our command handler and if it handles them
|
// Otherwise they will go to our command handler and if it handles them
|
||||||
// they will NOT be available to wxWidgets.
|
// they will NOT be available to wxWidgets.
|
||||||
if( pWnd != pTrackPanel ){
|
if( bIntercept ){
|
||||||
switch( evt.GetKeyCode() ){
|
switch( evt.GetKeyCode() ){
|
||||||
case WXK_LEFT:
|
case WXK_LEFT:
|
||||||
case WXK_RIGHT:
|
case WXK_RIGHT:
|
||||||
|
@ -90,6 +90,11 @@ wxString EffectAmplify::GetDescription()
|
|||||||
return XO("Increases or decreases the volume of the audio you have selected");
|
return XO("Increases or decreases the volume of the audio you have selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectAmplify::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Amplify");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectAmplify::GetType()
|
EffectType EffectAmplify::GetType()
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -115,6 +115,11 @@ wxString EffectAutoDuck::GetDescription()
|
|||||||
return XO("Reduces (ducks) the volume of one or more tracks whenever the volume of a specified \"control\" track reaches a particular level");
|
return XO("Reduces (ducks) the volume of one or more tracks whenever the volume of a specified \"control\" track reaches a particular level");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectAutoDuck::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Auto_Duck");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectAutoDuck::GetType()
|
EffectType EffectAutoDuck::GetType()
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -92,6 +92,11 @@ wxString EffectBassTreble::GetDescription()
|
|||||||
return XO("Simple tone control effect");
|
return XO("Simple tone control effect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectBassTreble::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Bass_and_Treble");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectBassTreble::GetType()
|
EffectType EffectBassTreble::GetType()
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -126,6 +126,11 @@ wxString EffectChangePitch::GetDescription()
|
|||||||
return XO("Change the pitch of a track without changing its tempo");
|
return XO("Change the pitch of a track without changing its tempo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectChangePitch::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Change_Pitch");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectChangePitch::GetType()
|
EffectType EffectChangePitch::GetType()
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -115,6 +115,12 @@ wxString EffectChangeSpeed::GetDescription()
|
|||||||
return XO("Change the speed of a track, also changing its pitch");
|
return XO("Change the speed of a track, also changing its pitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectChangeSpeed::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Change_Speed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectChangeSpeed::GetType()
|
EffectType EffectChangeSpeed::GetType()
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -102,6 +102,11 @@ wxString EffectChangeTempo::GetDescription()
|
|||||||
return XO("Change the tempo of a selection without changing its pitch");
|
return XO("Change the tempo of a selection without changing its pitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectChangeTempo::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Change_Tempo");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectChangeTempo::GetType()
|
EffectType EffectChangeTempo::GetType()
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -85,6 +85,11 @@ wxString EffectClickRemoval::GetDescription()
|
|||||||
return XO("Click Removal is designed to remove clicks on audio tracks");
|
return XO("Click Removal is designed to remove clicks on audio tracks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectClickRemoval::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Click_Removal");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectClickRemoval::GetType()
|
EffectType EffectClickRemoval::GetType()
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -107,6 +107,11 @@ wxString EffectCompressor::GetDescription()
|
|||||||
return XO("Compresses the dynamic range of audio");
|
return XO("Compresses the dynamic range of audio");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectCompressor::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Compressor");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectCompressor::GetType()
|
EffectType EffectCompressor::GetType()
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -177,6 +177,7 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
|
|||||||
S.SetBorder(5);
|
S.SetBorder(5);
|
||||||
S.StartHorizontalLay(wxCENTER, false);
|
S.StartHorizontalLay(wxCENTER, false);
|
||||||
{
|
{
|
||||||
|
/* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
|
||||||
S.AddTitle(_("Contrast Analyzer, for measuring RMS volume differences between two selections of audio."));
|
S.AddTitle(_("Contrast Analyzer, for measuring RMS volume differences between two selections of audio."));
|
||||||
}
|
}
|
||||||
S.EndHorizontalLay();
|
S.EndHorizontalLay();
|
||||||
@ -362,6 +363,67 @@ void ContrastDialog::OnGetBackground(wxCommandEvent & /*event*/)
|
|||||||
results();
|
results();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// PRL: I gathered formatting into these functions, and eliminated some
|
||||||
|
// repetitions, and removed the redundant word "Average" as applied to RMS.
|
||||||
|
// Should these variations in formats be collapsed further?
|
||||||
|
|
||||||
|
// Pass nullptr when value is not yet defined
|
||||||
|
wxString FormatRMSMessage( float *pValue )
|
||||||
|
{
|
||||||
|
|
||||||
|
/* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
|
||||||
|
wxString format0{ _("RMS = %s.") };
|
||||||
|
|
||||||
|
/* i18n-hint: dB abbreviates decibels */
|
||||||
|
wxString format1{ _("%s dB") };
|
||||||
|
|
||||||
|
wxString value;
|
||||||
|
|
||||||
|
if ( pValue )
|
||||||
|
if( fabs( *pValue ) != std::numeric_limits<float>::infinity() ) {
|
||||||
|
auto number = wxString::Format( _("%.2f"), *pValue );
|
||||||
|
value = wxString::Format( format1, number );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = _("zero");
|
||||||
|
else
|
||||||
|
value = wxString::Format( format1, "" );
|
||||||
|
|
||||||
|
return wxString::Format( format0, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString FormatDifference( float diffdB )
|
||||||
|
{
|
||||||
|
if( diffdB != diffdB ) // test for NaN, reliant on IEEE implementation
|
||||||
|
return _("indeterminate");
|
||||||
|
else {
|
||||||
|
if( diffdB != std::numeric_limits<float>::infinity() )
|
||||||
|
/* i18n-hint: dB abbreviates decibels */
|
||||||
|
/* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
|
||||||
|
return wxString::Format(_("%.2f dB RMS"), diffdB);
|
||||||
|
else
|
||||||
|
/* i18n-hint: dB abbreviates decibels */
|
||||||
|
return wxString::Format(_("Infinite dB difference"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString FormatDifferenceForExport( float diffdB )
|
||||||
|
{
|
||||||
|
if( diffdB != diffdB ) //test for NaN, reliant on IEEE implementation
|
||||||
|
return _("Difference is indeterminate.");
|
||||||
|
else
|
||||||
|
if( fabs(diffdB) != std::numeric_limits<float>::infinity() )
|
||||||
|
/* i18n-hint: dB abbreviates decibels */
|
||||||
|
/* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
|
||||||
|
return wxString::Format(_("Difference = %.2f RMS dB."), diffdB );
|
||||||
|
else
|
||||||
|
/* i18n-hint: dB abbreviates decibels */
|
||||||
|
/* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
|
||||||
|
return _("Difference = infinite RMS dB.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ContrastDialog::results()
|
void ContrastDialog::results()
|
||||||
{
|
{
|
||||||
mPassFailText->SetName(wxT(""));
|
mPassFailText->SetName(wxT(""));
|
||||||
@ -381,25 +443,17 @@ void ContrastDialog::results()
|
|||||||
mPassFailText->ChangeValue(_("Background higher than foreground"));
|
mPassFailText->ChangeValue(_("Background higher than foreground"));
|
||||||
}
|
}
|
||||||
else if(diffdB > WCAG2_PASS) {
|
else if(diffdB > WCAG2_PASS) {
|
||||||
|
/* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
|
||||||
mPassFailText->ChangeValue(_("WCAG2 Pass"));
|
mPassFailText->ChangeValue(_("WCAG2 Pass"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
|
||||||
mPassFailText->ChangeValue(_("WCAG2 Fail"));
|
mPassFailText->ChangeValue(_("WCAG2 Fail"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* i18n-hint: i.e. difference in loudness at the moment. */
|
/* i18n-hint: i.e. difference in loudness at the moment. */
|
||||||
mDiffText->SetName(_("Current difference"));
|
mDiffText->SetName(_("Current difference"));
|
||||||
if( diffdB != diffdB ) { // test for NaN, reliant on IEEE implementation
|
mDiffText->ChangeValue( FormatDifference( diffdB ) );
|
||||||
mDiffText->ChangeValue(wxString::Format(_("indeterminate")));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( diffdB != std::numeric_limits<float>::infinity() ) {
|
|
||||||
mDiffText->ChangeValue(wxString::Format(_("%.2f dB Average RMS"), diffdB));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mDiffText->ChangeValue(wxString::Format(_("Infinite dB difference")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mForegroundIsDefined) {
|
if (mForegroundIsDefined) {
|
||||||
@ -459,6 +513,7 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.AddLine(wxT("==================================="));
|
f.AddLine(wxT("==================================="));
|
||||||
|
/* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
|
||||||
f.AddLine(_("WCAG 2.0 Success Criteria 1.4.7 Contrast Results"));
|
f.AddLine(_("WCAG 2.0 Success Criteria 1.4.7 Contrast Results"));
|
||||||
f.AddLine(wxT(""));
|
f.AddLine(wxT(""));
|
||||||
f.AddLine(wxString::Format(_("Filename = %s."), project->GetFileName().c_str() ));
|
f.AddLine(wxString::Format(_("Filename = %s."), project->GetFileName().c_str() ));
|
||||||
@ -474,13 +529,7 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
|
|||||||
m = (int)((t - h*3600)/60);
|
m = (int)((t - h*3600)/60);
|
||||||
s = t - h*3600.0 - m*60.0;
|
s = t - h*3600.0 - m*60.0;
|
||||||
f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
|
f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
|
||||||
if(mForegroundIsDefined)
|
f.AddLine( FormatRMSMessage( mForegroundIsDefined ? &foregrounddB : nullptr ) );
|
||||||
if( fabs(foregrounddB) != std::numeric_limits<float>::infinity() )
|
|
||||||
f.AddLine(wxString::Format(_("Average RMS = %.2f dB."), foregrounddB ));
|
|
||||||
else
|
|
||||||
f.AddLine(wxString::Format(_("Average RMS = zero.") ));
|
|
||||||
else
|
|
||||||
f.AddLine(wxString::Format(_("Average RMS = dB.")));
|
|
||||||
f.AddLine(wxT(""));
|
f.AddLine(wxT(""));
|
||||||
f.AddLine(_("Background"));
|
f.AddLine(_("Background"));
|
||||||
t = (float)mBackgroundStartT->GetValue();
|
t = (float)mBackgroundStartT->GetValue();
|
||||||
@ -493,23 +542,12 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
|
|||||||
m = (int)((t - h*3600)/60);
|
m = (int)((t - h*3600)/60);
|
||||||
s = t - h*3600.0 - m*60.0;
|
s = t - h*3600.0 - m*60.0;
|
||||||
f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
|
f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
|
||||||
if(mBackgroundIsDefined)
|
f.AddLine( FormatRMSMessage( mBackgroundIsDefined ? &backgrounddB : nullptr ) );
|
||||||
if( fabs(backgrounddB) != std::numeric_limits<float>::infinity() )
|
|
||||||
f.AddLine(wxString::Format(_("Average RMS = %.2f dB."), backgrounddB ));
|
|
||||||
else
|
|
||||||
f.AddLine(wxString::Format(_("Average RMS = zero.") ));
|
|
||||||
else
|
|
||||||
f.AddLine(wxString::Format(_("Average RMS = dB.")));
|
|
||||||
f.AddLine(wxT(""));
|
f.AddLine(wxT(""));
|
||||||
f.AddLine(_("Results"));
|
f.AddLine(_("Results"));
|
||||||
float diffdB = foregrounddB - backgrounddB;
|
float diffdB = foregrounddB - backgrounddB;
|
||||||
if( diffdB != diffdB ) //test for NaN, reliant on IEEE implementation
|
|
||||||
f.AddLine(wxString::Format(_("Difference is indeterminate.") ));
|
f.AddLine( FormatDifferenceForExport( diffdB ) );
|
||||||
else
|
|
||||||
if( fabs(diffdB) != std::numeric_limits<float>::infinity() )
|
|
||||||
f.AddLine(wxString::Format(_("Difference = %.2f Average RMS dB."), diffdB ));
|
|
||||||
else
|
|
||||||
f.AddLine(wxString::Format(_("Difference = infinite Average RMS dB.")));
|
|
||||||
if( diffdB > 20. )
|
if( diffdB > 20. )
|
||||||
f.AddLine(_("Success Criteria 1.4.7 of WCAG 2.0: Pass"));
|
f.AddLine(_("Success Criteria 1.4.7 of WCAG 2.0: Pass"));
|
||||||
else
|
else
|
||||||
|
@ -192,6 +192,11 @@ wxString EffectDistortion::GetDescription()
|
|||||||
return XO("Waveshaping distortion effect");
|
return XO("Waveshaping distortion effect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectDistortion::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Distortion");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectDistortion::GetType()
|
EffectType EffectDistortion::GetType()
|
||||||
|
@ -68,6 +68,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -101,6 +101,11 @@ wxString EffectDtmf::GetDescription()
|
|||||||
return XO("Generates dual-tone multi-frequency (DTMF) tones like those produced by the keypad on telephones");
|
return XO("Generates dual-tone multi-frequency (DTMF) tones like those produced by the keypad on telephones");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectDtmf::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Generate_Menu#dtmf");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectDtmf::GetType()
|
EffectType EffectDtmf::GetType()
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -60,6 +60,11 @@ wxString EffectEcho::GetDescription()
|
|||||||
return XO("Repeats the selected audio again and again");
|
return XO("Repeats the selected audio again and again");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectEcho::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Echo");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectEcho::GetType()
|
EffectType EffectEcho::GetType()
|
||||||
|
@ -33,6 +33,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -53,6 +53,10 @@ greater use in future.
|
|||||||
#include "../ondemand/ODManager.h"
|
#include "../ondemand/ODManager.h"
|
||||||
#include "TimeWarper.h"
|
#include "TimeWarper.h"
|
||||||
#include "nyquist/Nyquist.h"
|
#include "nyquist/Nyquist.h"
|
||||||
|
#include "../widgets/HelpSystem.h"
|
||||||
|
#include "../widgets/LinkingHtmlWindow.h"
|
||||||
|
#include "../widgets/ErrorDialog.h"
|
||||||
|
#include "../FileNames.h"
|
||||||
|
|
||||||
#if defined(__WXMAC__)
|
#if defined(__WXMAC__)
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
@ -1098,6 +1102,16 @@ wxString Effect::GetPreset(wxWindow * parent, const wxString & parms)
|
|||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString Effect::ManualPage()
|
||||||
|
{
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString Effect::HelpPage()
|
||||||
|
{
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
bool Effect::IsBatchProcessing()
|
bool Effect::IsBatchProcessing()
|
||||||
{
|
{
|
||||||
return mIsBatch;
|
return mIsBatch;
|
||||||
@ -2604,8 +2618,9 @@ void Effect::Preview(bool dryOnly)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wxMessageBox(_("Error opening sound device. Try changing the audio host, playback device and the project sample rate."),
|
ShowErrorDialog(FocusDialog, _("Error"),
|
||||||
_("Error"), wxOK | wxICON_EXCLAMATION, FocusDialog);
|
_("Error opening sound device.\nTry changing the audio host, playback device and the project sample rate."),
|
||||||
|
wxT("http://manual.audacityteam.org/man/faq_errors.html#sound_device"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2767,6 +2782,7 @@ BEGIN_EVENT_TABLE(EffectUIHost, wxDialogWrapper)
|
|||||||
EVT_CLOSE(EffectUIHost::OnClose)
|
EVT_CLOSE(EffectUIHost::OnClose)
|
||||||
EVT_BUTTON(wxID_APPLY, EffectUIHost::OnApply)
|
EVT_BUTTON(wxID_APPLY, EffectUIHost::OnApply)
|
||||||
EVT_BUTTON(wxID_CANCEL, EffectUIHost::OnCancel)
|
EVT_BUTTON(wxID_CANCEL, EffectUIHost::OnCancel)
|
||||||
|
EVT_BUTTON(wxID_HELP, EffectUIHost::OnHelp)
|
||||||
EVT_BUTTON(eDebugID, EffectUIHost::OnDebug)
|
EVT_BUTTON(eDebugID, EffectUIHost::OnDebug)
|
||||||
EVT_BUTTON(kMenuID, EffectUIHost::OnMenu)
|
EVT_BUTTON(kMenuID, EffectUIHost::OnMenu)
|
||||||
EVT_CHECKBOX(kEnableID, EffectUIHost::OnEnable)
|
EVT_CHECKBOX(kEnableID, EffectUIHost::OnEnable)
|
||||||
@ -3039,9 +3055,24 @@ bool EffectUIHost::Initialize()
|
|||||||
bar->SetSizerAndFit(bs.release());
|
bar->SetSizerAndFit(bs.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
long buttons = eApplyButton + eCloseButton;
|
long buttons;
|
||||||
if (mEffect->mUIDebug)
|
if ( mEffect->ManualPage().IsEmpty() && mEffect->HelpPage().IsEmpty()) {
|
||||||
{
|
buttons = eApplyButton + eCloseButton;
|
||||||
|
this->SetAcceleratorTable(wxNullAcceleratorTable);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buttons = eApplyButton + eCloseButton + eHelpButton;
|
||||||
|
wxAcceleratorEntry entries[1];
|
||||||
|
#if defined(__WXMAC__)
|
||||||
|
// Is there a standard shortcut on Mac?
|
||||||
|
#else
|
||||||
|
entries[0].Set(wxACCEL_NORMAL, (int) WXK_F1, wxID_HELP);
|
||||||
|
#endif
|
||||||
|
wxAcceleratorTable accel(1, entries);
|
||||||
|
this->SetAcceleratorTable(accel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEffect->mUIDebug) {
|
||||||
buttons += eDebugButton;
|
buttons += eDebugButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3203,6 +3234,19 @@ void EffectUIHost::OnCancel(wxCommandEvent & evt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EffectUIHost::OnHelp(wxCommandEvent & WXUNUSED(event))
|
||||||
|
{
|
||||||
|
if (mEffect->GetFamily().IsSameAs(NYQUISTEFFECTS_FAMILY) && (mEffect->ManualPage().IsEmpty())) {
|
||||||
|
// Old ShowHelpDialog required when there is no on-line manual.
|
||||||
|
// Always use default web browser to allow full-featured HTML pages.
|
||||||
|
HelpSystem::ShowHelpDialog(FindWindow(wxID_HELP), mEffect->HelpPage(), wxEmptyString, true, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise use the new ShowHelpDialog
|
||||||
|
HelpSystem::ShowHelpDialog(FindWindow(wxID_HELP), mEffect->ManualPage(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EffectUIHost::OnDebug(wxCommandEvent & evt)
|
void EffectUIHost::OnDebug(wxCommandEvent & evt)
|
||||||
{
|
{
|
||||||
OnApply(evt);
|
OnApply(evt);
|
||||||
|
@ -226,6 +226,11 @@ class AUDACITY_DLL_API Effect /* not final */ : public wxEvtHandler,
|
|||||||
virtual bool HasFactoryDefaults();
|
virtual bool HasFactoryDefaults();
|
||||||
virtual wxString GetPreset(wxWindow * parent, const wxString & parms);
|
virtual wxString GetPreset(wxWindow * parent, const wxString & parms);
|
||||||
|
|
||||||
|
// Name of page in the Audacity alpha manual
|
||||||
|
virtual wxString ManualPage();
|
||||||
|
// Fully qualified local help file name
|
||||||
|
virtual wxString HelpPage();
|
||||||
|
|
||||||
virtual bool IsBatchProcessing();
|
virtual bool IsBatchProcessing();
|
||||||
virtual void SetBatchProcessing(bool start);
|
virtual void SetBatchProcessing(bool start);
|
||||||
|
|
||||||
@ -593,6 +598,7 @@ private:
|
|||||||
void OnApply(wxCommandEvent & evt);
|
void OnApply(wxCommandEvent & evt);
|
||||||
void DoCancel();
|
void DoCancel();
|
||||||
void OnCancel(wxCommandEvent & evt);
|
void OnCancel(wxCommandEvent & evt);
|
||||||
|
void OnHelp(wxCommandEvent & evt);
|
||||||
void OnDebug(wxCommandEvent & evt);
|
void OnDebug(wxCommandEvent & evt);
|
||||||
void OnMenu(wxCommandEvent & evt);
|
void OnMenu(wxCommandEvent & evt);
|
||||||
void OnEnable(wxCommandEvent & evt);
|
void OnEnable(wxCommandEvent & evt);
|
||||||
|
@ -298,6 +298,11 @@ wxString EffectEqualization::GetDescription()
|
|||||||
return XO("Adjusts the volume levels of particular frequencies");
|
return XO("Adjusts the volume levels of particular frequencies");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectEqualization::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Equalization");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectEqualization::GetType()
|
EffectType EffectEqualization::GetType()
|
||||||
|
@ -95,6 +95,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -61,6 +61,11 @@ wxString EffectFindClipping::GetDescription()
|
|||||||
return XO("Creates labels where clipping is detected");
|
return XO("Creates labels where clipping is detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectFindClipping::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Find_Clipping");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectFindClipping::GetType()
|
EffectType EffectFindClipping::GetType()
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -78,6 +78,11 @@ wxString EffectNoise::GetDescription()
|
|||||||
return XO("Generates one of three different types of noise");
|
return XO("Generates one of three different types of noise");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectNoise::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Generate_Menu#noise");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectNoise::GetType()
|
EffectType EffectNoise::GetType()
|
||||||
|
@ -33,6 +33,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -68,6 +68,11 @@ wxString EffectNormalize::GetDescription()
|
|||||||
return XO("Sets the peak amplitude of one or more tracks");
|
return XO("Sets the peak amplitude of one or more tracks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectNormalize::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Normalize");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectNormalize::GetType()
|
EffectType EffectNormalize::GetType()
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -107,6 +107,11 @@ wxString EffectPaulstretch::GetDescription()
|
|||||||
return XO("Use Paulstretch only for an extreme time-stretch or \"stasis\" effect");
|
return XO("Use Paulstretch only for an extreme time-stretch or \"stasis\" effect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectPaulstretch::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Paulstretch");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectPaulstretch::GetType()
|
EffectType EffectPaulstretch::GetType()
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -112,6 +112,11 @@ wxString EffectPhaser::GetDescription()
|
|||||||
return XO("Combines phase-shifted signals with the original signal");
|
return XO("Combines phase-shifted signals with the original signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectPhaser::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Phaser");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectPhaser::GetType()
|
EffectType EffectPhaser::GetType()
|
||||||
|
@ -56,6 +56,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -67,6 +67,11 @@ wxString EffectRepeat::GetDescription()
|
|||||||
return XO("Repeats the selection the specified number of times");
|
return XO("Repeats the selection the specified number of times");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectRepeat::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Repeat");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectRepeat::GetType()
|
EffectType EffectRepeat::GetType()
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
|
|
||||||
wxString GetSymbol() override;
|
wxString GetSymbol() override;
|
||||||
wxString GetDescription() override;
|
wxString GetDescription() override;
|
||||||
|
wxString ManualPage() override;
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
|
@ -153,6 +153,11 @@ wxString EffectReverb::GetDescription()
|
|||||||
return XO("Adds ambience or a \"hall effect\"");
|
return XO("Adds ambience or a \"hall effect\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString EffectReverb::ManualPage()
|
||||||
|
{
|
||||||
|
return wxT("Reverb");
|
||||||
|
}
|
||||||
|
|
||||||
// EffectIdentInterface implementation
|
// EffectIdentInterface implementation
|
||||||
|
|
||||||
EffectType EffectReverb::GetType()
|
EffectType EffectReverb::GetType()
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user