sample bank import
This commit is contained in:
parent
7591b2ed6a
commit
dce4c9a4b2
|
@ -681,6 +681,14 @@ src/engine/fileOps/text.cpp
|
||||||
src/engine/fileOps/tfm.cpp
|
src/engine/fileOps/tfm.cpp
|
||||||
src/engine/fileOps/xm.cpp
|
src/engine/fileOps/xm.cpp
|
||||||
|
|
||||||
|
src/engine/fileOps/p.cpp
|
||||||
|
src/engine/fileOps/p86.cpp
|
||||||
|
src/engine/fileOps/pdx.cpp
|
||||||
|
src/engine/fileOps/ppc.cpp
|
||||||
|
src/engine/fileOps/pps.cpp
|
||||||
|
src/engine/fileOps/pvi.cpp
|
||||||
|
src/engine/fileOps/pzi.cpp
|
||||||
|
|
||||||
src/engine/blip_buf.c
|
src/engine/blip_buf.c
|
||||||
src/engine/brrUtils.c
|
src/engine/brrUtils.c
|
||||||
src/engine/safeReader.cpp
|
src/engine/safeReader.cpp
|
||||||
|
|
|
@ -617,6 +617,17 @@ class DivEngine {
|
||||||
void loadFF(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
void loadFF(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||||
void loadWOPL(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
void loadWOPL(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||||
void loadWOPN(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
void loadWOPN(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||||
|
|
||||||
|
//sample banks
|
||||||
|
void loadP(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
void loadPPC(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
void loadPPS(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
void loadPVI(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
void loadPDX(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
void loadPZI(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
void loadP86(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int loadSampleROM(String path, ssize_t expectedSize, unsigned char*& ret);
|
int loadSampleROM(String path, ssize_t expectedSize, unsigned char*& ret);
|
||||||
|
|
||||||
|
@ -1027,7 +1038,8 @@ class DivEngine {
|
||||||
int addSamplePtr(DivSample* which);
|
int addSamplePtr(DivSample* which);
|
||||||
|
|
||||||
// get sample from file
|
// get sample from file
|
||||||
DivSample* sampleFromFile(const char* path);
|
//DivSample* sampleFromFile(const char* path);
|
||||||
|
std::vector<DivSample*> sampleFromFile(const char* path);
|
||||||
|
|
||||||
// get raw sample
|
// get raw sample
|
||||||
DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate);
|
DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate);
|
||||||
|
|
|
@ -24,10 +24,12 @@
|
||||||
#include "sfWrapper.h"
|
#include "sfWrapper.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DivSample* DivEngine::sampleFromFile(const char* path) {
|
std::vector<DivSample*> DivEngine::sampleFromFile(const char* path) {
|
||||||
|
std::vector<DivSample*> ret;
|
||||||
|
|
||||||
if (song.sample.size()>=256) {
|
if (song.sample.size()>=256) {
|
||||||
lastError="too many samples!";
|
lastError="too many samples!";
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
warnings="";
|
warnings="";
|
||||||
|
@ -58,6 +60,110 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
}
|
}
|
||||||
extS+=i;
|
extS+=i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(extS == ".pps" || extS == ".ppc" || extS == ".pvi" ||
|
||||||
|
extS == ".pdx" || extS == ".pzi" || extS == ".p86" ||
|
||||||
|
extS == ".p") //sample banks!
|
||||||
|
{
|
||||||
|
String stripPath;
|
||||||
|
const char* pathReduxEnd=strrchr(pathRedux,'.');
|
||||||
|
if (pathReduxEnd==NULL) {
|
||||||
|
stripPath=pathRedux;
|
||||||
|
} else {
|
||||||
|
for (const char* i=pathRedux; i!=pathReduxEnd && (*i); i++) {
|
||||||
|
stripPath+=*i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* f=ps_fopen(path,"rb");
|
||||||
|
if (f==NULL) {
|
||||||
|
lastError=strerror(errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
unsigned char* buf;
|
||||||
|
ssize_t len;
|
||||||
|
if (fseek(f,0,SEEK_END)!=0) {
|
||||||
|
lastError=strerror(errno);
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
len=ftell(f);
|
||||||
|
if (len<0) {
|
||||||
|
lastError=strerror(errno);
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (len==(SIZE_MAX>>1)) {
|
||||||
|
lastError=strerror(errno);
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (len==0) {
|
||||||
|
lastError=strerror(errno);
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (fseek(f,0,SEEK_SET)!=0) {
|
||||||
|
lastError=strerror(errno);
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
buf=new unsigned char[len];
|
||||||
|
if (fread(buf,1,len,f)!=(size_t)len) {
|
||||||
|
logW("did not read entire sample bank file buffer!");
|
||||||
|
lastError=_LE("did not read entire sample bank file!");
|
||||||
|
delete[] buf;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
SafeReader reader = SafeReader(buf,len);
|
||||||
|
|
||||||
|
if(extS == ".pps")
|
||||||
|
{
|
||||||
|
loadPPS(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
if(extS == ".ppc")
|
||||||
|
{
|
||||||
|
loadPPC(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
if(extS == ".pvi")
|
||||||
|
{
|
||||||
|
loadPVI(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
if(extS == ".pdx")
|
||||||
|
{
|
||||||
|
loadPDX(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
if(extS == ".pzi")
|
||||||
|
{
|
||||||
|
loadPZI(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
if(extS == ".p86")
|
||||||
|
{
|
||||||
|
loadP86(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
if(extS == ".p")
|
||||||
|
{
|
||||||
|
loadP(reader,ret,stripPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((int)ret.size() > 0)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
for(DivSample* s: ret)
|
||||||
|
{
|
||||||
|
s->name = fmt::sprintf("%s sample %d", stripPath, counter);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] buf; //done with buffer
|
||||||
|
BUSY_END;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (extS==".dmc" || extS==".brr") { // read as .dmc or .brr
|
if (extS==".dmc" || extS==".brr") { // read as .dmc or .brr
|
||||||
size_t len=0;
|
size_t len=0;
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
|
@ -68,7 +174,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not open file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not open file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(f,0,SEEK_END)<0) {
|
if (fseek(f,0,SEEK_END)<0) {
|
||||||
|
@ -76,7 +182,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not get file length! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not get file length! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
len=ftell(f);
|
len=ftell(f);
|
||||||
|
@ -86,7 +192,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="file is empty!";
|
lastError="file is empty!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len==(SIZE_MAX>>1)) {
|
if (len==(SIZE_MAX>>1)) {
|
||||||
|
@ -94,7 +200,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="file is invalid!";
|
lastError="file is invalid!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(f,0,SEEK_SET)<0) {
|
if (fseek(f,0,SEEK_SET)<0) {
|
||||||
|
@ -102,7 +208,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not seek to beginning of file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not seek to beginning of file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extS==".dmc") {
|
if (extS==".dmc") {
|
||||||
|
@ -120,7 +226,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="wait... is that right? no I don't think so...";
|
lastError="wait... is that right? no I don't think so...";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* dataBuf=sample->dataDPCM;
|
unsigned char* dataBuf=sample->dataDPCM;
|
||||||
|
@ -147,14 +253,14 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="BRR sample is empty!";
|
lastError="BRR sample is empty!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
} else if ((len%9)!=0) {
|
} else if ((len%9)!=0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="possibly corrupt BRR sample!";
|
lastError="possibly corrupt BRR sample!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,16 +269,17 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not read file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not read file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return sample;
|
ret.push_back(sample);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_SNDFILE
|
#ifndef HAVE_SNDFILE
|
||||||
lastError="Furnace was not compiled with libsndfile!";
|
lastError="Furnace was not compiled with libsndfile!";
|
||||||
return NULL;
|
return ret;
|
||||||
#else
|
#else
|
||||||
SF_INFO si;
|
SF_INFO si;
|
||||||
SFWrapper sfWrap;
|
SFWrapper sfWrap;
|
||||||
|
@ -186,13 +293,13 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
} else {
|
} else {
|
||||||
lastError=fmt::sprintf("could not open file! (%s)\nif this is raw sample data, you may import it by right-clicking the Load Sample icon and selecting \"import raw\".",sf_error_number(err));
|
lastError=fmt::sprintf("could not open file! (%s)\nif this is raw sample data, you may import it by right-clicking the Load Sample icon and selecting \"import raw\".",sf_error_number(err));
|
||||||
}
|
}
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
if (si.frames>16777215) {
|
if (si.frames>16777215) {
|
||||||
lastError="this sample is too big! max sample size is 16777215.";
|
lastError="this sample is too big! max sample size is 16777215.";
|
||||||
sfWrap.doClose();
|
sfWrap.doClose();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
void* buf=NULL;
|
void* buf=NULL;
|
||||||
sf_count_t sampleLen=sizeof(short);
|
sf_count_t sampleLen=sizeof(short);
|
||||||
|
@ -298,14 +405,15 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
||||||
if (sample->centerRate>64000) sample->centerRate=64000;
|
if (sample->centerRate>64000) sample->centerRate=64000;
|
||||||
sfWrap.doClose();
|
sfWrap.doClose();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return sample;
|
ret.push_back(sample);
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate) {
|
DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate) {
|
||||||
if (song.sample.size()>=256) {
|
if (song.sample.size()>=256) {
|
||||||
lastError="too many samples!";
|
lastError="too many samples!";
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
if (channels<1) {
|
if (channels<1) {
|
||||||
channels=1;
|
channels=1;
|
||||||
|
@ -362,7 +470,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="file is empty!";
|
lastError="file is empty!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len==(SIZE_MAX>>1)) {
|
if (len==(SIZE_MAX>>1)) {
|
||||||
|
@ -370,7 +478,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="file is invalid!";
|
lastError="file is invalid!";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(f,0,SEEK_SET)<0) {
|
if (fseek(f,0,SEEK_SET)<0) {
|
||||||
|
@ -378,7 +486,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError=fmt::sprintf("could not seek to beginning of file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not seek to beginning of file! (%s)",strerror(errno));
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
lenDivided=len/channels;
|
lenDivided=len/channels;
|
||||||
|
@ -420,7 +528,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
lastError="this sample is too big! max sample size is 16777215.";
|
lastError="this sample is too big! max sample size is 16777215.";
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample->rate=rate;
|
sample->rate=rate;
|
||||||
|
@ -435,7 +543,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
|
||||||
lastError=fmt::sprintf("could not read file! (%s)",strerror(errno));
|
lastError=fmt::sprintf("could not read file! (%s)",strerror(errno));
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
delete sample;
|
delete sample;
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
|
@ -1593,7 +1593,7 @@ class FurnaceGUI {
|
||||||
int sampleTexW, sampleTexH;
|
int sampleTexW, sampleTexH;
|
||||||
bool updateSampleTex;
|
bool updateSampleTex;
|
||||||
|
|
||||||
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery, paletteQuery;
|
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery, paletteQuery, sampleBankSearchQuery;
|
||||||
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport;
|
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport;
|
||||||
String workingDirVGMExport, workingDirZSMExport, workingDirROMExport;
|
String workingDirVGMExport, workingDirZSMExport, workingDirROMExport;
|
||||||
String workingDirFont, workingDirColors, workingDirKeybinds;
|
String workingDirFont, workingDirColors, workingDirKeybinds;
|
||||||
|
@ -1605,6 +1605,7 @@ class FurnaceGUI {
|
||||||
String folderString;
|
String folderString;
|
||||||
|
|
||||||
std::vector<DivSystem> sysSearchResults;
|
std::vector<DivSystem> sysSearchResults;
|
||||||
|
std::vector<std::pair><DivSample*,bool>> sampleBankSearchResults;
|
||||||
std::vector<FurnaceGUISysDef> newSongSearchResults;
|
std::vector<FurnaceGUISysDef> newSongSearchResults;
|
||||||
std::vector<int> paletteSearchResults;
|
std::vector<int> paletteSearchResults;
|
||||||
FixedQueue<String,32> recentFile;
|
FixedQueue<String,32> recentFile;
|
||||||
|
@ -1620,6 +1621,7 @@ class FurnaceGUI {
|
||||||
bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, sysDupCloneChannels, sysDupEnd, noteInputPoly, notifyWaveChange;
|
bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, sysDupCloneChannels, sysDupEnd, noteInputPoly, notifyWaveChange;
|
||||||
bool wantScrollListIns, wantScrollListWave, wantScrollListSample;
|
bool wantScrollListIns, wantScrollListWave, wantScrollListSample;
|
||||||
bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
|
bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
|
||||||
|
bool displayPendingSamples, replacePendingSample;
|
||||||
bool changeCoarse;
|
bool changeCoarse;
|
||||||
bool mobileEdit;
|
bool mobileEdit;
|
||||||
bool killGraphics;
|
bool killGraphics;
|
||||||
|
@ -2373,6 +2375,7 @@ class FurnaceGUI {
|
||||||
std::vector<DivCommand> cmdStream;
|
std::vector<DivCommand> cmdStream;
|
||||||
std::vector<Particle> particles;
|
std::vector<Particle> particles;
|
||||||
std::vector<std::pair<DivInstrument*,bool>> pendingIns;
|
std::vector<std::pair<DivInstrument*,bool>> pendingIns;
|
||||||
|
std::vector <std::pair<DivSample*,bool>> pendingSamples;
|
||||||
|
|
||||||
std::vector<FurnaceGUISysCategory> sysCategories;
|
std::vector<FurnaceGUISysCategory> sysCategories;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue