[ai] random mode now really working

This commit is contained in:
Stefan Ostermann 2025-10-05 18:26:15 +02:00
parent d0c9a7e482
commit 33701636af
2 changed files with 77 additions and 23 deletions

View File

@ -270,29 +270,58 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String *songName)
// Check if the input is an absolute path (starts with '/') or just a filename
bool isAbsolutePath = songName->startsWith("/");
// Normalize trailing slash for absolute folder path targets
String normalizedPath = *songName;
if (isAbsolutePath && normalizedPath.length() > 1 && normalizedPath.endsWith("/"))
{
normalizedPath.remove(normalizedPath.length() - 1);
}
// Lowercased copies for case-insensitive comparisons (FAT can uppercase names)
String lowTarget = *songName;
lowTarget.toLowerCase();
String lowNormPath = normalizedPath;
lowNormPath.toLowerCase();
// First, search in the current directory's MP3 files
for (size_t i = 0; i < mp3Files.size(); i++)
{
if (isAbsolutePath)
{
if (*songName == mp3Files[i])
if (mp3Files[i].equalsIgnoreCase(*songName))
{
setCurrentPlaying(&mp3Files[i]);
return this;
}
}
else if (mp3Files[i].endsWith(*songName))
else
{
setCurrentPlaying(&mp3Files[i]);
return this;
String f = mp3Files[i];
f.toLowerCase();
if (f.endsWith(lowTarget))
{
setCurrentPlaying(&mp3Files[i]);
return this;
}
}
}
// Then search in subdirectories
for (auto subdir : subdirectories)
{
if (!isAbsolutePath && subdir->getName() == *songName)
// Absolute folder target: match directory by its full path derived from its files
if (isAbsolutePath && subdir->mp3Files.size() > 0)
{
String anyFile = subdir->mp3Files[0];
int lastSlash = anyFile.lastIndexOf('/');
String subdirPath = (lastSlash >= 0) ? anyFile.substring(0, lastSlash) : String();
if (subdirPath.equalsIgnoreCase(normalizedPath))
{
subdir->advanceToFirstMP3InThisNode();
return subdir;
}
}
if (!isAbsolutePath && subdir->getName().equalsIgnoreCase(*songName))
{
subdir->advanceToFirstMP3InThisNode();
return subdir;
@ -304,18 +333,29 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String *songName)
if (isAbsolutePath)
{
if (*songName == subdir->mp3Files[i])
if (subdir->mp3Files[i].equalsIgnoreCase(*songName))
{
subdir->setCurrentPlaying(&subdir->mp3Files[i]);
return subdir;
}
}
else if (subdir->mp3Files[i].endsWith(*songName))
else
{
subdir->setCurrentPlaying(&subdir->mp3Files[i]);
return subdir;
String f = subdir->mp3Files[i];
f.toLowerCase();
if (f.endsWith(lowTarget))
{
subdir->setCurrentPlaying(&subdir->mp3Files[i]);
return subdir;
}
}
}
// Recurse into deeper subdirectories to support nested folders and files
DirectoryNode* deeper = subdir->advanceToMP3(songName);
if (deeper != nullptr)
{
return deeper;
}
}
// If we get here, no matching song was found

View File

@ -560,24 +560,38 @@ void playSongByRFID(String id)
}
}
// Find index of current playing file within the folder list
for (size_t i = 0; i < folderFlatList.size(); i++)
if (entry.mode == 'r' && !folderFlatList.empty())
{
DirectoryNode *node = folderFlatList[i].first;
int fileIdx = folderFlatList[i].second;
if (node->getCurrentPlayingFilePath() == mp3File)
// In random mode, pick a random start index and move it to front
int startIdx = (int)random((long)folderFlatList.size());
if (startIdx != 0)
{
folderFlatIndex = (int)i;
break;
auto tmp = folderFlatList[0];
folderFlatList[0] = folderFlatList[startIdx];
folderFlatList[startIdx] = tmp;
}
}
// 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;
DirectoryNode *startNode = folderFlatList[0].first;
int fileIdx = folderFlatList[0].second;
Serial.print("Shuffle start: ");
Serial.println(startNode->getMP3Files()[fileIdx]);
startNode->setCurrentPlaying(&startNode->getMP3Files()[fileIdx]);
currentNode = startNode;
mp3File = currentNode->getCurrentPlayingFilePath();
}
else
{
// Find index of current playing file within the folder list
for (size_t i = 0; i < folderFlatList.size(); i++)
{
DirectoryNode *node = folderFlatList[i].first;
int fileIdx = folderFlatList[i].second;
if (node->getCurrentPlayingFilePath() == mp3File)
{
folderFlatIndex = (int)i;
break;
}
}
}
// Compute root path for safety checks (path up to last '/')