Search code examples
c#audiodata-analysisanalysisaudio-analysis

Why does sorting a list of onsets into numbers the size of the Sample Depth of the song (1024) always result in 20


ok so i'm not exactly sure how to describe this problem as i'm new to Audio analysis as a whole so i'm going to explain it step by step.

  1. So i have this algorithm here written in csharp
// Put into groups
for (int i = 0; i < onsets.Count-1; i++){
    for (float i2 = 1f; i2 < range+1; i2++){
        if (onsets[i] >= rangemult*(i2-1f) && onsets[i] <= rangemult*i2){
           sorted.Add(((rangemult*i2)*2f)*10f);
        }
    }
}
  1. Here's what it does:

onsets --> a List containing the onsets found (excluding any 0's)

range --> Song Sample Depth (1024)

rangemult --> Is the maximum value in the list of onsets (so onsets.Max()) divided by the range so (max DIV range)

sorted --> list the sorted onsets are added to

(rangemult*i2)*2f)*10f --> i do this in order to get the value to be a whole number (which doesn't happen most of the time but it's really just for a sake of neatness - so for the most part it can be ignored)

in principle this algorithm would convert an array (0.1, 0.2, 0.4, 0.45, 0.5) with

range = 10 to 2, 4, 8, 9, 10

range = 20 to 4, 8, 16, 18, 20

etc...

  1. so given this why is it that when 1024 is set as range the maximum value in sorted is always 20?

Additional info:

  • i'm using a lomont FFT
  • 1024 is constant throughout the onset detection algo
  • treat onsets.max() as always 1 (i'm yet to find an instance where onsets.Max() is not 1)

I greatly appreciate it if you can provide even the smallest hint as to what's wrong - if there is not enough information here or the information is uneeded please inform me as i'm still new so i have hard time trying to explain my questions in an accurate manner - thankyou for understanding :)


Solution

  • Given your apparent purpose, all you need is a simple LINQ statement:

    var rangemult = range/onsets.Max();
    var sorted = onsets.Select(onset => onset*rangemult).ToList();
    

    However, this doesn't round the result to integers. You can add any desired rounding such as Math.Floor or Math.Round or Math.Ceil in the Select:

    var sorted = onsets.Select(onset => Math.Round(onset*rangemult)).ToList();