mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 15:03:01 +00:00
add a sample preview button (hopefully)
the next commit will be about normalizing sample rate
This commit is contained in:
parent
6ee4e33b89
commit
48f4f5835b
4 changed files with 82 additions and 11 deletions
|
@ -1485,6 +1485,26 @@ void DivEngine::syncReset() {
|
|||
isBusy.unlock();
|
||||
}
|
||||
|
||||
const int sampleRates[6]={
|
||||
4000, 8000, 11025, 16000, 22050, 32000
|
||||
};
|
||||
|
||||
void DivEngine::previewSample(int sample) {
|
||||
isBusy.lock();
|
||||
if (sample<0 || sample>(int)song.sample.size()) {
|
||||
sPreview.sample=-1;
|
||||
sPreview.pos=0;
|
||||
isBusy.unlock();
|
||||
return;
|
||||
}
|
||||
blip_clear(bb[2]);
|
||||
blip_set_rates(bb[2],sampleRates[song.sample[sample]->rate],got.rate);
|
||||
prevSample[2]=0;
|
||||
sPreview.pos=0;
|
||||
sPreview.sample=sample;
|
||||
isBusy.unlock();
|
||||
}
|
||||
|
||||
String DivEngine::getConfigPath() {
|
||||
return configPath;
|
||||
}
|
||||
|
@ -1942,13 +1962,23 @@ bool DivEngine::init(String outName) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bb[2]=blip_new(32768);
|
||||
if (bb[2]==NULL) {
|
||||
logE("not enough memory!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bbOut[0]=new short[got.bufsize];
|
||||
bbOut[1]=new short[got.bufsize];
|
||||
bbOut[2]=new short[got.bufsize];
|
||||
|
||||
bbIn[0]=new short[32768];
|
||||
bbIn[1]=new short[32768];
|
||||
bbIn[2]=new short[32768];
|
||||
bbInLen=32768;
|
||||
|
||||
blip_set_rates(bb[2],44100,got.rate);
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI));
|
||||
}
|
||||
|
|
|
@ -92,13 +92,21 @@ class DivEngine {
|
|||
String configFile;
|
||||
String lastError;
|
||||
|
||||
struct SamplePreview {
|
||||
int sample;
|
||||
unsigned int pos;
|
||||
SamplePreview():
|
||||
sample(-1),
|
||||
pos(0) {}
|
||||
} sPreview;
|
||||
|
||||
short vibTable[64];
|
||||
|
||||
blip_buffer_t* bb[2];
|
||||
blip_buffer_t* bb[3];
|
||||
size_t bbInLen;
|
||||
int temp[2], prevSample[2];
|
||||
short* bbIn[2];
|
||||
short* bbOut[2];
|
||||
int temp[3], prevSample[3];
|
||||
short* bbIn[3];
|
||||
short* bbOut[3];
|
||||
|
||||
size_t totalProcessed;
|
||||
|
||||
|
@ -155,6 +163,9 @@ class DivEngine {
|
|||
// reset playback state
|
||||
void syncReset();
|
||||
|
||||
// trigger sample preview
|
||||
void previewSample(int sample);
|
||||
|
||||
// get config path
|
||||
String getConfigPath();
|
||||
|
||||
|
|
|
@ -802,9 +802,36 @@ bool DivEngine::nextTick(bool noAccum) {
|
|||
}
|
||||
|
||||
void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) {
|
||||
if (!playing || dispatch==NULL) {
|
||||
memset(out[0],0,size*sizeof(float));
|
||||
memset(out[1],0,size*sizeof(float));
|
||||
|
||||
isBusy.lock();
|
||||
if (sPreview.sample>=0 && sPreview.sample<(int)song.sample.size()) {
|
||||
DivSample* s=song.sample[sPreview.sample];
|
||||
size_t prevtotal=blip_clocks_needed(bb[2],size);
|
||||
|
||||
for (size_t i=0; i<prevtotal; i++) {
|
||||
if (sPreview.pos>=s->rendLength) {
|
||||
temp[2]=0;
|
||||
} else {
|
||||
temp[2]=s->rendData[sPreview.pos++];
|
||||
}
|
||||
blip_add_delta(bb[2],i,temp[2]-prevSample[2]);
|
||||
prevSample[2]=temp[2];
|
||||
}
|
||||
|
||||
if (sPreview.pos>=s->rendLength) sPreview.sample=-1;
|
||||
|
||||
blip_end_frame(bb[2],prevtotal);
|
||||
blip_read_samples(bb[2],bbOut[2],size,0);
|
||||
for (size_t i=0; i<size; i++) {
|
||||
out[0][i]+=(float)bbOut[2][i]/32768.0;
|
||||
out[1][i]+=(float)bbOut[2][i]/32768.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!playing || dispatch==NULL) {
|
||||
isBusy.unlock();
|
||||
return;
|
||||
}
|
||||
size_t runtotal=blip_clocks_needed(bb[0],size);
|
||||
|
@ -820,7 +847,6 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
size_t runLeft=runtotal;
|
||||
size_t runPos=0;
|
||||
totalProcessed=0;
|
||||
isBusy.lock();
|
||||
while (runLeft) {
|
||||
if (!remainingLoops) {
|
||||
memset(bbIn[0]+runPos,0,runLeft*sizeof(short));
|
||||
|
@ -874,13 +900,13 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
|
||||
if (dispatch->isStereo()) {
|
||||
for (size_t i=0; i<size; i++) {
|
||||
out[0][i]=(float)bbOut[0][i]/16384.0;
|
||||
out[1][i]=(float)bbOut[1][i]/16384.0;
|
||||
out[0][i]+=(float)bbOut[0][i]/16384.0;
|
||||
out[1][i]+=(float)bbOut[1][i]/16384.0;
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<size; i++) {
|
||||
out[0][i]=(float)bbOut[0][i]/16384.0;
|
||||
out[1][i]=(float)bbOut[0][i]/16384.0;
|
||||
out[0][i]+=(float)bbOut[0][i]/16384.0;
|
||||
out[1][i]+=(float)bbOut[0][i]/16384.0;
|
||||
}
|
||||
}
|
||||
isBusy.unlock();
|
||||
|
|
|
@ -906,6 +906,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::Button("Apply")) {
|
||||
e->renderSamplesP();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_PLAY "##PreviewSample")) {
|
||||
e->previewSample(curSample);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused()) curWindow=GUI_WINDOW_SAMPLE_EDIT;
|
||||
|
|
Loading…
Reference in a new issue