[ai] random mode
This commit is contained in:
parent
626657a976
commit
d0c9a7e482
|
|
@ -133,6 +133,7 @@ Option A: Map through the web app (recommended)
|
||||||
5) Choose Mode:
|
5) Choose Mode:
|
||||||
- Single (s): Play just the selected song/file once.
|
- Single (s): Play just the selected song/file once.
|
||||||
- Folder (f): Play all files in the selected folder once, then stop.
|
- Folder (f): Play all files in the selected folder once, then stop.
|
||||||
|
- Random (r): Play all files in the selected folder in random order once, then stop.
|
||||||
- Continuous (c): Loop through the selected folder continuously.
|
- Continuous (c): Loop through the selected folder continuously.
|
||||||
6) Click “Update Mapping”.
|
6) Click “Update Mapping”.
|
||||||
|
|
||||||
|
|
|
||||||
38
src/main.cpp
38
src/main.cpp
|
|
@ -14,6 +14,9 @@
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
#include <MFRC522.h> //RFID Reader
|
#include <MFRC522.h> //RFID Reader
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#if defined(ESP32)
|
||||||
|
#include <esp_system.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// define pins for RFID
|
// define pins for RFID
|
||||||
#define CS_RFID 32 // SIC, tried 4 and 32 but only this worked!
|
#define CS_RFID 32 // SIC, tried 4 and 32 but only this worked!
|
||||||
|
|
@ -127,6 +130,7 @@ uint16_t voltage_threshold_counter = 0;
|
||||||
|
|
||||||
size_t free_heap = 0;
|
size_t free_heap = 0;
|
||||||
|
|
||||||
|
// webrequest_blockings is a simple watchdog counter that tracks how long at least one HTTP request has been “active” (not yet disconnected) according to the AsyncWebServer.
|
||||||
int webrequest_blockings = 0;
|
int webrequest_blockings = 0;
|
||||||
|
|
||||||
void activateSD()
|
void activateSD()
|
||||||
|
|
@ -534,8 +538,8 @@ void playSongByRFID(String id)
|
||||||
targetIsFolder = true;
|
targetIsFolder = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the mapping targets a folder (or explicitly 'f' mode), activate folder tracking
|
// If the mapping targets a folder (or explicitly 'f' or 'r' mode), activate folder tracking
|
||||||
if (targetIsFolder || entry.mode == 'f')
|
if (targetIsFolder || entry.mode == 'f' || entry.mode == 'r')
|
||||||
{
|
{
|
||||||
folderModeActive = true;
|
folderModeActive = true;
|
||||||
folderRootNode = currentNode;
|
folderRootNode = currentNode;
|
||||||
|
|
@ -543,6 +547,19 @@ void playSongByRFID(String id)
|
||||||
folderFlatList.clear();
|
folderFlatList.clear();
|
||||||
folderRootNode->buildFlatMP3List(folderFlatList);
|
folderRootNode->buildFlatMP3List(folderFlatList);
|
||||||
|
|
||||||
|
// If random-folder mode requested, shuffle the flat list once
|
||||||
|
if (entry.mode == 'r' && folderFlatList.size() > 1)
|
||||||
|
{
|
||||||
|
// Fisher-Yates shuffle using Arduino random()
|
||||||
|
for (int i = (int)folderFlatList.size() - 1; i > 0; --i)
|
||||||
|
{
|
||||||
|
int j = (int)random((long)(i + 1)); // 0..i
|
||||||
|
auto tmp = folderFlatList[i];
|
||||||
|
folderFlatList[i] = folderFlatList[j];
|
||||||
|
folderFlatList[j] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find index of current playing file within the folder list
|
// Find index of current playing file within the folder list
|
||||||
for (size_t i = 0; i < folderFlatList.size(); i++)
|
for (size_t i = 0; i < folderFlatList.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
@ -554,6 +571,14 @@ void playSongByRFID(String id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If random mode, make sure the current file is at the start so next advance is random
|
||||||
|
if (entry.mode == 'r' && folderFlatIndex > 0 && folderFlatIndex < (int)folderFlatList.size())
|
||||||
|
{
|
||||||
|
auto tmp = folderFlatList[0];
|
||||||
|
folderFlatList[0] = folderFlatList[folderFlatIndex];
|
||||||
|
folderFlatList[folderFlatIndex] = tmp;
|
||||||
|
folderFlatIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute root path for safety checks (path up to last '/')
|
// Compute root path for safety checks (path up to last '/')
|
||||||
int lastSlash = mp3File.lastIndexOf('/');
|
int lastSlash = mp3File.lastIndexOf('/');
|
||||||
|
|
@ -1337,6 +1362,13 @@ void setup()
|
||||||
activateSD();
|
activateSD();
|
||||||
Serial.println("SD initialization done.");
|
Serial.println("SD initialization done.");
|
||||||
|
|
||||||
|
// Seed RNG for shuffle mode
|
||||||
|
#if defined(ESP32)
|
||||||
|
randomSeed(esp_random());
|
||||||
|
#else
|
||||||
|
randomSeed((uint32_t)micros());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Load configuration from SD card
|
// Load configuration from SD card
|
||||||
Serial.println("Loading configuration...");
|
Serial.println("Loading configuration...");
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
|
@ -1503,7 +1535,7 @@ const String getSysDir(const String filename)
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
if (webreq_cnt > 0 && webrequest_blockings > 5000) {
|
if (webreq_cnt > 0 && webrequest_blockings > 10000) {
|
||||||
Serial.println("excessive webrequest blocking!");
|
Serial.println("excessive webrequest blocking!");
|
||||||
webreq_cnt = 0;
|
webreq_cnt = 0;
|
||||||
webrequest_blockings = 0;
|
webrequest_blockings = 0;
|
||||||
|
|
|
||||||
10
src/main.h
10
src/main.h
|
|
@ -84,10 +84,12 @@ boolean prepareSleepMode = false;
|
||||||
|
|
||||||
class DirectoryNode;
|
class DirectoryNode;
|
||||||
|
|
||||||
// Mapping entry that stores target (file or folder) and playback mode:
|
/* Mapping entry that stores target (file or folder) and playback mode:
|
||||||
// 's' = single (default) - play only the selected song (or single file in folder)
|
* 's' = single (default) - play only the selected song (or single file in folder)
|
||||||
// 'f' = folder - play files inside the selected folder, then stop
|
* 'f' = folder - play files inside the selected folder, then stop
|
||||||
// 'c' = continuous - continuously play (like previous continuousMode)
|
* 'r' = random-folder - play files inside the selected folder in random order, then stop
|
||||||
|
* 'c' = continuous - continuously play (like previous continuousMode)
|
||||||
|
*/
|
||||||
struct MappingEntry {
|
struct MappingEntry {
|
||||||
String target;
|
String target;
|
||||||
char mode;
|
char mode;
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@
|
||||||
<select id="mode" name="mode">
|
<select id="mode" name="mode">
|
||||||
<option value="s">Single (play selected song / file)</option>
|
<option value="s">Single (play selected song / file)</option>
|
||||||
<option value="f">Folder (play selected folder, then stop)</option>
|
<option value="f">Folder (play selected folder, then stop)</option>
|
||||||
|
<option value="r">Random (randomize order in folder, then stop)</option>
|
||||||
<option value="c">Continuous (continuous playback / loop folder)</option>
|
<option value="c">Continuous (continuous playback / loop folder)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue