Partially ES5506 support (not working yet!)

Add sample related enums
Add support for backward/pingpong loop, loop end position
Structize Notemap in sample instrument
This commit is contained in:
cam900 2022-04-21 01:52:37 +09:00
parent 96715ed88c
commit 29ea6dc360
50 changed files with 4501 additions and 248 deletions

View file

@ -41,7 +41,7 @@ void FurnaceGUI::drawSampleEdit() {
} else {
DivSample* sample=e->song.sample[curSample];
String sampleType="Invalid";
if (sample->depth<17) {
if (sample->depth<DIV_SAMPLE_DEPTH_MAX) {
if (sampleDepths[sample->depth]!=NULL) {
sampleType=sampleDepths[sample->depth];
}
@ -61,11 +61,11 @@ void FurnaceGUI::drawSampleEdit() {
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::BeginCombo("##SampleType",sampleType.c_str())) {
for (int i=0; i<17; i++) {
for (int i=0; i<DIV_SAMPLE_DEPTH_MAX; i++) {
if (sampleDepths[i]==NULL) continue;
if (ImGui::Selectable(sampleDepths[i])) {
sample->prepareUndo(true);
sample->depth=i;
sample->depth=DivSampleDepth(i);
e->renderSamplesP();
updateSampleTex=true;
MARK_MODIFIED;
@ -93,22 +93,54 @@ void FurnaceGUI::drawSampleEdit() {
}
ImGui::TableNextColumn();
bool doLoop=(sample->loopStart>=0);
if (ImGui::Checkbox("Loop",&doLoop)) { MARK_MODIFIED
if (doLoop) {
ImGui::Text("Loop Mode");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
int mode=(int)sample->loopMode;
if (ImGui::Combo("##LoopMode",&mode,loopMode,DIV_SAMPLE_LOOPMODE_MAX,DIV_SAMPLE_LOOPMODE_MAX)) { MARK_MODIFIED
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
sample->loopStart=0;
} else {
sample->loopStart=-1;
}
if (sample->loopEnd>sample->samples) {
sample->loopEnd=sample->samples;
}
sample->loopMode=DivSampleLoopMode(mode);
updateSampleTex=true;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Length: %d",sample->samples);
bool doLoop=(sample->loopMode!=DIV_SAMPLE_LOOPMODE_ONESHOT);
if (doLoop) {
ImGui::TableNextColumn();
ImGui::Text("Loop start");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##LoopPosition",&sample->loopStart,1,10)) { MARK_MODIFIED
if (ImGui::InputInt("##LoopStart",&sample->loopStart,1,10)) { MARK_MODIFIED
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
sample->loopStart=0;
}
if (sample->loopStart>=(int)sample->loopEnd) {
sample->loopStart=sample->loopEnd;
}
updateSampleTex=true;
}
ImGui::TableNextColumn();
ImGui::Text("Loop End");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
int end=(int)sample->loopEnd;
if (ImGui::InputInt("##LoopEnd",&end,1,10)) { MARK_MODIFIED
if (end<0) {
end=0;
}
if (end<sample->loopStart) {
end=sample->loopStart;
}
if (end>sample->samples) {
end=sample->samples;
}
sample->loopEnd=end;
updateSampleTex=true;
}
}
@ -123,7 +155,7 @@ void FurnaceGUI::drawSampleEdit() {
*/
ImGui::Separator();
ImGui::BeginDisabled(sample->depth!=8 && sample->depth!=16);
ImGui::BeginDisabled(sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT);
ImGui::PushStyleColor(ImGuiCol_Button,TOGGLE_COLOR(!sampleDragMode));
if (ImGui::Button(ICON_FA_I_CURSOR "##SSelect")) {
@ -275,14 +307,14 @@ void FurnaceGUI::drawSampleEdit() {
SAMPLE_OP_BEGIN;
float vol=amplifyVol/100.0f;
if (sample->depth==16) {
if (sample->depth==DIV_SAMPLE_DEPTH_16BIT) {
for (unsigned int i=start; i<end; i++) {
float val=sample->data16[i]*vol;
if (val<-32768) val=-32768;
if (val>32767) val=32767;
sample->data16[i]=val;
}
} else if (sample->depth==8) {
} else if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
for (unsigned int i=start; i<end; i++) {
float val=sample->data8[i]*vol;
if (val<-128) val=-128;
@ -466,7 +498,7 @@ void FurnaceGUI::drawSampleEdit() {
double power=(sampleFilterCutStart>sampleFilterCutEnd)?0.5:2.0;
if (sample->depth==16) {
if (sample->depth==DIV_SAMPLE_DEPTH_16BIT) {
for (unsigned int i=start; i<end; i++) {
double freq=sampleFilterCutStart+(sampleFilterCutEnd-sampleFilterCutStart)*pow(double(i-start)/double(end-start),power);
double cut=sin((freq/double(sample->rate))*M_PI);
@ -482,7 +514,7 @@ void FurnaceGUI::drawSampleEdit() {
if (val>32767) val=32767;
sample->data16[i]=val;
}
} else if (sample->depth==8) {
} else if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
for (unsigned int i=start; i<end; i++) {
double freq=sampleFilterCutStart+(sampleFilterCutEnd-sampleFilterCutStart)*pow(double(i-start)/double(end-start),power);
double cut=sin((freq/double(sample->rate))*M_PI);
@ -574,11 +606,11 @@ void FurnaceGUI::drawSampleEdit() {
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::BeginCombo("##SampleType",sampleType.c_str())) {
for (int i=0; i<17; i++) {
for (int i=0; i<DIV_SAMPLE_DEPTH_MAX; i++) {
if (sampleDepths[i]==NULL) continue;
if (ImGui::Selectable(sampleDepths[i])) {
sample->prepareUndo(true);
sample->depth=i;
sample->depth=DivSampleDepth(i);
e->renderSamplesP();
updateSampleTex=true;
MARK_MODIFIED;
@ -607,22 +639,55 @@ void FurnaceGUI::drawSampleEdit() {
}
ImGui::TableNextColumn();
bool doLoop=(sample->loopStart>=0);
if (ImGui::Checkbox("Loop",&doLoop)) { MARK_MODIFIED
if (doLoop) {
ImGui::Text("Loop Mode");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
int mode=(int)sample->loopMode;
if (ImGui::Combo("##LoopMode",&mode,loopMode,DIV_SAMPLE_LOOPMODE_MAX,DIV_SAMPLE_LOOPMODE_MAX)) { MARK_MODIFIED
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
sample->loopStart=0;
} else {
sample->loopStart=-1;
}
if (sample->loopEnd>sample->samples) {
sample->loopEnd=sample->samples;
}
sample->loopMode=DivSampleLoopMode(mode);
updateSampleTex=true;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Length: %d",sample->samples);
bool doLoop=(sample->loopMode!=DIV_SAMPLE_LOOPMODE_ONESHOT);
if (doLoop) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Loop start");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##LoopPosition",&sample->loopStart,1,10)) { MARK_MODIFIED
if (ImGui::InputInt("##LoopStart",&sample->loopStart,1,10)) { MARK_MODIFIED
if (sample->loopStart<0 || sample->loopStart>=(int)sample->samples) {
sample->loopStart=0;
}
if (sample->loopStart>=(int)sample->loopEnd) {
sample->loopStart=loopEnd;
}
updateSampleTex=true;
}
ImGui::TableNextColumn();
ImGui::Text("Loop End");
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
int end=(int)sample->loopEnd;
if (ImGui::InputInt("##LoopEnd",&end,1,10)) { MARK_MODIFIED
if (end<0) {
end=0;
}
if (end<sample->loopStart) {
end=sample->loopStart;
}
if (end>sample->samples) {
end=sample->samples;
}
sample->loopEnd=end;
updateSampleTex=true;
}
}
@ -637,7 +702,7 @@ void FurnaceGUI::drawSampleEdit() {
*/
ImGui::Separator();
ImGui::BeginDisabled(sample->depth!=8 && sample->depth!=16);
ImGui::BeginDisabled(sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT);
ImGui::PushStyleColor(ImGuiCol_Button,TOGGLE_COLOR(!sampleDragMode));
if (ImGui::Button(ICON_FA_I_CURSOR "##SSelect")) {
@ -820,7 +885,7 @@ void FurnaceGUI::drawSampleEdit() {
double power=(sampleFilterCutStart>sampleFilterCutEnd)?0.5:2.0;
if (sample->depth==16) {
if (sample->depth==DIV_SAMPLE_DEPTH_16BIT) {
for (unsigned int i=start; i<end; i++) {
double freq=sampleFilterCutStart+(sampleFilterCutEnd-sampleFilterCutStart)*pow(double(i-start)/double(end-start),power);
double cut=sin((freq/double(sample->rate))*M_PI);
@ -836,7 +901,7 @@ void FurnaceGUI::drawSampleEdit() {
if (val>32767) val=32767;
sample->data16[i]=val;
}
} else if (sample->depth==8) {
} else if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
for (unsigned int i=start; i<end; i++) {
double freq=sampleFilterCutStart+(sampleFilterCutEnd-sampleFilterCutStart)*pow(double(i-start)/double(end-start),power);
double cut=sin((freq/double(sample->rate))*M_PI);
@ -890,14 +955,14 @@ void FurnaceGUI::drawSampleEdit() {
SAMPLE_OP_BEGIN;
float vol=amplifyVol/100.0f;
if (sample->depth==16) {
if (sample->depth==DIV_SAMPLE_DEPTH_16BIT) {
for (unsigned int i=start; i<end; i++) {
float val=sample->data16[i]*vol;
if (val<-32768) val=-32768;
if (val>32767) val=32767;
sample->data16[i]=val;
}
} else if (sample->depth==8) {
} else if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
for (unsigned int i=start; i<end; i++) {
float val=sample->data8[i]*vol;
if (val<-128) val=-128;
@ -1137,7 +1202,8 @@ void FurnaceGUI::drawSampleEdit() {
ImU32 centerLineColor=ImAlphaBlendColors(bgColor,ImGui::GetColorU32(ImGuiCol_PlotLines,0.25));
for (int i=0; i<availY; i++) {
for (int j=0; j<availX; j++) {
if (sample->loopStart>=0 && sample->loopStart<(int)sample->samples && ((j+samplePos)*sampleZoom)>sample->loopStart) {
int scaledPos=samplePos+(j*sampleZoom);
if (sample->isLoopable() && ((scaledPos>=sample->loopStart) && (scaledPos<sample->loopEnd))) {
data[i*availX+j]=bgColorLoop;
} else {
data[i*availX+j]=bgColor;
@ -1157,7 +1223,7 @@ void FurnaceGUI::drawSampleEdit() {
if (xCoarse>=sample->samples) break;
int y1, y2;
int totalAdvance=0;
if (sample->depth==8) {
if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
y1=((unsigned char)sample->data8[xCoarse]^0x80)*availY/256;
} else {
y1=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536;
@ -1170,7 +1236,7 @@ void FurnaceGUI::drawSampleEdit() {
totalAdvance+=xAdvanceCoarse;
if (xCoarse>=sample->samples) break;
do {
if (sample->depth==8) {
if (sample->depth==DIV_SAMPLE_DEPTH_8BIT) {
y2=((unsigned char)sample->data8[xCoarse]^0x80)*availY/256;
} else {
y2=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536;
@ -1208,11 +1274,11 @@ void FurnaceGUI::drawSampleEdit() {
sampleSelStart=0;
sampleSelEnd=sample->samples;
} else {
if (sample->samples>0 && (sample->depth==16 || sample->depth==8)) {
if (sample->samples>0 && (sample->depth==DIV_SAMPLE_DEPTH_16BIT || sample->depth==DIV_SAMPLE_DEPTH_8BIT)) {
sampleDragStart=rectMin;
sampleDragAreaSize=rectSize;
sampleDrag16=(sample->depth==16);
sampleDragTarget=(sample->depth==16)?((void*)sample->data16):((void*)sample->data8);
sampleDrag16=(sample->depth==DIV_SAMPLE_DEPTH_16BIT);
sampleDragTarget=(sample->depth==DIV_SAMPLE_DEPTH_16BIT)?((void*)sample->data16):((void*)sample->data8);
sampleDragLen=sample->samples;
sampleDragActive=true;
sampleSelStart=-1;
@ -1277,7 +1343,7 @@ void FurnaceGUI::drawSampleEdit() {
posX=samplePos+pos.x*sampleZoom;
if (posX>(int)sample->samples) posX=-1;
}
posY=(0.5-pos.y/rectSize.y)*((sample->depth==8)?255:32767);
posY=(0.5-pos.y/rectSize.y)*((sample->depth==DIV_SAMPLE_DEPTH_8BIT)?255:32767);
if (posX>=0) {
statusBar+=fmt::sprintf(" | (%d, %d)",posX,posY);
}
@ -1325,7 +1391,7 @@ void FurnaceGUI::drawSampleEdit() {
}
}
if (sample->depth!=8 && sample->depth!=16) {
if (sample->depth!=DIV_SAMPLE_DEPTH_8BIT && sample->depth!=DIV_SAMPLE_DEPTH_16BIT) {
statusBar="Non-8/16-bit samples cannot be edited without prior conversion.";
}