Hi ! For an audio project, I'm trying to choose a random file in a folder (files with random names).
The only solution I found at this time is to:
list all files and count them
choose a random value between 1 and the total of files
re-list all files and stop when a counter of files (incremented at each file) matches the random value
It can be very slow on big folders, so I'm wondering if there are better solutions.
Thanks
Sure! Keep a file of names as you add them to folders.
You mean "appending their names in a text file in the SD card, count the lines, and pick a random name in the list" ?
That should work, don't you think?
xfpd
April 3, 2023, 12:32am
5
Use only numbers for file names, that is to say:
001.wav
002.wav
003.wav
.
.
.
999.wav
@Paul_KD7HB Yes, good idea, I will try ! Thanks !
@xfpd Yes, it is the solution I actually use, but it limits the ability to use random name files
xfpd
April 3, 2023, 6:09am
9
How does it limit randomness?
play(random(999).wav)
;
@xfpd I mean, you need to follow the naming guideline, you can't add "whatever.wav"
But it works
If you want to randomly select an element from a list of unknown size, you could try the following strategy:
Select the first element in the list as a candidate with probability 1.
Select the second element in the list as a candidate with probability 1/2.
Select the third element in the list as a candidate with probability 1/3.
etc.
In the following example, we assume we receive a zero terminated array:
char const* pick(char const* const files[]) {
char const* candidate {nullptr};
for (size_t i {0}; files[i]; ++i) {
if (not random(i + 1)) {
candidate = files[i];
}
}
return candidate;
}
Usage:
char const* files[] {"a", "b", "c", "d", "e", nullptr};
Serial.println(pick(files));
Instead of an array, you can use a function that returns the next entry in a directory list. The following example is based on the list files example (untested):
void pick(char name[], File dir) {
File entry {dir.openNextFile()};
for (size_t i {0}; entry; ++i) {
if (not random(i + 1)) {
strcpy(name, entry.name());
}
entry.close();
entry = dir.openNextFile();
}
}
Usage:
void setup() {
Serial.begin(9600);
char name[20] {};
File root {SD.open("/")};
pick(name, root);
root.close();
Serial.println(name);
}
system
Closed
September 30, 2023, 10:05am
12
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.