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

View File

@ -491,8 +491,12 @@ class DivEngine {
// add instrument
int addInstrument(int refChan=0);
// add instrument from file
bool addInstrumentFromFile(const char* path);
// add instrument from pointer
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
void delInstrument(int index);

View File

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