Beat Per Minute labels

How do I turn on the Bars and Beats grid?



How do I > Snap > an audio clip to a particular beat?



I saw a Sonar video where they had little grid bars they could grab and move to the start of each note that corrected any sloppy timing.



My song is 140 bpm but I can only snap to whole second…

Audacity does not have any kind of “timing grid” and the “Time Line” only shows hh:mm:ss and not bars:beats (though there is a feature request for this).

Currently, the closest thing to these features in Audacity is to create “Regular Interval Labels”, then audio clips can “snap” to the label positions.

Unfortunately, “Regular Interval Labels” is not a very convenient tool for this job. First you have to convert BPM to “seconds”. Then if you want bars and beats, you need to create two sets of labels - one for the bars and one for the beats. Also there is no provision for “swing”, or tempo changes.

To address these shortcomings, here’s a plug-in that will create labels based on BPM settings.
I think that it is well featured and hopefully it will be obvious how to use it without instructions or help screens.

Note, this is a “Generate” type plug-in and when installed will appear in the Generate menu.
Most plug-ins that create labels are “Analyze” type, but for this plug-in I thought that users may want to create their “timing track” right at the start of a project before any audio tracks have been created. “Generate” plug-ins are the only type that can run without an audio track already existing.
Also, by making this a Generate plug-in, the start point of the labels can be set by clicking on an existing track (with or without a selected region), whereas Analyze plug-ins are not available unless there is a selected region. (see here for additional comments on this “feature” Nyquist Wish List )

Before anyone asks, no it does not extract the BPM from an existing audio track. BPM detection is another project and not currently good enough to provide accurate timing data for making BPM labels. This may come in a future version, but that’s still a long way off.

Any other comments, questions, suggestions or other feedback are very welcome.

This plug-in requires a recent version of Audacity 1.3.x
See here for installation instructions. https://manual.audacityteam.org/man/installing_effect_generator_and_analyzer_plug_ins.html
bmp-labels.ny (3.66 KB)
Latest version:
[u]Download latest version[/u]

The basic features seem to work correctly (which is all I personally need). I’m sure you’ve noticed the typo already (“Peats”). The default value for the number of bars ought to be 16, as that’s the value used for click track as well. Speed up/down might need some documentation, as I don’t think I’ll still know what it does in a few weeks. And I suppose you can remove the randomized beats altogether (I simply can’t think of any situation when this would come in handy). Nevertheless, this is a very useful plug-in which I can see myself using quite a bit in the future.

However when comparing the labels and a click track at 130 bpm I noticed that they are slightly different. At first I thought your plug-in was wrong, but after a closer I look I realized it’s the click track itself. It basically gets worse after every measure whereas the beats within the measures are correct (they are off just as well as the entire measure, but they don’t add anything to the problem).

I could fix this by replacing

(dotimes (x (- measures 1))
  (setf result (seq result measure)))

with:

(dotimes (x (- measures 1))
  (setf result (sim result(at (* (+ x 1) sig beatlen) (cue measure)))))

So instead of sticking all measures together I added the current result and a measure at the next position and made that the new result. Maybe there are better ways to do this though.

Of course these are just minor differences (there are no differences at all on 120 bpm), but still, 16 ms difference after 5 minutes for four beats per measure is quite formidable in my opinion.

Thanks - fixed that.

I’ve also noticed that there’s a division by zero error if the number of bars is set to 1, so I’ll need to fix that also.

Or we could change the default in Click Track to 8 :wink:
In most cases I’d expect that the user would set this value to suit there needs and using the default would be pretty rare.

If I was going to explain that I’d just say that it makes the tempo speed up or slow down by the specified number of beats per minute - which is pretty well what the control says.
I suppose it’s not obvious that the speed changes from bar to bar rather than from beat to beat (so the tempo within any one bar is constant). I don’t think that it justifies a built-in help screen but I’ll add a text file with some documentation. The “Swing” and “Randomize” settings may also be worth a note.

:astonished:

The problem is line numbers 272 - 273.

(setf measure (sim measure
                   (stretch-abs (* sig beatlen) (const 0.0))))

(stretch-abs) performs a linear time transformation to make 1 second of silence (created at the control sample rate) stretch (approximately) to the length of the bar, but depending on the precise bar length and sample rate, the final (stretched) length may not be exact.

A more accurate method would be to use (s-rest [duration]) to generate silence of the required length, so those lines would become:

(setf measure (sim measure (s-rest (* sig beatlen))))

Because s-rest is generated at the current sound sample rate it will be accurate to within 1 sample (per bar).
This gives an accuracy at 130 bpm, 1 beat per bar, of about 2 ms over a 5 minute track at 48 kHz.

I think the worst case scenario should be if the tempo were such that the bar length fell in the middle between 2 samples. This would give an error of 0.011337868 ms per bar at a sample rate of 44100 Hz.

I’d say that it was pretty tiny (about 0.0023%), but for some tempos it can be worse (129 bpm with 1 beat per bar at 48kHz sample rate gives an error of over 0.12 seconds) and its better if it’s right.

Something like this is probably the neatest solution as it avoids cumulative errors altogether. Looking back to lines 272 - 273 we see that these lines are now redundant as we are not using the length of the measure to set the start position of the next measure.
The only drawback to this is that we then loose the trailing silence at the end of the track, so we could add that on at the end by replacing:

(setf result (if (= offset 0) result
(sim (s-rest offset) (at-abs offset (cue result)))))

; return [click track] result
result

with

(seq (s-rest offset)(cue result)(s-rest(- beatlen ticklen)))

as this returns the final click track the last couple of lines are not required.

David’s code is probably not the best example of code formatting - he did not tend to use line indentations because he was blind. While trying to unravel his code I’ve added some indentations which will hopefully make it a little easier to follow. I’ve also restructured his error checking code so that it’s no longer checking double negatives. The only other change that I’ve made is to remove “0 0” from the start of two (pwl) functions as t=0 l=0 is implicit with (pwl).

The only change that I made to your code was to use (1+ x) rather than (+ x 1).

I’ve attached a revised version, renamed as clicktrack2.ny. The changes have turned out to be somewhat more extensive than I originally intended so it would be helpful if it could be tested by as many people as possible - particularly the error checking aspects. This effect will be listed as “Click Track 2…” so that it can be installed alongside the original version.
clicktrack2.ny (9.74 KB)

And here’s the fixed version of bpm-labels.ny
bmp-labels.ny (3.63 KB)

Thanks, Steve.

I had a casual test. It seems much more accurate in length generation than the old Click Track. I did not find any cases that were too long, but some were one or two samples too short unless 8000 Hz was used.

I noticed it errored on double positives but not single positives.

I guess we should take the opportunity as per current conventions to trim the licence in the ;info line to “Released under GPL v2.” and add the following to the comments:

;; Released under terms of the GNU General Public License version 2:
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html .

Would this be an opportunity to allow fractional BPM in the Tempo field, given people are asking for the built-in Change Speed and Change Tempo to support this? If not, perhaps the Help should state this is not supported?

PS I notice crossfadeout.ny and crossfadein.ny are not licensed at all (nor clipfix.ny, but I don’t know if I can contact Ben to ask him about that). So should we add the above GPL comment to those two crossfades?



Gale

As both of these are basically just one line of code I’d guess that when written it wasn’t considered worth the space.
I suppose that strictly speaking they should carry a GPL comment. Even if we replace these effects I’d expect that we’d keep an archive copy on the wiki, so if you’re able to get hold of Ben then that would be best. I don’t know where these effects came from initially, but as they are bundled with Audacity I would have thought that there must have been at least an implied agreement that they were GPL.

Yes.

I don’t see any problem with that.

We’ve drifted some way off the original topic so I’ve started a new topic about Click Track here: Inaccuracy in Click Track

Sure, but I think someone could question if most plug-ins are GPL and a few aren’t, what the licence of the unlicensed plug-ins actually is. The two crossfades were added by Dominic originally, so I assume he wrote them, but I don’t know. I’ll ask him if we can include the two comment lines to make the plug-ins GPL.

Clip Fix definitely isn’t GPL, but Ben agreed to have it included in Audacity and let anyone modify or distribute it, without wanting to tie the licence down or make the terms explicit in the plug-in. That isn’t ideal, but I’ve reached him today and he is now very happy to make the plug-in GPL so that anyone can openly work on improving it. I pointed him to the main discussion thread we had on improving it:

Gale

Back to BPM labels.

The only bug I could spot is the following. When setting “Bars (only)” at Label Text it will not put anything in the labels (similar to selecting “none”). This worked correctly in your first version though, sneaky bugs.

It has also come to my mind that an option to put markers/labels at bars only might come in handy. This way one can combine a click track and BPM labels to select bars easily without too many markers and still get to the individual beats just by looking at the click track. Additionally it could be useful to be able to define an offset as right now the labels always start at the origin.

Thanks for testing, I’ll check that out tonight.

Same as “Beats per bar = 1” ?

Labels always start at the Cursor position, or the start of the selection, or at time=0 if there none selected. This was one of the main reasons for making it a Generator plug-in (see first topic post for explanation).

Almost, however when setting beats per bar to 1 I need to set the BPM to 1/4 for a song with actually 4 beats per bar. It’s possible, but not as convenient.

You are right. I think in my initial tests I started with no tracks at all and set a marker at a certain time, then created labels and saw them appear at 0. But with an existing track it will work just fine. I do believe however that there shouldn’t be an offset option for the click track plug-in then. I like to see both plug-ins being kind of symmetrical when it comes to these things. Everything tidied up. :slight_smile:

Doh!
Line 56:

		(1 (if (= beat 0)(format nil "~a" bar)""))

should be:

		(1 (if (= beat 1)(format nil "~a" bar)""))

The previous version counted beats from 0, but the new version counts from 1

I’ve attached the fixed version.

There’s always a delicate balance between functional simplicity vs. additional features.
I’m sure that there’s also a case for adding markers at other divisions, such as half-beats and 1/4 beats.
I don’t think that it would be difficult to code. I’ll consider a multi-choice option:
“Create Labels at:” [choices: whole bar, whole beat, 1/2 beat, 1/3 beat, 1/4 beat]
Any need to go smaller than 1/4 beat? Would marking 1/16th beats be overkill for everyone?
Labels every other beat (minim beats) could be useful if the time signature is 4/4, but a bit daft if there’s 3 beats to the bar.
Your thoughts?

Personally I’ve never found a use for the “Start time offset”, though it is useful for VIPs (visually impaired persons) as they would have difficulty navigating to a specific point on the time line. It would be a lot easier for a VIP to set the cursor at zero and type a start time offset.

With the BPM labels the situation is different. Firstly I don’t imagine that VIPs will find much use for BPM labels. Also, as “BPM Labels” is concerned with (bars/beats) tempo, rather than (mm:ss) time, if there was an offset option then it would make sense for that to be to offset by so many bars and beats rather than by a time value. Quickly without the aid of a calculator - how many bars and beats for a 5 second offset at 130 bpm 4/4 time?
bmp-labels.ny (3.63 KB)

The options you’ve written in bold should be more than enough. If there ever was any need for labels in a pattern less than 100 ms apart (which I suppose is quite rare) it is still possible to just increase the tempo to get a minimum distance of 50 ms. If even this isn’t enough then there is still the regular interval label option.

As for labels at every other beat. If you were to put a label at 2 and 4 only you could just place labels at 1 and 3 with an offset (the bar label excluded). Well, it’s not possible to make have labels at 1-3 only with the current plug-in, but actually I doubt being able to do this would do any good. It creates all kinds of different situations with different beats per bar. This is one of the cases in which I do think that it’s probably better to just calculate a new tempo.

Sounds reasonable. Clicking at the right spot is surely more convenient.

Subdividing beats has been added as an option in this version.
The sub-divisions are always an exact fraction of the beat length regardless of “swing”, “randomization” or tempo change.
bmp-labels.ny (4.61 KB)

I can see a version of that done by tapping on your microphone to the beat of a song and capture it in Overdubbing. That should be a simple matter of counting the waves over a certain level and appropriate maths – extrapolating to a minute and divide. The setup for that would be strenuous, but it would work and the programming shouldn’t be that hard.

We could tell people there was a reliable way to do it in Audacity.

Can I assume the worst problem of BPM is finding the beats? I know of a great many songs that have a bridge or other interruption in the beat progression making it a nightmare to get software to do it. Also, anything with a backbeat or secondary beat would drive the system crazy – all this in addition to the mentioned artistic expression.

But not if you do it tapping a pencil on your mic. That’s pretty simple.

Koz

Yes.

Yes that is much easier, though unfortunately it cannot be done in real time - the “tapping” track would need to be recorded then analyzed.
On my laptop, if I tap on the case and record with the internal microphone, then normalize to 0 dB, “Analyze > Beat Finder” set to “Threshold 30%” provides reliable results:
tracks000.png

I expect this Feature Request would like it to be done in real time (or apparently so in the background), otherwise it hardly seems worth doing. I assume this requires a built-in tool, not Nyquist.

For example, Audacity pops a progress message when it has enough data to analyze then gives you the BPM and puts the measures on the Timeline (if that is part of the feature).


Gale

though unfortunately it cannot be done in real time

Where is it written you have to play the song in Audacity? Play it in Windows Media or VLC Player, QuickTime Player or iTunes and tap with your pencil into a recording. Run the algorithm and poof: BPM.

Koz

I agree with Gale that there is demand for a “real time tool” - open a dialogue window, tap your pencil, and it outputs shows the BPM in real time, then (optionally) creates a label track or sets the time-line to bars and beats with the appropriate BPM. Yes, that would have to be built in (or perhaps a “module”, though “modules” do not look like an attractive proposition unless they are officially included in the standard Audacity release, which currently no modules are.)

Yes, recording a “tap” track (in whatever way) and analyzing that, is a beautifully simple and effective workaround, though that does not preclude improving beat detection for music.

Yes, recording a “tap” track (in whatever way) and analyzing that, is a beautifully simple and effective workaround, though that does not preclude improving beat detection for music.

I understand. Baby steps.

Another semi-real time possibility is Audacity creates a “beat track” and then measures it. Audacity taps the pencil. The ticks in the beat track can be examined to make sure Audacity is getting the rhythm from the same musical notes you are.

Koz

Sorry for refreshing a very old topic but I guess someone from here might help me with my question.

I am looking for a way to see a selected part of a track’s bpm.

For example I have a 2 hours of electronic music set, I will open this big file with and select 30 seconds part of it and want to see just one approximate bpm value like 115bpm… (Calculated from that 30 seconds of selection)

Is this possible ?