1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-28 16:20:12 +01:00

Update and rename Click Track as Rhythm Track

This commit is contained in:
Steve Daulton
2016-09-29 20:58:44 +01:00
parent e5abdb6b27
commit 52b1c6e00f
3 changed files with 157 additions and 99 deletions

View File

@@ -550,7 +550,6 @@ nobase_dist_pkgdata_DATA = \
nyquist/rawwaves/sinewave.raw \ nyquist/rawwaves/sinewave.raw \
plug-ins/adjustable-fade.ny \ plug-ins/adjustable-fade.ny \
plug-ins/beat.ny \ plug-ins/beat.ny \
plug-ins/clicktrack.ny \
plug-ins/clipfix.ny \ plug-ins/clipfix.ny \
plug-ins/crossfadeclips.ny \ plug-ins/crossfadeclips.ny \
plug-ins/crossfadetracks.ny \ plug-ins/crossfadetracks.ny \
@@ -561,6 +560,7 @@ nobase_dist_pkgdata_DATA = \
plug-ins/lowpass.ny \ plug-ins/lowpass.ny \
plug-ins/notch.ny \ plug-ins/notch.ny \
plug-ins/pluck.ny \ plug-ins/pluck.ny \
plug-ins/rhythmtrack.ny \
plug-ins/rissetdrum.ny \ plug-ins/rissetdrum.ny \
plug-ins/sample-data-export.ny \ plug-ins/sample-data-export.ny \
plug-ins/SilenceMarker.ny \ plug-ins/SilenceMarker.ny \

View File

@@ -2,64 +2,68 @@
;version 4 ;version 4
;type generate ;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin" ;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;name "Click Track..." ;name "Rhythm Track..."
;preview linear ;preview linear
;action "Generating Click Track..." ;action "Generating Rhythm..."
;info "For help, select one of two help screens in 'Action choice' below."
;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"
;; by Dominic Mazzoni, modified by David R. Sky and Steve Daulton. ;; by Dominic Mazzoni, David R. Sky and Steve Daulton.
;; Drip sound generator by Paul Beach
;; 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 .
;; original clicktrack.ny by Dominic Mazzoni,
;; modified by David R. Sky and Steve Daulton.
;;
;; Updated to v4 by Steve Daulton May 2015
;; bug fixes and restructured by Steve Daulton Sept 2011.
;; string input verification added by Steve Daulton, 2009.
;; added click pitch [user request] and sound types fields September 2007 (D.R.Sky).
;; added optional total click track duration field [requested by Mike Mullins]
;; June 2009 (D.R.Sky).
;; added individual click duration field [requested by Quinto Milana]
;; June 2009 (D.R.Sky).
;;
;; Drip sound generator by Paul Beach,
;; used with permission.
;;
;; Thanks very much to Gale Andrews, who gave extensive visual feedback
;; and suggestions!
;control action "Action choice" choice "Generate track, help screen 1, help screen 2" 0
;control tempo "Tempo [beats per minute]" real "30 - 300 beats/minute" 120 30 300 ;control action "Action choice" choice "Generate track, Help screen 1, Help screen 2" 0
;control sig "Beats per measure [bar]" int "1 - 20 beats/measure" 4 1 20 ;control tempo "Tempo (beats per minute)" real "30 - 300 beats/minute" 120 30 300
;control measures "Number of measures [bars]" int "1 - 1000 bars" 16 1 1000 ;control timesig "Beats per measure (bar)" int "1 - 20 beats/measure" 4 1 20
;control click-track-dur "Optional click track duration [minutes seconds]" string "Whole numbers only" "" ;control swing "Swing amount" float "+/- 1" 0 -1 1
;control ticklen "Individual click duration [milliseconds]" int "1 - 100 ms" 10 1 100 ;control measures "Number of measures (bars)" int "1 - 1000 bars" 16 1 1000
;control offset "Start time offset [seconds]" real "0 - 30 seconds" 0 0 30 ;control click-track-dur "Optional rhythm track duration (minutes seconds)" string "Whole numbers only" ""
;control click-type "Click sound" choice "ping,noise,tick" 0
;control q "Noise click resonance - discernable pitch [q]" int "1 - 20" 1 1 20 ;;control ticklen "Individual beat duration (milliseconds)" int "1 - 100 ms" 10 1 100
;control high "MIDI pitch of strong click" int "18 - 116" 92 18 116
;control low "MIDI pitch of weak click" int "18 - 116" 80 18 116 ;control offset "Start time offset (seconds)" real "0 - 30 seconds" 0 0 30
;control click-type "Beat sound" choice "Metronome tick,Ping,Cowbell,Resonant noise,Noise click,Drip" 0
;;control q "Noise click resonance - discernable pitch (q)" int "1 - 20" 1 1 20
;control high "MIDI pitch of strong beat" int "18 - 116" 84 18 116
;control low "MIDI pitch of weak beat" int "18 - 116" 80 18 116
;; allow q control to be commented out.
(if (not (boundp 'q))
(setf q 10))
;; allow ticklen control to be commented out.
(if (not (boundp 'ticklen))
(setf ticklen 10))
;; TODO: Hard code tick length (long and short versions
;; TODO: add drum sounds
(defun help1 () (defun help1 ()
(format nil (format nil
"Click Track Generator help - screen 1 of 2 "Rhythm Track Generator help - screen 1 of 2
Generates a click track at the selected tempo, beats per Generates a rhythm track at the selected tempo, beats per
measure, and either number of measures or track duration, measure, and either number of measures or track duration,
using selected click sound. using the selected sound.
'Tempo': number of beats (clicks) per minute. 'Tempo': number of beats (clicks) per minute.
'Beats per measure (bar)': For example, 3/4 time means one 'Beats per measure (bar)': For example, 3/4 time means one
strong click then two others to form one bar, repeated strong beat then two others to form one bar, repeated
depending on 'number of measures' or 'click track duration'. depending on 'number of measures' or 'rhythm track duration'.
'Optional click track duration': If you enter a value into this 'Swing amount': When set to a non-zero amount, alternate
field, either [minutes seconds] (separated by a space), or beats are delayed or advanced to give a swing feel. At
[seconds], the generated click track will be at or slightly maximum / minimum settings the rhythm plays with triplet timing.
'Optional rhythm track duration': If you enter a value into this
field, either (minutes seconds - separated by a space), or
(seconds), the generated rhythm track will be at or slightly
longer than this duration: the end of the track is extended longer than this duration: the end of the track is extended
into a whole measure if the entered duration does not into a whole measure if the entered duration does not
produce this. Use whole numbers only. produce this. Use whole numbers only.
@@ -67,34 +71,28 @@ produce this. Use whole numbers only.
If you enter a value into this field, the 'number of measures' If you enter a value into this field, the 'number of measures'
value will be ignored. value will be ignored.
To generate click track or view help screen 2, To generate rhythm track or view help screen 2,
restart Click Track and select from 'Action choice'.")) ;end of help1 restart Rhythm Track and select from 'Action choice'.")) ;end of help1
(defun help2 () (defun help2 ()
(format nil (format nil
"Click Track Generator help - screen 2 of 2 "Rhythm Track Generator help - screen 2 of 2
'Individual click duration': the duration of each individual 'Start time offset': makes the rhythm track start at a later
click, minimum of 1 millisecond (ms) to maximum of 100 ms.
'Start time offset': makes the click track start at a later
time than the very beginning (zero seconds), maximum time than the very beginning (zero seconds), maximum
of 30 seconds. of 30 seconds.
'Click sound': choose between ping, noise or tick sound 'Beat sound': choose which sound to use for the beats.
for clicks.
'Noise click resonance': the higher this value, the more 'MIDI pitch of strong/weak beat': MIDI values indicate
clearly noise clicks have a tone. what pitch to use. C-notes are:
'MIDI pitch of strong/weak click': MIDI values indicate\nwhat pitch to use. C-notes are:
24, 36, 48, 60 (middle C), 72, 84, 96, 108. 24, 36, 48, 60 (middle C), 72, 84, 96, 108.
C# (C-sharp) above middle C is 61. C# (C-sharp) above middle C is 61.
To generate click track or view help screen 1, To generate rhythm track or view help screen 1,
restart Click Track and select from 'Action choice'.")) ;end of help 2 restart Rhythm Track and select from 'Action choice'.")) ;end of help 2
;Check function: returns 1 on error ;Check function: returns 1 on error
@@ -159,10 +157,10 @@ restart Click Track and select from 'Action choice'.")) ;end of help 2
" tempo)))) " tempo))))
;beats per measure ;beats per measure
(if (= (check sig 1 20) 1) (if (= (check timesig 1 20) 1)
(setq error-msg (strcat error-msg (format nil (setq error-msg (strcat error-msg (format nil
"Beats per measure ~a outside valid range 1 to 20 "Beats per measure ~a outside valid range 1 to 20
" sig)))) " timesig))))
;number of measures ;number of measures
(if (= (check measures 1 1000) 1) (if (= (check measures 1 1000) 1)
@@ -202,9 +200,9 @@ restart Click Track and select from 'Action choice'.")) ;end of help 2
(not (integerp (first m-s))) ;first is not an integer or (not (integerp (first m-s))) ;first is not an integer or
(and (= (length m-s) 2)(not (integerp (second m-s))))) ;second is not an integer (and (= (length m-s) 2)(not (integerp (second m-s))))) ;second is not an integer
(setq error-msg (strcat error-msg (format nil (setq error-msg (strcat error-msg (format nil
"If used, 'Optional click track duration' must be "If used, 'Optional rhythm track duration' must be
entered as either one number [seconds], or two entered as either one number (seconds0, or two
numbers [minutes seconds] separated by a space. numbers (minutes seconds) separated by a space.
Use whole numbers only.~%")))) Use whole numbers only.~%"))))
;one or two integers ;one or two integers
((and ((and
@@ -219,52 +217,115 @@ Use whole numbers only.~%"))))
(= (check (first m-s) 0 60) 1) ;1st is outside valid range or (= (check (first m-s) 0 60) 1) ;1st is outside valid range or
(= (check (second m-s) 0 59) 1))) ;2nd is outside valid range or (= (check (second m-s) 0 59) 1))) ;2nd is outside valid range or
(setq error-msg (strcat error-msg (format nil (setq error-msg (strcat error-msg (format nil
"~a is outside valid range 0 to [60 59]~%" "~a is outside valid range 0 to (60 59)~%"
m-s))))))) ;end of error checking m-s))))))) ;end of error checking
(defun metronome-tick (hz peak)
(let* ((ln 300)
(sig-array (make-array ln))
(x 1))
;; generate some 'predictable' white noise
(dotimes (i ln)
(setf x (rem (* 479 x) 997))
(setf (aref sig-array i) (- (/ x 500.0) 1)))
(setf sig (sim (s-rest-abs 0.2)
(snd-from-array 0 44100 sig-array)))
(setf sig
(mult (abs-env (pwev 10 (/ ln 44100.0) 2 1 0))
(highpass8 (lowpass2 sig (* 2 hz) 6)
hz)))
(let ((gain (/ (peak sig 300))))
; The '1.11' factor makes up for gain reduction in 'resample'
(mult (abs-env (pwlv 1.11 0.02 1.11 0.05 0 ))
(jcrev (mult peak gain sig) 0.01 0.1)))))
(defun s-rest-abs (d)
(abs-env (s-rest d)))
(defun cowbell (hz)
(sim
(mult (pwev 0.3 0.8 0.0005)
(hzosc hz *tri-table*)
(hzosc (* hz 3.46) *tri-table*))
(mult (pwev 0.7 0.2 0.01)
(hzosc (* hz 7.3) *tri-table*)
(hzosc (* hz 1.52) *tri-table*))))
(defun get-metronome-tick (hz gain)
(resample
(sound-srate-abs 44100 (metronome-tick hz gain))
*sound-srate*))
(defun get-ping (pitch)
(stretch-abs ticklen
(mult
(control-srate-abs *sound-srate* (pwl 0.005 amp 0.995 amp 1))
(osc pitch))))
(defun get-resonant-noise (pitch)
(stretch-abs 0.05 ; 50 milliseconds
(mult
(control-srate-abs *sound-srate* (pwl 0.05 amp 0.95 amp 1))
(normalize (lowpass2 (noise 1) (step-to-hz pitch) 20)))))
(defun get-noise-click (pitch)
(stretch-abs 0.005
(mult
(control-srate-abs *sound-srate* (pwl 0.005 amp 0.995 amp 1))
(normalize (lowpass2 (noise 1) (step-to-hz pitch) 2)))))
(defun get-drip (pitch)
(stretch-abs ticklen
(mult
(control-srate-abs *sound-srate* (pwl 0.005 amp 0.995 amp 1))
(normalize (drip (step-to-hz pitch))))))
(defun get-cowbell (pitch)
(mult 0.8 (cowbell (step-to-hz pitch))))
;Function to make click ;Function to make click
(defun click (type accent) (defun click (type accent)
(setq pitch (if (= accent 1) high low)) (setq pitch (if (= accent 1) high low))
(setq amp (if (= accent 1) 0.75 0.5)) (setq amp (if (= accent 1) 0.75 0.5))
(stretch-abs ticklen
;pwl is used to add 5ms fade-in and fade-out of clicks
(mult
(control-srate-abs *sound-srate*
(pwl 0.005 amp 0.995 amp 1))
(case type (case type
(0 (osc pitch)) ;ping click (0 (get-metronome-tick (step-to-hz pitch) amp))
(1 (normalize (lowpass2 (noise 1) (step-to-hz pitch) q))) ;noise click (1 (get-ping pitch))
(2 (normalize (drip (step-to-hz pitch)))))))) ;tick click (2 (get-cowbell pitch))
(3 (get-resonant-noise pitch))
(4 (get-noise-click pitch))
(t (get-drip pitch))))
;Function to make one measure (defun swing-adjust (i val)
(* val (/ 3.0) (rem (1+ i) 2)))
;Function to make one measure and save it in the global *measure*
(defun makemeasure () (defun makemeasure ()
(setf measure (click click-type 1)) ;accented click (setf *measure*
(dotimes (x (- sig 1)) (sim
(setf measure (sim measure (s-rest (* timesig beatlen)) ;required for trailing silence
(at (* beatlen (+ x 1)) (click click-type 1) ;accented beat
(click click-type 0)))))) ;unaccented clicks (simrep (x (- timesig 1))
(at-abs (* beatlen (+ x 1 (swing-adjust x swing)))
(cue (click click-type 0))))))) ;unaccented beat
;Function to loop measures (defun make-click-track (measures mdur)
(defun loop (bar number sig beatlen) (setf *measure* (set-logical-stop (cue *measure*) (* timesig beatlen)))
(do* ((result bar) ;initialise result (seqrep (i measures) (cue *measure*)))
(count 1 (setq count (1+ count))))
((= count number) result) ;up to number of measures and return result
(setq mtime (* count sig beatlen)) ;set time for next measure
(setf result (sim result (at mtime (cue bar))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; START MAIN PROGRAM ;; START MAIN PROGRAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;view 1 of 2 help screens, or generate click track ;view 1 of 2 help screens, or generate rhythm track
(cond ;'master' cond (cond ;'master' cond
((= action 1)(help1)); display help screen 1 ((= action 1)(help1)); display help screen 1
((= action 2)(help2)) ; display help screen 2 ((= action 2)(help2)) ; display help screen 2
(t ;Run Program (t ;Run Program
(setq len (/ (* 60.0 *sound-srate* sig measures) tempo)) (setq len (/ (* 60.0 *sound-srate* timesig measures) tempo))
(setq error-msg "") ;initialize error-msg (setq error-msg "") ;initialize error-msg
;convert minutes-seconds string to a list ;convert minutes-seconds string to a list
@@ -274,9 +335,9 @@ Use whole numbers only.~%"))))
;run error checks on input values ;run error checks on input values
(errorcheck) (errorcheck)
(if (= (length error-msg) 0) ;if no errors, generate Click Track (if (= (length error-msg) 0) ;if no errors, generate Rhythm Track
(progn (progn
; duration of 1 click, originally statically 0.01 s ; duration of 1 beat, originally statically 0.01 s
(setf ticklen (* (max 1 (min 100 ticklen)) 0.001)) (setf ticklen (* (max 1 (min 100 ticklen)) 0.001))
(setf beatlen (/ 60.0 tempo)) (setf beatlen (/ 60.0 tempo))
@@ -285,24 +346,21 @@ Use whole numbers only.~%"))))
;calculate measures from text input (if used) ;calculate measures from text input (if used)
(if m-s (setq measures (if m-s (setq measures
(/ (m-s-to-seconds m-s)(* sig beatlen)))) (/ (m-s-to-seconds m-s)(* timesig beatlen))))
;if previewing, restrict number of measures ;if previewing, restrict number of measures
(let ((preview (/ (get '*project* 'preview-duration) (let ((preview (/ (get '*project* 'preview-duration)
(* sig beatlen)))) (* timesig beatlen))))
(if (not (get '*track* 'view)) ;NIL if preview (if (not (get '*track* 'view)) ;NIL if preview
(setq measures (min preview measures)))) (setq measures (min preview measures))))
;round up number of measures ;round up number of measures
(setq measures (round-up measures)) (setq measures (round-up measures))
;loop measures ;add time offset and beatlen of silence to rhythm track,
(setf clicktrack (loop measure measures sig beatlen)) (seq
(s-rest offset) ;offset
;add time offset and beatlen of silence to clicktrack, (make-click-track measures (* timesig beatlen)))) ;click track
(seq (s-rest offset) ;offset
(cue clicktrack) ;click track
(s-rest(- beatlen ticklen)))) ;trailing silence
;Else error message ;Else error message
(setq error-msg (strcat (format nil (setq error-msg (strcat (format nil
"Error.~%You have entered at least one invalid value:~%~%") error-msg))))) "Error.~%You have entered at least one invalid value:~%~%") error-msg)))))

View File

@@ -23,7 +23,6 @@ const static wxChar *kShippedEffects[] =
{ {
wxT("adjustable-fade.ny"), wxT("adjustable-fade.ny"),
wxT("beat.ny"), wxT("beat.ny"),
wxT("clicktrack.ny"),
wxT("clipfix.ny"), wxT("clipfix.ny"),
wxT("crossfadeclips.ny"), wxT("crossfadeclips.ny"),
wxT("crossfadetracks.ny"), wxT("crossfadetracks.ny"),
@@ -34,6 +33,7 @@ const static wxChar *kShippedEffects[] =
wxT("lowpass.ny"), wxT("lowpass.ny"),
wxT("notch.ny"), wxT("notch.ny"),
wxT("pluck.ny"), wxT("pluck.ny"),
wxT("rhythmtrack.ny"),
wxT("rissetdrum.ny"), wxT("rissetdrum.ny"),
wxT("sample-data-export.ny"), wxT("sample-data-export.ny"),
wxT("SilenceMarker.ny"), wxT("SilenceMarker.ny"),