prepare for .opm support

goodbye addInstrumentFromFile
hello instrumentFromFile + addInstrumentPtr

these changes are required to allow loading instrument banks
This commit is contained in:
tildearrow 2022-04-03 01:56:49 -05:00
parent 44d72c2106
commit e44d081adc
3 changed files with 49 additions and 32 deletions

View File

@ -1260,6 +1260,16 @@ int DivEngine::addInstrument(int refChan) {
return insCount; return insCount;
} }
int DivEngine::addInstrumentPtr(DivInstrument* which) {
BUSY_BEGIN;
saveLock.lock();
song.ins.push_back(which);
song.insLen=song.ins.size();
saveLock.unlock();
BUSY_END;
return song.insLen;
}
enum DivInsFormats { enum DivInsFormats {
DIV_INSFORMAT_DMP, DIV_INSFORMAT_DMP,
DIV_INSFORMAT_TFI, DIV_INSFORMAT_TFI,
@ -1268,12 +1278,14 @@ enum DivInsFormats {
DIV_INSFORMAT_BTI, DIV_INSFORMAT_BTI,
DIV_INSFORMAT_S3I, DIV_INSFORMAT_S3I,
DIV_INSFORMAT_SBI, DIV_INSFORMAT_SBI,
DIV_INSFORMAT_OPM
}; };
// TODO: re-organize this function to: // TODO: re-organize this function to:
// - support replacing instruments // - support replacing instruments
// - support instrument formats which contain multiple instruments // - support instrument formats which contain multiple instruments
bool DivEngine::addInstrumentFromFile(const char* path) { std::vector<DivInstrument*> DivEngine::instrumentFromFile(const char* path) {
std::vector<DivInstrument*> ret;
warnings=""; warnings="";
const char* pathRedux=strrchr(path,DIR_SEPARATOR); const char* pathRedux=strrchr(path,DIR_SEPARATOR);
@ -1295,37 +1307,37 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
FILE* f=ps_fopen(path,"rb"); FILE* f=ps_fopen(path,"rb");
if (f==NULL) { if (f==NULL) {
lastError=strerror(errno); lastError=strerror(errno);
return false; return ret;
} }
unsigned char* buf; unsigned char* buf;
ssize_t len; ssize_t len;
if (fseek(f,0,SEEK_END)!=0) { if (fseek(f,0,SEEK_END)!=0) {
lastError=strerror(errno); lastError=strerror(errno);
fclose(f); fclose(f);
return false; return ret;
} }
len=ftell(f); len=ftell(f);
if (len<0) { if (len<0) {
lastError=strerror(errno); lastError=strerror(errno);
fclose(f); fclose(f);
return false; return ret;
} }
if (len==0) { if (len==0) {
lastError=strerror(errno); lastError=strerror(errno);
fclose(f); fclose(f);
return false; return ret;
} }
if (fseek(f,0,SEEK_SET)!=0) { if (fseek(f,0,SEEK_SET)!=0) {
lastError=strerror(errno); lastError=strerror(errno);
fclose(f); fclose(f);
return false; return ret;
} }
buf=new unsigned char[len]; buf=new unsigned char[len];
if (fread(buf,1,len,f)!=(size_t)len) { if (fread(buf,1,len,f)!=(size_t)len) {
logW("did not read entire instrument file buffer!\n"); logW("did not read entire instrument file buffer!\n");
lastError="did not read entire instrument file!"; lastError="did not read entire instrument file!";
delete[] buf; delete[] buf;
return false; return ret;
} }
fclose(f); fclose(f);
@ -1359,14 +1371,14 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
lastError="invalid instrument header/data!"; lastError="invalid instrument header/data!";
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
} catch (EndOfFileException& e) { } catch (EndOfFileException& e) {
lastError="premature end of file"; lastError="premature end of file";
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
} else { // read as a different format } else { // read as a different format
const char* ext=strrchr(path,'.'); const char* ext=strrchr(path,'.');
@ -1412,14 +1424,14 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
if (version>11) { if (version>11) {
lastError="unknown instrument version!"; lastError="unknown instrument version!";
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
ins->name=stripPath; ins->name=stripPath;
@ -1466,7 +1478,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
lastError="unknown instrument type!"; lastError="unknown instrument type!";
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
break; break;
} }
} catch (EndOfFileException& e) { } catch (EndOfFileException& e) {
@ -1474,7 +1486,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
} }
@ -1661,7 +1673,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
break; break;
} }
@ -1694,7 +1706,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
break; break;
case DIV_INSFORMAT_VGI: case DIV_INSFORMAT_VGI:
@ -1733,12 +1745,14 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
break; break;
case DIV_INSFORMAT_FTI: case DIV_INSFORMAT_FTI: // TODO
break; break;
case DIV_INSFORMAT_BTI: case DIV_INSFORMAT_BTI: // TODO
break;
case DIV_INSFORMAT_OPM: // TODO
break; break;
case DIV_INSFORMAT_S3I: case DIV_INSFORMAT_S3I:
try { try {
@ -1816,7 +1830,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
break; break;
case DIV_INSFORMAT_SBI: case DIV_INSFORMAT_SBI:
@ -1983,7 +1997,7 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
logE("premature end of file!\n"); logE("premature end of file!\n");
delete ins; delete ins;
delete[] buf; delete[] buf;
return false; return ret;
} }
break; break;
} }
@ -1995,14 +2009,8 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
} }
} }
BUSY_BEGIN; ret.push_back(ins);
saveLock.lock(); return ret;
int insCount=(int)song.ins.size();
song.ins.push_back(ins);
song.insLen=insCount+1;
saveLock.unlock();
BUSY_END;
return true;
} }
void DivEngine::delInstrument(int index) { void DivEngine::delInstrument(int index) {

View File

@ -491,8 +491,12 @@ class DivEngine {
// add instrument // add instrument
int addInstrument(int refChan=0); int addInstrument(int refChan=0);
// add instrument from file // add instrument from pointer
bool addInstrumentFromFile(const char* path); int addInstrumentPtr(DivInstrument* which);
// get instrument from file
// if the returned vector is empty then there was an error.
std::vector<DivInstrument*> instrumentFromFile(const char* path);
// delete instrument // delete instrument
void delInstrument(int index); void delInstrument(int index);

View File

@ -2628,15 +2628,20 @@ bool FurnaceGUI::loop() {
case GUI_FILE_EXPORT_AUDIO_PER_CHANNEL: case GUI_FILE_EXPORT_AUDIO_PER_CHANNEL:
exportAudio(copyOfName,DIV_EXPORT_MODE_MANY_CHAN); exportAudio(copyOfName,DIV_EXPORT_MODE_MANY_CHAN);
break; break;
case GUI_FILE_INS_OPEN: case GUI_FILE_INS_OPEN: {
if (e->addInstrumentFromFile(copyOfName.c_str())) { std::vector<DivInstrument*> instruments=e->instrumentFromFile(copyOfName.c_str());
if (!instruments.empty()) {
if (!e->getWarnings().empty()) { if (!e->getWarnings().empty()) {
showWarning(e->getWarnings(),GUI_WARN_GENERIC); showWarning(e->getWarnings(),GUI_WARN_GENERIC);
} }
for (DivInstrument* i: instruments) {
e->addInstrumentPtr(i);
}
} else { } else {
showError("cannot load instrument! ("+e->getLastError()+")"); showError("cannot load instrument! ("+e->getLastError()+")");
} }
break; break;
}
case GUI_FILE_WAVE_OPEN: case GUI_FILE_WAVE_OPEN:
e->addWaveFromFile(copyOfName.c_str()); e->addWaveFromFile(copyOfName.c_str());
MARK_MODIFIED; MARK_MODIFIED;