rounding error on label import

That’s a good subject line, right? I always like people to know what it is about.

It doesn’t round, it truncates. I like to use labels to figure out how I want to break up a wave into tracks for burning to CD days before I actually want to use disk space to ‘Export Multiple’. I am running into problems with the labels, one of which is that on export, it does not save the file as a text file; I have to include the extension manually in the name. While on import it looks for text files. Not a big problem, but it suggests that this area is not a focus of development. I understand that not everything can be at once, that’s just how it is. However, I suppose the squeaky wheel gets the grease and you need feedback from users to determine what needs attention. So here it is.

So I am using labels to break the wave into frames which are 1 / 75 th of a second.
Each succeeding frame looks like this:

0.000000
0.133333
0.266667
0.400000
0.533333
0.666667
0.800000
0.933333
0.106667
0.120000
0.133333
0.146667
0.160000
0.173333
0.186667
0.200000
. . .
0.920000
0.933333
0.946667
0.960000
0.973333
0.986667

So the last 4 digits end in 0000, 3333, or 6667. Since it truncates, the last four digits must end in 0000, 3334, or 6667 to prevent rounding errors one-third of the time. I edit them manually. It could be fixed either by adding 0.000001 to the numbers instead of rounding normally when the file is created or by actually rounding when importing the file. Probably changing how the file is created on export is easier and changing what the program does when importing labels is more correct.

It’s easy enough opening a text file and changing the last 3’s to 4’s, but I thought I’d mention it to you.

Stephen

I’ve only tested this on Linux but the default file name that I get is “labels.txt”.

Regarding rounding errors, I’m not sure that this should be a problem.
As you rightly say, a CD frame is 1/75 th of a second, and as I understand it a CD track mark must always land on a frame boundary, so if you try to set a track mark at 5.01 seconds, then the track mark will actually be placed at 5 and 1/75 seconds as that is the closest frame boundary.

Trust Me, in Windows the default name is labels with no extension added.

When I Import a label, it looks for files with the extension .txt. I have to choose ‘all files’ to see the files with no extension that gets saved by default. On import labels, it does not round, it truncates to the last sample. I do in fact edit my files so that where is ends in 0.003333 seconds, it will end in 0.003334 seconds instead. So yes, all I have to do is round up so that the truncate works properly. But of course it should not truncate at all.

f you try to set a track mark at 5.01 seconds, then the track mark will actually be placed at 5 and 1/75 seconds as that is the closest frame boundary.

Oh, now I see what you mean. But is does so by padding the end of the track with silent samples. I don’t want my burning program to do any padding at all, so I have to make sure that I am saving all my waves at frame boundaries in the first place. So I must place the labels at those boundaries precisely down to the last sample. The last sample will get chopped off whenever I re-import my labels whenever the second decimal end in 3’s.

Furthermore, whenever I have snap to frame enabled, I can’t even select the area properly, because it won’t allow the selected area to end on a label if the label is not place on a frame boundary. It is only a problem because I am trying to be accurate to the last sample.

As minor a problem as it is, I think everyone will agree that ideally it shouldn’t truncate on import when it rounds down on export. If is always rounded up on export, then it would not be a problem to truncate on import. So that I think is the easiest solution.

Stephen

I don’t doubt you, but which Audacity and which Windows?

Then surely the worst thing that could happen would be that a label position is rounded up (as that could push it over the frame boundary causing the burning program to pad up to the next frame boundary)?

I am using Audacity 1.3.12.

OK, let’s say I export two label positions:

02:30:50 and 05:00:25

In the label file this will be saved as seconds and fractions of seconds:

150.666667
300.333333

Upon importing the file, the number of samples in each track will be determined by the equation: s times 44100.

664440 and 13244700

But however, actually 300.333333 times 44100 equals 13244699.9853 now if this is truncated what happens?
You lose a sample.
On the other hand 150.666667 times 44100 equals 6644400.0147
and 300.333334 times 44100 equals 13244700.0294
What happens when these are truncated?

So truncation on import is OK if everything is rounded up no matter what when the label file is being created.

I just tested it and Audacity 1.2.6 does not have the problem. Only the Beta version.

If you are not following the developer’s discussion about the general topic of sample level accuracy (including talk about this rounding issue) you might be interested in reading it here:
http://audacity.238276.n2.nabble.com/Sample-level-time-accuracy-td5524594.html#a5524594
and a new offshoot:
http://audacity.238276.n2.nabble.com/WaveClip-mis-reporting-start-time-td5552788.html#a5552788

I started a conversation about this a while back with one of the Developers but quickly realized that I was in over my head! The real problem is that Audacity stores and displays everything as floating point numbers related to time not sample. This makes some sense when you consider that a project might have some samples at one rate (f.i. 44100) in one wavetrack and others at another (f.i. 48000) in a different track. Given all the various possible sample rate do note have the same “least common denominator” Audacity is always going to be faced with fractional math even if everything was sample based. Given that, there will always be the possibility of rounding errors.

There is no way that Audacity would be re-written to do away with floating point time and move to sample accuracy–it would require a massive change in the code-base and most users are doing time-based editing anyway, not sample accurate manipulation.

A number like 13244699.9853 should still be rounded up to 13244700. Instead it is treated like the integer 13244699; the part after the decimal is thrown away.

The real problem is that Audacity stores and displays everything as floating point numbers related to time not sample.

I know. If you take the floating-point representation of the time in seconds and multiply it by the sample-rate you will get the number of samples. If you multiply exactly 300 and a third seconds by 44100, you get 13244700. If you store only six parts of the fraction like this 300.333333, you get 13244699.9853. So I was doing that; I recognized that the label positions were stored in seconds in the exported label files. But on import, if Audacity 1.3.12 does not round up, as it does not, it gives me the wrong number of samples. In this instance, I aim to be accurate to the last sample.

I fix this by editing the files; changing 300.333333 to 300.333334. 300.333334 times 44100 equals 13244700.0294. This will both round or truncate back to the right number. So what’s broken is that it is not rounding up to the nearest sample. I believe the labels always have to be attached to a sample. One third of a second is a rational number, but it can’t be represented with total accuracy with a floating-point number. A famous way to avoid rounding is to add 0.0000005 to the number of seconds before storing the floating-point number in the format 0.000000. Then later on you could truncate and get the same result as if you had rounded. This is a trick in computer programming.

Generate a second of tone, click anywhere and zoom in to maximum. You can place a label anywhere between the sample points. For example, I was able to position a label at these three time points which were all between the same two sample dots.

Seconds    Samples
0.203403	8970.072300
0.203412	8970.469200
0.203422	8970.910200

So these three label positions were all between samples 8970 and 8971. Truncating to 8970 makes as much sense as rounding.

One-ninth of a second is also a rational number, but 44100 is not evenly divisible by 9, so if one asks for one-ninth of a second of audio sampled at 44100 one is asking for a fraction of a sample. It just so happens that 44100 is evenly divisible by 3.

– Bill

One-ninth of a second is also a rational number, but 44100 is not evenly divisible by 9, so if one asks for one-ninth of a second of audio sampled at 44100 one is asking for a fraction of a sample. It just so happens that 44100 is evenly divisible by 3.

It just so happens that 44100 is evenly divisible by 75. That is the point. I am talking about making AudioCd s. There is no question of actual fractions of a sample if I want to place my labels squarely on Cd frame divisions. Only the lack of rounding when re-importing lablels creates a problem. When I first place them, they are exactly where I want them; when I import them later, they are one sample off. I already pointed out that 75ths end in 0, 6, or 3. One-third of the time no rounding is needed, one-third of the time it rounds down, and one-third of the time it rounds up. A single sample off is not important except for it not behaving as expected. Let’s say you have snap-to CDDA frames enabled and you create labels that way. Later after importing the labels back, if snap-to CDDA frames is still enabled, if you try to select between labels it won’t stop at the second label if it is not on a CDDA frame as it originally was when it was created. This became a puzzle which I have investigated, discovering that one-third of the time the label won’t stay where it was put due to the new behavior of truncation instead of rounding.

I’ve just tested this with Audacity 1.3.12 on Windows Vista Home Basic and the default file name was “labels.txt” :confused:

I’m still not clear what the problem is. Could you give a step-by-step method to produce the problem.

I am looking for a better way to state the problem.

I want to use labels to Export Multiple such that each labeled track will have samples divisible by 588.

If I create labels with snap-on CDDA frames on, export the labels and import them back into the same session, there are places where parallel labels will be offset by one sample. Making the samples in each track not divisible by 588 if I use the imported labels.

OK, can someone confirm that labels do get attached to samples?
Well I guess they have to, but perhaps it would be more accurate to state that when a label is selected, the insertion point in the audio track will start at a specific sample. Perhaps that does not affect the placement of labels on the label track?
Nevertheless, an effort should be made to increase the accuracy of the correspondence between the original label track and its imported version. I assume the original labels have double precision and so they cannot be the same because the text file for the imported labels only stores the labels with single float precision.

So again the only way to increase accuracy is either to move to the next sample when the insertion point into the audio is past the halfway point between samples or to add .000001 to a truncated float when the sixth part of the decimal is not zero. Like 1.240000, 1.253334, and 1.266667. Well the math still isn’t right. Because it is predicated on the assumption that the sample rate will be 44100?
I guess the first option is the only one that will work for any random sample rate. I hope it is not annoying that I am focusing on CDDA audio to the exclusion of all others. It is the only case I can think of where “sample-level accuracy” may be important. In the case of using CDDA frames, I think it is safe to assume that the audio must be CDDA compatible audio was well, however.

Thanks for your input Steve. I hope this clarifies the problem. I suppose saying I create a label track, export it, and import it in the same session, so that I have what should be two identical label tracks but are not is a step by step account?

When I export a label the default label name is ‘label’. Then when I try to import it, it looks for a file with a .txt extension, but it does not show. Instead it was saved without any extension. In Windows applications are required to provide the extension it expects to see when opening a file when the file is saved, not the user. The extensions are supposed to be mostly transparent to the user. I am running Audacity 1.3.12 on Windows Vista Home Premium. I just tried it again. I have been double checking to make sure what I am saying is accurate.

It’s some of the steps.

Here’s what I’m getting:

  1. Open a new Audacity project.
  2. Generate 40 frames of a sine tone.
  3. Select CDDA frames and enable Snap to.
  4. Select the first 10 frames, press Ctrl+B and enter “1” as the label text (frames 0 to 10)
  5. Select the next 10 frames, press Ctrl+B and enter “2” as the label text (frames 10 to 20)
  6. Select the next 10 frames, press Ctrl+B and enter “3” as the label text (frames 20 to 30)
  7. Select the next 10 frames, press Ctrl+B and enter “4” as the label text (frames 30 to 40)
  8. File menu > Export Multiple (16 bit WAV and all other settings at default)
  9. Import files 1.wav, 2.wav,.wav and 4.wav
  10. Drag the clips 2.wav, 3.wav and 4.wav into the same track as 1.wav and compare with the original track.

As can be seen, each wav file is exactly in line with the label and each split is exactly on a frame boundary.
(only one split position shown, but the others are the same.)
fullwindow000.png

I’m not seeing this problem with 1.3.13 alpha Oct 1 Mac PPC.

    1. generate 10 seconds tone
  1. set snap to CDDA frames
  2. put labels at 100 frames, 275 frames, 450 frames and 562 frames
  3. export labels
  4. import labels

The imported labels line up exactly with the original labels.
tracks000.png
– Bill

Steve, I am talking about exporting and importing labels and you’d have to choose the label positions more randomly than that. billw58 followed the directions correctly in that he did export and import the same labels during the same session except that again, they fail to line up only one-third of the time and he did not choose his points randomly enough. And after that you’d have to switch from frame to sample view to check whether the two label tracks are not off by one sample sometimes.

The reason I started out by showing length in seconds or successive frames is to reveal the 0, 3, 6 pattern with the ones ending in 3 being the only ones that must be rounded up to be right; truncating and rounding down results in the same thing, so when it should round down anyway, you won’t see any difference.

I’ll double check what you did anyway to see if I get the same result.

Comparing the label tracks I get the following sets of data: 5880:5879; 11760:11760; 17640:17640; 23520:23519.

And copying the contents of label.txt (which did automatically save as a text file?!!):

0.133333	0.133333	1
0.266667	0.266667	2
0.400000	0.400000	3
0.533333	0.533333	4

So only label 1 and 4 (according to me) are short one sample. Do you see the pattern? I don’t see why you don’t get the same results. The problem only crops up in the beta version of the program by the way. Perhaps 1.3.13 will fix the problem?

Comparing the labels of billw58 I get the following data sets: 58800:58799; 161700:161700; 264600:264600; 330456:330455.

And the contents of label.txt looks like:

1.333333	1.333333	100 frames
3.666667	3.666667	275 frames
6.000000	6.000000	450 frames
7.493333	7.493333	562 frames

Interesting, the exact same pattern persists.

OK that is as clear as can be. My solution has been to open the label.txt file and change 1.333333 to 1.333334 etc. And that works fine. So it is not a gigantic problem. I just like the challenge of communicating the ideas.

Apparently this little discrepancy which is basically in the time-line due to the different resolutions of float vs double (a number like 1.333333 is not a double precision representation of 1 and a third, right?) has been fixed in the new beta version 1.3.13. so next I’ll just upgrade Audacity and this specific problem which does not affect very many people anyway will probably go away. (The word ‘probably’ never looks like it is spelled right to me. ‘Pro Barbara -ly’?) PPS (Babs is a nickname for Barbara)

It is really ironic that I brought this up right on the cusp of the newer Beta version of Audacity. Or is it actually still in Alpha? I don’t want to steer anybody wrong.

edit

OK, so it is in Alpha. How do I get it?

What exactly are you doing there?

I’ve also repeated Bills test with Audacity 1.3.12 beta and I get the same results as Bill.

I suspect it’s because there is some small detail in your method that you’ve not yet told us about.

You can download the alpha version for Windows from here: http://wiki.audacityteam.org/index.php?title=Nightly_Builds#Windows_Binaries

Note that the alpha “nightly builds” are not official releases and are not recommended for a production environment. They are made available primarily for testing.
Because of the current stage of Audacity 1.3.x development they are usually pretty stable and may even contain bug fixes and quality enhancements that are not yet in the beta version, however it’s in the nature of alpha releases that sometimes they will be broken.

When reporting bugs in alpha versions of Audacity it is particularly important to give precise details. For example, look in the Audacity “Help menu > About Audacity” and near the bottom of the “Build Information” tab will be the “build date”. The Audacity version (including build date), the operating system (for example “Windows Vista Home Basic SP2”) and exact steps to reproduce the bug are required.

I should have been more rigourous in my step-by-step. I turned snap-to OFF before importing the labels.txt file.

Just tried importing the labels into 1.3.12 and I get the problem. The “100 frames” label imports to 58799 samples instead of 58800.

So perhaps this somehow magically got fixed in 1.3.13 without anyone specifically intending to fix it. One of the devs has been working on rationalizing “quantized time” with “real time”, so maybe this was an unintended benefit.

I see Steve has posted while I was composing this and reports that he does not see the problem in 1.3.12. Strange. Here is a screen shot of 1.3.12 importing my test label file.
labelcompare.png
The cursor in the audio track was placed with “snap-to CDDA frames” and reports “58,800” in the selection bar. With the imported label selected you can see that the selection bar reports “58,799”, even though the labels appear to be in the same place!

– Bill

Thanks Bill, I can see what you mean.
If you zoom in as far as possible you may notice that the labels do not match up exactly - they are very slightly off (but less than a millionth of a second difference).
I think that the issue seen here is more to do with the time display than inaccuracies in the labels. The problem is that the label should be exactly coincident with the sample so any degree of inaccuracy will, for some samples, push the sample count from one side of the sample to the other.

However, I don’t see that it is a problem because whichever label you use, whether the original or the exported/imported copy, if you split the track based on labels the splits will occur between sample number 58799 and sample number 58800. Similarly if you select up to the label then in both cases the selection will go up to the 5880th sample, even though the time display will show 58800 samples for one label and 58799 for the other label.

“Curiouser and curiouser …”

In Audacity 1.3.12
Set snap-to CDDA frames on.
Generate 10 sec tone
Set labels at 100, 200, 300 and 400 frames.
Export the labels
Set snap-to off, and selection format to “samples”
Verify that selection from time=0 to the 100-frame label, and between labels. relying on the yellow snap line always reports a selection length of 58,800
Delete the label track
Import the labels
Select from time=0 to “100 frames” label - selection length is 58,799 samples
Select from “100 frames” label to “200 frames” label - selection length is 58,800 samples
Select from time=0 to “200 frames” label - selection length is 117,600 samples!
Select from “200 frames” label to “300 frames” label - selection length is 58,799 samples
Select from “300 frames” label to “400 frames” label - selection length is 58,799 samples
Export multiple based on labels, name first file “0 frames”, WAV or AIF (I used AIF)
Import the exported files
Verify the length of each file by double-clicking on the audio in the imported track: the first file and all the “between label” files report lengths of 58,800 samples

Conclusion 1: despite the apparent misplacement of some labels when importing a label text file, no samples are dropped on export.
Conclusion 2: Steve is right - the “issue seen here is more to do with the time display than inaccuracies in the labels”
Conclusion 3: Ctrl+N, you can relax. No samples are being dropped on export multiple, and your files will line up on CDDA frames.

Quit Audacity 1.3.12 and start Audacity 1.3.13
Generate 10 sec tone
Set sync-lock off, snap-to off, and selection format to samples
Import the labels
Select from time=0 to “100 frames” label - selection length is 58,800 samples
Select from “100 frames” label to “200 frames” label - selection length is 58,800 samples
Select from “200 frames” label to “300 frames” label - selection length is 58,800 samples
Select from “300 frames” label to “400 frames” label - selection length is 58,800 samples
Export multiple based on labels, name first file “0 frames”, WAV or AIF (I used AIF)
Import the exported files
Verify the length of each file by double-clicking on the audio in the imported track: the first file and all the “between label” files report lengths of 58,800 samples

Conclusion 1: something (inadvertently?) got fixed in 1.3.13 alpha.
Conclusion 2: Yay!

– Bill