Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing blocks read with overlap for files shorter than block size #446

Merged

Conversation

illesguy
Copy link
Contributor

@illesguy illesguy commented Nov 7, 2024

Summary

The blocks method to read an audio in frame blocks with an optional overlap has a bug in the edge case when the file has less frames than the block size specified and the overlap specified is not 0. The full file and an overlap number of random values are returned in the output in this case.

Explanation

When the method is called without a provided out array, it creates an empty array to store the output with the np.empty method with the shape corresponding to the block size argument (and the number of channels but that is not relevant for this problem). The default values in an array created by np.empty are not deterministic.

The file is then read into this out array up to the block size or the end of the file, whichever is shorter. The number of frames in the file plus the overlap size is copied into a block from the out array which is returned.

Example

Let's take an example of a mono file with 5 frames, a block size of 10 and an overlap of 1.

  • First an output array of size 10 is produced: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
  • Then the entire file is read into this array (since the file length is shorter than the block size) so it becomes:
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 0] (assuming all frames in the mono file were 1)
  • Then the number of frames in the file plus the overlap size is taken from the output array as the block which is 5+1=6. The output block we get therefore is: [1, 1, 1, 1, 1, 0].
  • We get an extra frame at the end of our output array which in this example is 0 but can be a random number produced by np.empty.

The test_block_longer_than_file_with_overlap_mono test was added to cover this case. It did fail as expected before adding the fix.

What happens when the block size is smaller than the file length but there is an overlap?

In case the where the file has multiple blocks in it, the error doesn't occur because at the end of each block read, the overlapping frames are added to the beginning of the out array and the next frames for the file are read on top of that. Due to this, when returning the final block, we will again return the number of frames left in the file plus the overlap frames, but in this case the overlap frames will be the frames added to the beginning of the output in the previous run so this case isn't impacted by the bug.

The fix

When creating the initial out array (in case it was not provided as an argument) we just need to make sure to create it with a length that is equal to the block size OR the number of frames in the file, whichever is smaller. If the block size is smaller than the number of frames in the file, it will work as previously and as discussed above, that case is not affected by the bug. If however the block size is greater, the output array will be equal to the number of frames in the file but in this case there's only going to be one block anyway so having an overlap does not make sense.

@bastibe
Copy link
Owner

bastibe commented Nov 7, 2024

Congratulations! It's quite rare that someone finds a real bug in this project.

And thank you for fixing it right away as well!

@bastibe bastibe merged commit 7eb5697 into bastibe:master Nov 7, 2024
24 of 31 checks passed
@illesguy
Copy link
Contributor Author

illesguy commented Nov 8, 2024

Thanks for being responsive and for the merge! Will there be a new version released with this commit?

@bastibe
Copy link
Owner

bastibe commented Nov 9, 2024

There are still a few cross-compilation issues with the CI that need to be resolved before I'll cut a new version. Unfortunately, this is not my area of expertise, and I don't have a whole lot of time available to devote to this. I can't promise any particular time frame, but I hope to find time for it during the Christmas holidays at the latest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants