Merge branch 'master' of https://github.com/tildearrow/furnace into ymf289b

This commit is contained in:
cam900 2023-05-13 18:53:50 +09:00
commit 967cc86ec9
3 changed files with 42 additions and 40 deletions

View File

@ -701,7 +701,7 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
#define RESAMPLE_BEGIN \ #define RESAMPLE_BEGIN \
if (samples<1) return true; \ if (samples<1) return true; \
int finalCount=(double)samples*(r/(double)rate); \ int finalCount=(double)samples*(tRate/sRate); \
signed char* oldData8=data8; \ signed char* oldData8=data8; \
short* oldData16=data16; \ short* oldData16=data16; \
if (depth==DIV_SAMPLE_DEPTH_16BIT) { \ if (depth==DIV_SAMPLE_DEPTH_16BIT) { \
@ -719,10 +719,10 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
} }
#define RESAMPLE_END \ #define RESAMPLE_END \
if (loopStart>=0) loopStart=(double)loopStart*(r/(double)rate); \ if (loopStart>=0) loopStart=(double)loopStart*(tRate/sRate); \
if (loopEnd>=0) loopEnd=(double)loopEnd*(r/(double)rate); \ if (loopEnd>=0) loopEnd=(double)loopEnd*(tRate/sRate); \
centerRate=(int)((double)centerRate*(r/(double)rate)); \ centerRate=(int)((double)centerRate*(tRate/sRate)); \
rate=r; \ rate=(int)((double)rate*(tRate/sRate)); \
samples=finalCount; \ samples=finalCount; \
if (depth==DIV_SAMPLE_DEPTH_16BIT) { \ if (depth==DIV_SAMPLE_DEPTH_16BIT) { \
delete[] oldData16; \ delete[] oldData16; \
@ -730,12 +730,12 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
delete[] oldData8; \ delete[] oldData8; \
} }
bool DivSample::resampleNone(double r) { bool DivSample::resampleNone(double sRate, double tRate) {
RESAMPLE_BEGIN; RESAMPLE_BEGIN;
if (depth==DIV_SAMPLE_DEPTH_16BIT) { if (depth==DIV_SAMPLE_DEPTH_16BIT) {
for (int i=0; i<finalCount; i++) { for (int i=0; i<finalCount; i++) {
unsigned int pos=(unsigned int)((double)i*((double)rate/r)); unsigned int pos=(unsigned int)((double)i*(sRate/tRate));
if (pos>=samples) { if (pos>=samples) {
data16[i]=0; data16[i]=0;
} else { } else {
@ -744,7 +744,7 @@ bool DivSample::resampleNone(double r) {
} }
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) { } else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
for (int i=0; i<finalCount; i++) { for (int i=0; i<finalCount; i++) {
unsigned int pos=(unsigned int)((double)i*((double)rate/r)); unsigned int pos=(unsigned int)((double)i*(sRate/tRate));
if (pos>=samples) { if (pos>=samples) {
data8[i]=0; data8[i]=0;
} else { } else {
@ -757,12 +757,12 @@ bool DivSample::resampleNone(double r) {
return true; return true;
} }
bool DivSample::resampleLinear(double r) { bool DivSample::resampleLinear(double sRate, double tRate) {
RESAMPLE_BEGIN; RESAMPLE_BEGIN;
double posFrac=0; double posFrac=0;
unsigned int posInt=0; unsigned int posInt=0;
double factor=(double)rate/r; double factor=sRate/tRate;
if (depth==DIV_SAMPLE_DEPTH_16BIT) { if (depth==DIV_SAMPLE_DEPTH_16BIT) {
for (int i=0; i<finalCount; i++) { for (int i=0; i<finalCount; i++) {
@ -796,12 +796,12 @@ bool DivSample::resampleLinear(double r) {
return true; return true;
} }
bool DivSample::resampleCubic(double r) { bool DivSample::resampleCubic(double sRate, double tRate) {
RESAMPLE_BEGIN; RESAMPLE_BEGIN;
double posFrac=0; double posFrac=0;
unsigned int posInt=0; unsigned int posInt=0;
double factor=(double)rate/r; double factor=sRate/tRate;
float* cubicTable=DivFilterTables::getCubicTable(); float* cubicTable=DivFilterTables::getCubicTable();
if (depth==DIV_SAMPLE_DEPTH_16BIT) { if (depth==DIV_SAMPLE_DEPTH_16BIT) {
@ -850,12 +850,12 @@ bool DivSample::resampleCubic(double r) {
return true; return true;
} }
bool DivSample::resampleBlep(double r) { bool DivSample::resampleBlep(double sRate, double tRate) {
RESAMPLE_BEGIN; RESAMPLE_BEGIN;
double posFrac=0; double posFrac=0;
unsigned int posInt=0; unsigned int posInt=0;
double factor=r/(double)rate; double factor=tRate/sRate;
float* sincITable=DivFilterTables::getSincIntegralTable(); float* sincITable=DivFilterTables::getSincIntegralTable();
float* floatData=new float[finalCount]; float* floatData=new float[finalCount];
@ -934,12 +934,12 @@ bool DivSample::resampleBlep(double r) {
return true; return true;
} }
bool DivSample::resampleSinc(double r) { bool DivSample::resampleSinc(double sRate, double tRate) {
RESAMPLE_BEGIN; RESAMPLE_BEGIN;
double posFrac=0; double posFrac=0;
unsigned int posInt=0; unsigned int posInt=0;
double factor=(double)rate/r; double factor=sRate/tRate;
float* sincTable=DivFilterTables::getSincTable(); float* sincTable=DivFilterTables::getSincTable();
float s[16]; float s[16];
@ -1001,29 +1001,29 @@ bool DivSample::resampleSinc(double r) {
return true; return true;
} }
bool DivSample::resample(double r, int filter) { bool DivSample::resample(double sRate, double tRate, int filter) {
if (depth!=DIV_SAMPLE_DEPTH_8BIT && depth!=DIV_SAMPLE_DEPTH_16BIT) return false; if (depth!=DIV_SAMPLE_DEPTH_8BIT && depth!=DIV_SAMPLE_DEPTH_16BIT) return false;
switch (filter) { switch (filter) {
case DIV_RESAMPLE_NONE: case DIV_RESAMPLE_NONE:
return resampleNone(r); return resampleNone(sRate,tRate);
break; break;
case DIV_RESAMPLE_LINEAR: case DIV_RESAMPLE_LINEAR:
return resampleLinear(r); return resampleLinear(sRate,tRate);
break; break;
case DIV_RESAMPLE_CUBIC: case DIV_RESAMPLE_CUBIC:
return resampleCubic(r); return resampleCubic(sRate,tRate);
break; break;
case DIV_RESAMPLE_BLEP: case DIV_RESAMPLE_BLEP:
return resampleBlep(r); return resampleBlep(sRate,tRate);
break; break;
case DIV_RESAMPLE_SINC: case DIV_RESAMPLE_SINC:
return resampleSinc(r); return resampleSinc(sRate,tRate);
break; break;
case DIV_RESAMPLE_BEST: case DIV_RESAMPLE_BEST:
if (r>rate) { if (tRate>sRate) {
return resampleSinc(r); return resampleSinc(sRate,tRate);
} else { } else {
return resampleBlep(r); return resampleBlep(sRate,tRate);
} }
break; break;
} }

View File

@ -188,11 +188,11 @@ struct DivSample {
/** /**
* @warning DO NOT USE - internal functions * @warning DO NOT USE - internal functions
*/ */
bool resampleNone(double rate); bool resampleNone(double sRate, double tRate);
bool resampleLinear(double rate); bool resampleLinear(double sRate, double tRate);
bool resampleCubic(double rate); bool resampleCubic(double sRate, double tRate);
bool resampleBlep(double rate); bool resampleBlep(double sRate, double tRate);
bool resampleSinc(double rate); bool resampleSinc(double sRate, double tRate);
/** /**
* save this sample to a file. * save this sample to a file.
@ -262,11 +262,12 @@ struct DivSample {
/** /**
* change the sample rate. * change the sample rate.
* @warning do not attempt to resample outside of a synchronized block! * @warning do not attempt to resample outside of a synchronized block!
* @param rate number of samples. * @param sRate source rate.
* @param tRate target rate.
* @param filter the interpolation filter. * @param filter the interpolation filter.
* @return whether it was successful. * @return whether it was successful.
*/ */
bool resample(double rate, int filter); bool resample(double sRate, double tRate, int filter);
/** /**
* initialize the rest of sample formats for this sample. * initialize the rest of sample formats for this sample.

View File

@ -188,6 +188,8 @@ void FurnaceGUI::drawSampleEdit() {
for (int i=0; i<DIV_MAX_CHIPS; i++) { for (int i=0; i<DIV_MAX_CHIPS; i++) {
if (isChipVisible[i]) selColumns++; if (isChipVisible[i]) selColumns++;
} }
int targetRate=sampleCompatRate?sample->rate:sample->centerRate;
if (ImGui::BeginTable("SampleProps",(selColumns>1)?4:3,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersV|ImGuiTableFlags_BordersOuterH)) { if (ImGui::BeginTable("SampleProps",(selColumns>1)?4:3,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersV|ImGuiTableFlags_BordersOuterH)) {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
@ -286,7 +288,6 @@ void FurnaceGUI::drawSampleEdit() {
} }
} }
int targetRate=sampleCompatRate?sample->rate:sample->centerRate;
int sampleNote=round(64.0+(128.0*12.0*log((double)targetRate/8363.0)/log(2.0))); int sampleNote=round(64.0+(128.0*12.0*log((double)targetRate/8363.0)/log(2.0)));
int sampleNoteCoarse=60+(sampleNote>>7); int sampleNoteCoarse=60+(sampleNote>>7);
int sampleNoteFine=(sampleNote&127)-64; int sampleNoteFine=(sampleNote&127)-64;
@ -620,7 +621,7 @@ void FurnaceGUI::drawSampleEdit() {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Button(ICON_FA_EXPAND "##SResample"); ImGui::Button(ICON_FA_EXPAND "##SResample");
if (ImGui::IsItemClicked()) { if (ImGui::IsItemClicked()) {
resampleTarget=sample->rate; resampleTarget=targetRate;
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Resample"); ImGui::SetTooltip("Resample");
@ -641,23 +642,23 @@ void FurnaceGUI::drawSampleEdit() {
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("==")) { if (ImGui::Button("==")) {
resampleTarget=sample->rate; resampleTarget=targetRate;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("2.0x")) { if (ImGui::Button("2.0x")) {
resampleTarget*=2.0; resampleTarget*=2.0;
} }
double factor=resampleTarget/(double)sample->rate; double factor=resampleTarget/(double)targetRate;
if (ImGui::InputDouble("Factor",&factor,0.125,0.5,"%g")) { if (ImGui::InputDouble("Factor",&factor,0.125,0.5,"%g")) {
resampleTarget=(double)sample->rate*factor; resampleTarget=(double)targetRate*factor;
if (resampleTarget<0) resampleTarget=0; if (resampleTarget<0) resampleTarget=0;
if (resampleTarget>96000) resampleTarget=96000; if (resampleTarget>96000) resampleTarget=96000;
} }
ImGui::Combo("Filter",&resampleStrat,resampleStrats,6); ImGui::Combo("Filter",&resampleStrat,resampleStrats,6);
if (ImGui::Button("Resample")) { if (ImGui::Button("Resample")) {
sample->prepareUndo(true); sample->prepareUndo(true);
e->lockEngine([this,sample]() { e->lockEngine([this,sample,targetRate]() {
if (!sample->resample(resampleTarget,resampleStrat)) { if (!sample->resample(targetRate,resampleTarget,resampleStrat)) {
showError("couldn't resample! make sure your sample is 8 or 16-bit."); showError("couldn't resample! make sure your sample is 8 or 16-bit.");
} }
e->renderSamples(); e->renderSamples();
@ -670,7 +671,7 @@ void FurnaceGUI::drawSampleEdit() {
} }
ImGui::EndPopup(); ImGui::EndPopup();
} else { } else {
resampleTarget=sample->rate; resampleTarget=targetRate;
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale)); ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale));