1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 23:59:37 +02: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 \
plug-ins/adjustable-fade.ny \
plug-ins/beat.ny \
plug-ins/clicktrack.ny \
plug-ins/clipfix.ny \
plug-ins/crossfadeclips.ny \
plug-ins/crossfadetracks.ny \
@ -561,6 +560,7 @@ nobase_dist_pkgdata_DATA = \
plug-ins/lowpass.ny \
plug-ins/notch.ny \
plug-ins/pluck.ny \
plug-ins/rhythmtrack.ny \
plug-ins/rissetdrum.ny \
plug-ins/sample-data-export.ny \
plug-ins/SilenceMarker.ny \

View File

@ -2,64 +2,68 @@
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;name "Click Track..."
;name "Rhythm Track..."
;preview linear
;action "Generating Click Track..."
;info "For help, select one of two help screens in 'Action choice' below."
;action "Generating Rhythm..."
;author "Dominic Mazzoni"
;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:
;; 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 sig "Beats per measure [bar]" int "1 - 20 beats/measure" 4 1 20
;control measures "Number of measures [bars]" int "1 - 1000 bars" 16 1 1000
;control click-track-dur "Optional click track duration [minutes seconds]" string "Whole numbers only" ""
;control ticklen "Individual click duration [milliseconds]" int "1 - 100 ms" 10 1 100
;control offset "Start time offset [seconds]" real "0 - 30 seconds" 0 0 30
;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 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 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 timesig "Beats per measure (bar)" int "1 - 20 beats/measure" 4 1 20
;control swing "Swing amount" float "+/- 1" 0 -1 1
;control measures "Number of measures (bars)" int "1 - 1000 bars" 16 1 1000
;control click-track-dur "Optional rhythm track duration (minutes seconds)" string "Whole numbers only" ""
;;control ticklen "Individual beat duration (milliseconds)" int "1 - 100 ms" 10 1 100
;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 ()
(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,
using selected click sound.
using the selected sound.
'Tempo': number of beats (clicks) per minute.
'Beats per measure (bar)': For example, 3/4 time means one
strong click then two others to form one bar, repeated
depending on 'number of measures' or 'click track duration'.
strong beat then two others to form one bar, repeated
depending on 'number of measures' or 'rhythm track duration'.
'Optional click track duration': If you enter a value into this
field, either [minutes seconds] (separated by a space), or
[seconds], the generated click track will be at or slightly
'Swing amount': When set to a non-zero amount, alternate
beats are delayed or advanced to give a swing feel. At
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
into a whole measure if the entered duration does not
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'
value will be ignored.
To generate click track or view help screen 2,
restart Click Track and select from 'Action choice'.")) ;end of help1
To generate rhythm track or view help screen 2,
restart Rhythm Track and select from 'Action choice'.")) ;end of help1
(defun help2 ()
(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
click, minimum of 1 millisecond (ms) to maximum of 100 ms.
'Start time offset': makes the click track start at a later
'Start time offset': makes the rhythm track start at a later
time than the very beginning (zero seconds), maximum
of 30 seconds.
'Click sound': choose between ping, noise or tick sound
for clicks.
'Beat sound': choose which sound to use for the beats.
'Noise click resonance': the higher this value, the more
clearly noise clicks have a tone.
'MIDI pitch of strong/weak click': MIDI values indicate\nwhat pitch to use. C-notes are:
'MIDI pitch of strong/weak beat': MIDI values indicate
what pitch to use. C-notes are:
24, 36, 48, 60 (middle C), 72, 84, 96, 108.
C# (C-sharp) above middle C is 61.
To generate click track or view help screen 1,
restart Click Track and select from 'Action choice'.")) ;end of help 2
To generate rhythm track or view help screen 1,
restart Rhythm Track and select from 'Action choice'.")) ;end of help 2
;Check function: returns 1 on error
@ -159,10 +157,10 @@ restart Click Track and select from 'Action choice'.")) ;end of help 2
" tempo))))
;beats per measure
(if (= (check sig 1 20) 1)
(if (= (check timesig 1 20) 1)
(setq error-msg (strcat error-msg (format nil
"Beats per measure ~a outside valid range 1 to 20
" sig))))
" timesig))))
;number of measures
(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
(and (= (length m-s) 2)(not (integerp (second m-s))))) ;second is not an integer
(setq error-msg (strcat error-msg (format nil
"If used, 'Optional click track duration' must be
entered as either one number [seconds], or two
numbers [minutes seconds] separated by a space.
"If used, 'Optional rhythm track duration' must be
entered as either one number (seconds0, or two
numbers (minutes seconds) separated by a space.
Use whole numbers only.~%"))))
;one or two integers
((and
@ -219,52 +217,115 @@ Use whole numbers only.~%"))))
(= (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
(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
(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
(defun click (type accent)
(setq pitch (if (= accent 1) high low))
(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
(0 (osc pitch)) ;ping click
(1 (normalize (lowpass2 (noise 1) (step-to-hz pitch) q))) ;noise click
(2 (normalize (drip (step-to-hz pitch)))))))) ;tick click
(case type
(0 (get-metronome-tick (step-to-hz pitch) amp))
(1 (get-ping pitch))
(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 ()
(setf measure (click click-type 1)) ;accented click
(dotimes (x (- sig 1))
(setf measure (sim measure
(at (* beatlen (+ x 1))
(click click-type 0)))))) ;unaccented clicks
(setf *measure*
(sim
(s-rest (* timesig beatlen)) ;required for trailing silence
(click click-type 1) ;accented beat
(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 loop (bar number sig beatlen)
(do* ((result bar) ;initialise result
(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))))))
(defun make-click-track (measures mdur)
(setf *measure* (set-logical-stop (cue *measure*) (* timesig beatlen)))
(seqrep (i measures) (cue *measure*)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
((= action 1)(help1)); display help screen 1
((= action 2)(help2)) ; display help screen 2
(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
;convert minutes-seconds string to a list
@ -274,9 +335,9 @@ Use whole numbers only.~%"))))
;run error checks on input values
(errorcheck)
(if (= (length error-msg) 0) ;if no errors, generate Click Track
(if (= (length error-msg) 0) ;if no errors, generate Rhythm Track
(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 beatlen (/ 60.0 tempo))
@ -285,24 +346,21 @@ Use whole numbers only.~%"))))
;calculate measures from text input (if used)
(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
(let ((preview (/ (get '*project* 'preview-duration)
(* sig beatlen))))
(* timesig beatlen))))
(if (not (get '*track* 'view)) ;NIL if preview
(setq measures (min preview measures))))
;round up number of measures
(setq measures (round-up measures))
;loop measures
(setf clicktrack (loop measure measures sig beatlen))
;add time offset and beatlen of silence to clicktrack,
(seq (s-rest offset) ;offset
(cue clicktrack) ;click track
(s-rest(- beatlen ticklen)))) ;trailing silence
;add time offset and beatlen of silence to rhythm track,
(seq
(s-rest offset) ;offset
(make-click-track measures (* timesig beatlen)))) ;click track
;Else error message
(setq error-msg (strcat (format nil
"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("beat.ny"),
wxT("clicktrack.ny"),
wxT("clipfix.ny"),
wxT("crossfadeclips.ny"),
wxT("crossfadetracks.ny"),
@ -34,6 +33,7 @@ const static wxChar *kShippedEffects[] =
wxT("lowpass.ny"),
wxT("notch.ny"),
wxT("pluck.ny"),
wxT("rhythmtrack.ny"),
wxT("rissetdrum.ny"),
wxT("sample-data-export.ny"),
wxT("SilenceMarker.ny"),