Initial attempt at supporting loading SysEx files from subdirectories which seems to speed up loading significantly.

pull/473/head
diyelectromusic 2 years ago
parent 8f3b794f7f
commit 72bec02d09
  1. 178
      src/sysexfileloader.cpp
  2. 3
      src/sysexfileloader.h

@ -84,6 +84,7 @@ CSysExFileLoader::~CSysExFileLoader (void)
void CSysExFileLoader::Load (bool bHeaderlessSysExVoices) void CSysExFileLoader::Load (bool bHeaderlessSysExVoices)
{ {
m_nNumHighestBank = 0; m_nNumHighestBank = 0;
m_nBanksLoaded = 0;
DIR *pDirectory = opendir (m_DirName.c_str ()); DIR *pDirectory = opendir (m_DirName.c_str ());
if (!pDirectory) if (!pDirectory)
@ -96,51 +97,112 @@ void CSysExFileLoader::Load (bool bHeaderlessSysExVoices)
dirent *pEntry; dirent *pEntry;
while ((pEntry = readdir (pDirectory)) != nullptr) while ((pEntry = readdir (pDirectory)) != nullptr)
{ {
unsigned nBank; LoadBank(m_DirName.c_str (), pEntry->d_name);
size_t nLen = strlen (pEntry->d_name); }
LOGDBG ("%u Banks loaded. Highest Bank loaded: #%u", m_nBanksLoaded, m_nNumHighestBank);
if ( nLen < 5 // "[NNNN]N[_name].syx" closedir (pDirectory);
|| strcasecmp (&pEntry->d_name[nLen-4], ".syx") != 0 }
|| sscanf (pEntry->d_name, "%u", &nBank) != 1)
{
LOGWARN ("%s: Invalid filename format", pEntry->d_name);
continue; void CSysExFileLoader::LoadBank (const char * sDirName, const char * sBankName)
} {
unsigned nBank;
size_t nLen = strlen (sBankName);
if (nBank > MaxVoiceBankID) if ( nLen < 5 // "[NNNN]N[_name].syx"
|| strcasecmp (&sBankName[nLen-4], ".syx") != 0
|| sscanf (sBankName, "%u", &nBank) != 1)
{
// See if this is a subdirectory...
std::string Dirname (sDirName);
Dirname += "/";
Dirname += sBankName;
DIR *pDirectory = opendir (Dirname.c_str ());
if (pDirectory)
{ {
LOGWARN ("Bank #%u is not supported", nBank); LOGDBG ("Processing subdirectory %s", sBankName);
continue; dirent *pEntry;
while ((pEntry = readdir (pDirectory)) != nullptr)
{
LoadBank(Dirname.c_str (), pEntry->d_name);
}
closedir (pDirectory);
} }
else
if (m_pVoiceBank[nBank])
{ {
LOGWARN ("Bank #%u already loaded", nBank); LOGWARN ("%s: Invalid filename format", sBankName);
continue;
} }
m_pVoiceBank[nBank] = new TVoiceBank; return;
assert (m_pVoiceBank[nBank]); }
assert (sizeof(TVoiceBank) == VoiceSysExHdrSize + VoiceSysExSize);
if (nBank > MaxVoiceBankID)
{
LOGWARN ("Bank #%u is not supported", nBank);
return;
}
if (m_pVoiceBank[nBank])
{
LOGWARN ("Bank #%u already loaded", nBank);
return;
}
m_pVoiceBank[nBank] = new TVoiceBank;
assert (m_pVoiceBank[nBank]);
assert (sizeof(TVoiceBank) == VoiceSysExHdrSize + VoiceSysExSize);
std::string Filename (m_DirName); std::string Filename (sDirName);
Filename += "/"; Filename += "/";
Filename += pEntry->d_name; Filename += sBankName;
FILE *pFile = fopen (Filename.c_str (), "rb"); FILE *pFile = fopen (Filename.c_str (), "rb");
if (pFile) if (pFile)
{
bool bBankLoaded = false;
if ( fread (m_pVoiceBank[nBank], VoiceSysExHdrSize+VoiceSysExSize, 1, pFile) == 1
&& m_pVoiceBank[nBank]->StatusStart == 0xF0
&& m_pVoiceBank[nBank]->CompanyID == 0x43
&& m_pVoiceBank[nBank]->Format == 0x09
&& m_pVoiceBank[nBank]->StatusEnd == 0xF7)
{ {
bool bBankLoaded = false; if (m_nBanksLoaded % 100 == 0)
if ( fread (m_pVoiceBank[nBank], VoiceSysExHdrSize+VoiceSysExSize, 1, pFile) == 1
&& m_pVoiceBank[nBank]->StatusStart == 0xF0
&& m_pVoiceBank[nBank]->CompanyID == 0x43
&& m_pVoiceBank[nBank]->Format == 0x09
&& m_pVoiceBank[nBank]->StatusEnd == 0xF7)
{ {
LOGDBG ("Bank #%u successfully loaded", nBank); LOGDBG ("Banks successfully loaded #%u", m_nBanksLoaded);
}
//LOGDBG ("Bank #%u successfully loaded", nBank);
m_BankFileName[nBank] = sBankName;
if (nBank > m_nNumHighestBank)
{
// This is the bank ID of the highest loaded bank
m_nNumHighestBank = nBank;
}
m_nBanksLoaded++;
bBankLoaded = true;
}
/* else if (bHeaderlessSysExVoices)
{
// Config says to accept headerless SysEx Voice Banks
// so reset file pointer and try again.
fseek (pFile, 0, SEEK_SET);
if (fread (m_pVoiceBank[nBank]->Voice, VoiceSysExSize, 1, pFile) == 1)
{
LOGDBG ("Bank #%u successfully loaded (headerless)", nBank);
// Add in the missing header items.
// Naturally it isn't possible to validate these!
m_pVoiceBank[nBank]->StatusStart = 0xF0;
m_pVoiceBank[nBank]->CompanyID = 0x43;
m_pVoiceBank[nBank]->Format = 0x09;
m_pVoiceBank[nBank]->ByteCountMS = 0x20;
m_pVoiceBank[nBank]->ByteCountLS = 0x00;
m_pVoiceBank[nBank]->Checksum = 0x00;
m_pVoiceBank[nBank]->StatusEnd = 0xF7;
m_BankFileName[nBank] = pEntry->d_name; m_BankFileName[nBank] = pEntry->d_name;
if (nBank > m_nNumHighestBank) if (nBank > m_nNumHighestBank)
@ -150,53 +212,23 @@ void CSysExFileLoader::Load (bool bHeaderlessSysExVoices)
} }
bBankLoaded = true; bBankLoaded = true;
} }
else if (bHeaderlessSysExVoices) }*/
{
// Config says to accept headerless SysEx Voice Banks
// so reset file pointer and try again.
fseek (pFile, 0, SEEK_SET);
if (fread (m_pVoiceBank[nBank]->Voice, VoiceSysExSize, 1, pFile) == 1)
{
LOGDBG ("Bank #%u successfully loaded (headerless)", nBank);
// Add in the missing header items.
// Naturally it isn't possible to validate these!
m_pVoiceBank[nBank]->StatusStart = 0xF0;
m_pVoiceBank[nBank]->CompanyID = 0x43;
m_pVoiceBank[nBank]->Format = 0x09;
m_pVoiceBank[nBank]->ByteCountMS = 0x20;
m_pVoiceBank[nBank]->ByteCountLS = 0x00;
m_pVoiceBank[nBank]->Checksum = 0x00;
m_pVoiceBank[nBank]->StatusEnd = 0xF7;
m_BankFileName[nBank] = pEntry->d_name;
if (nBank > m_nNumHighestBank)
{
// This is the bank ID of the highest loaded bank
m_nNumHighestBank = nBank;
}
bBankLoaded = true;
}
}
if (!bBankLoaded) if (!bBankLoaded)
{
LOGWARN ("%s: Invalid size or format", Filename.c_str ());
delete m_pVoiceBank[nBank];
m_pVoiceBank[nBank] = nullptr;
}
fclose (pFile);
}
else
{ {
LOGWARN ("%s: Invalid size or format", Filename.c_str ());
delete m_pVoiceBank[nBank]; delete m_pVoiceBank[nBank];
m_pVoiceBank[nBank] = nullptr; m_pVoiceBank[nBank] = nullptr;
} }
}
closedir (pDirectory); fclose (pFile);
}
else
{
delete m_pVoiceBank[nBank];
m_pVoiceBank[nBank] = nullptr;
}
} }
std::string CSysExFileLoader::GetBankName (unsigned nBankID) std::string CSysExFileLoader::GetBankName (unsigned nBankID)

@ -75,11 +75,14 @@ private:
std::string m_DirName; std::string m_DirName;
unsigned m_nNumHighestBank; unsigned m_nNumHighestBank;
unsigned m_nBanksLoaded;
TVoiceBank *m_pVoiceBank[MaxVoiceBankID+1]; TVoiceBank *m_pVoiceBank[MaxVoiceBankID+1];
std::string m_BankFileName[MaxVoiceBankID+1]; std::string m_BankFileName[MaxVoiceBankID+1];
static uint8_t s_DefaultVoice[SizeSingleVoice]; static uint8_t s_DefaultVoice[SizeSingleVoice];
void LoadBank (const char * sDirName, const char * sBankName);
}; };
#endif #endif

Loading…
Cancel
Save