0

One of my clients asked me to play sound from an SD card. But file selection should be random because the device is used to scare animals in the field(animals should not get used to sound pattern). I can generate random numbers by

void RNG_Generate_Numbers()
{
    HAL_RNG_GenerateRandomNumber(&hrng, &random_number.random_number1);
    HAL_RNG_GenerateRandomNumber(&hrng, &random_number.random_number2);
}

And I can count files via

void File_Find_File(file_manager_t *file_manage)
{

    file_manage->file_result = f_readdir(&file_manage->file_direction, &file_manage->file_info);

    if( (file_manage->file_result != FR_OK) || (file_manage->file_info.fname[0] == '\0')  )
    {
        file_manage->file_counter = 0;
    }
    else
    {
    ++file_manage->file_counter;
    }

}

Everything till here is just fine. But when It comes to select files randomly, I could not find any method to do it. Any help is appreciated.

Edit: This is file_manager structure;

typedef struct __file_manager /* struct tag */
{
FATFS drive_handler;
FIL file_handler;
FRESULT file_result;
uint8_t file_disk_status;
DIR file_direction;
FILINFO file_info;
uint8_t file_rx_buffer[512];
char file_current_dir[256];
uint32_t file_bytes_read;
uint32_t file_bytes_write;
size_t file_counter;
}file_manager_t ;
Peter O.
  • 32,158
  • 14
  • 82
  • 96
emre iris
  • 51
  • 1
  • 10
  • 1
    Is there any reason for which you can't cram all files into a single directory and rename them? If the answer is no, just rename the files so that filenames are a sequence of numbers and use `sprintf(file_name, "%d.mp3", rand() % n_files)`, or whatever is closest to that approach on your system. –  May 12 '21 at 17:58
  • This could be operating system specific and hardware specific. – Basile Starynkevitch May 12 '21 at 18:23
  • It is MCU based application. There is no OS on the system. I am using FATFS to operate file system. – emre iris May 12 '21 at 19:06
  • @Paul I was almost thinking the same. But audio files are determined by users and users tend to make mistakes... – emre iris May 12 '21 at 19:08
  • 1
    so many possibilities! Paul's suggestion is easiest. if you've got enough RAM, then load all the names in and just pick from that list. if your sd card is fast, then just traverse the directory every time doing [reservoir sampling](https://stackoverflow.com/q/9401375/1358308) – Sam Mason May 12 '21 at 19:13
  • Thanks to you all for your interest :) I will go with Pauls solution. – emre iris May 12 '21 at 19:17

1 Answers1

2

The simplest solution would be to move all files into a single directory and name each file in a sequence starting from zero. Getting a random files name would then be as simple as:

sprintf(file_name, "%d.mp3", rand() % my_files);