parent
f4f91ca49e
commit
705ba4273b
|
@ -258,6 +258,42 @@ bool DivSample::trim(unsigned int begin, unsigned int end) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: for clipboard
|
||||
bool DivSample::insert(unsigned int pos, unsigned int length) {
|
||||
unsigned int count=samples+length;
|
||||
if (depth==8) {
|
||||
if (data8!=NULL) {
|
||||
signed char* oldData8=data8;
|
||||
data8=NULL;
|
||||
initInternal(8,count);
|
||||
if (pos>0) {
|
||||
memcpy(data8,oldData8,pos);
|
||||
}
|
||||
if (count-pos-length>0) {
|
||||
memcpy(data8+pos+length,oldData8+pos,count-pos-length);
|
||||
}
|
||||
delete[] oldData8;
|
||||
} else {
|
||||
initInternal(8,count);
|
||||
}
|
||||
samples=count;
|
||||
return true;
|
||||
} else if (depth==16) {
|
||||
if (data16!=NULL) {
|
||||
short* oldData16=data16;
|
||||
data16=NULL;
|
||||
initInternal(16,count);
|
||||
memcpy(data16,oldData16,sizeof(short)*count);
|
||||
delete[] oldData16;
|
||||
} else {
|
||||
initInternal(16,count);
|
||||
}
|
||||
samples=count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define RESAMPLE_BEGIN \
|
||||
if (samples<1) return true; \
|
||||
int finalCount=(double)samples*(r/(double)rate); \
|
||||
|
|
|
@ -120,6 +120,15 @@ struct DivSample {
|
|||
*/
|
||||
bool trim(unsigned int begin, unsigned int end);
|
||||
|
||||
/**
|
||||
* insert silence at specified position.
|
||||
* @warning do not attempt to do this outside of a synchronized block!
|
||||
* @param pos the beginning.
|
||||
* @param length how many samples to insert.
|
||||
* @return whether it was successful.
|
||||
*/
|
||||
bool insert(unsigned int pos, unsigned int length);
|
||||
|
||||
/**
|
||||
* change the sample rate.
|
||||
* @warning do not attempt to resample outside of a synchronized block!
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#define DETERMINE_FIRST \
|
||||
int firstChannel=0; \
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) { \
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
|
||||
#include "gui.h"
|
||||
#include <fmt/printf.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include "actionUtil.h"
|
||||
#include "sampleUtil.h"
|
||||
|
||||
void FurnaceGUI::doAction(int what) {
|
||||
switch (what) {
|
||||
|
@ -577,6 +579,370 @@ void FurnaceGUI::doAction(int what) {
|
|||
e->stopSamplePreview();
|
||||
break;
|
||||
|
||||
case GUI_ACTION_SAMPLE_SELECT:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
sampleDragMode=false;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_DRAW:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
sampleDragMode=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_CUT: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (end-start<1) break;
|
||||
|
||||
if (sampleClipboard!=NULL) {
|
||||
delete[] sampleClipboard;
|
||||
}
|
||||
sampleClipboard=new short[end-start];
|
||||
sampleClipboardLen=end-start;
|
||||
memcpy(sampleClipboard,&(sample->data16[start]),end-start);
|
||||
|
||||
e->lockEngine([this,sample,start,end]() {
|
||||
sample->strip(start,end);
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_COPY: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (end-start<1) break;
|
||||
|
||||
if (sampleClipboard!=NULL) {
|
||||
delete[] sampleClipboard;
|
||||
}
|
||||
sampleClipboard=new short[end-start];
|
||||
sampleClipboardLen=end-start;
|
||||
memcpy(sampleClipboard,&(sample->data16[start]),end-start);
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_PASTE: // TODO!!!
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_PASTE_REPLACE:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_PASTE_MIX:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_SELECT_ALL: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
sampleDragActive=false;
|
||||
sampleSelStart=0;
|
||||
sampleSelEnd=sample->samples;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_RESIZE:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
openSampleResizeOpt=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_RESAMPLE:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
openSampleResampleOpt=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_AMPLIFY:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
openSampleAmplifyOpt=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_NORMALIZE: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
float maxVal=0.0f;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data16[i]/32767.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
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) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data8[i]/127.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*vol;
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_FADE_IN: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data16[i]*float(i-start)/float(end-start);
|
||||
if (val<-32768) val=-32768;
|
||||
if (val>32767) val=32767;
|
||||
sample->data16[i]=val;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*float(i-start)/float(end-start);
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_FADE_OUT: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data16[i]*float(end-i)/float(end-start);
|
||||
if (val<-32768) val=-32768;
|
||||
if (val>32767) val=32767;
|
||||
sample->data16[i]=val;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*float(end-i)/float(end-start);
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_SILENCE: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data16[i]=0;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data8[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_DELETE: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
sample->strip(start,end);
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_TRIM: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
sample->trim(start,end);
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_REVERSE: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
unsigned int ri=end-i-1+start;
|
||||
if (ri<=i) break;
|
||||
sample->data16[i]^=sample->data16[ri];
|
||||
sample->data16[ri]^=sample->data16[i];
|
||||
sample->data16[i]^=sample->data16[ri];
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
unsigned int ri=end-i-1+start;
|
||||
if (ri<=i) break;
|
||||
sample->data8[i]^=sample->data8[ri];
|
||||
sample->data8[ri]^=sample->data8[i];
|
||||
sample->data8[i]^=sample->data8[ri];
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_INVERT: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data16[i]=-sample->data16[i];
|
||||
if (sample->data16[i]==-32768) sample->data16[i]=32767;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data8[i]=-sample->data8[i];
|
||||
if (sample->data16[i]==-128) sample->data16[i]=127;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_SIGN: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
DivSample* sample=e->song.sample[curSample];
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data16[i]^=0x8000;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data8[i]^=0x80;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_FILTER:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
openSampleFilterOpt=true;
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_PREVIEW:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
e->previewSample(curSample);
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_STOP_PREVIEW:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
e->stopSamplePreview();
|
||||
break;
|
||||
case GUI_ACTION_SAMPLE_ZOOM_IN: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
double zoomPercent=100.0/sampleZoom;
|
||||
zoomPercent+=10.0;
|
||||
if (zoomPercent>10000.0) zoomPercent=10000.0;
|
||||
if (zoomPercent<1.0) zoomPercent=1.0;
|
||||
sampleZoom=100.0/zoomPercent;
|
||||
if (sampleZoom<0.01) sampleZoom=0.01;
|
||||
sampleZoomAuto=false;
|
||||
updateSampleTex=true;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_ZOOM_OUT: {
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
double zoomPercent=100.0/sampleZoom;
|
||||
zoomPercent-=10.0;
|
||||
if (zoomPercent>10000.0) zoomPercent=10000.0;
|
||||
if (zoomPercent<1.0) zoomPercent=1.0;
|
||||
sampleZoom=100.0/zoomPercent;
|
||||
if (sampleZoom<0.01) sampleZoom=0.01;
|
||||
sampleZoomAuto=false;
|
||||
updateSampleTex=true;
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_SAMPLE_ZOOM_AUTO:
|
||||
if (curSample<0 || curSample>=(int)e->song.sample.size()) break;
|
||||
if (sampleZoomAuto) {
|
||||
sampleZoom=1.0;
|
||||
sampleZoomAuto=false;
|
||||
updateSampleTex=true;
|
||||
} else {
|
||||
sampleZoomAuto=true;
|
||||
updateSampleTex=true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_ACTION_ORDERS_UP:
|
||||
if (e->getOrder()>0) {
|
||||
e->setOrder(e->getOrder()-1);
|
||||
|
|
|
@ -918,6 +918,16 @@ void FurnaceGUI::keyDown(SDL_Event& ev) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case GUI_WINDOW_SAMPLE_EDIT:
|
||||
try {
|
||||
int action=actionMapSample.at(mapped);
|
||||
if (action>0) {
|
||||
doAction(action);
|
||||
return;
|
||||
}
|
||||
} catch (std::out_of_range& e) {
|
||||
}
|
||||
break;
|
||||
case GUI_WINDOW_INS_LIST:
|
||||
try {
|
||||
int action=actionMapInsList.at(mapped);
|
||||
|
@ -2850,7 +2860,11 @@ FurnaceGUI::FurnaceGUI():
|
|||
sampleFilterCutEnd(100.0f),
|
||||
sampleFilterPower(1),
|
||||
sampleClipboard(NULL),
|
||||
sampleClipboardLen(0) {
|
||||
sampleClipboardLen(0),
|
||||
openSampleResizeOpt(false),
|
||||
openSampleResampleOpt(false),
|
||||
openSampleAmplifyOpt(false),
|
||||
openSampleFilterOpt(false) {
|
||||
// value keys
|
||||
valueKeys[SDLK_0]=0;
|
||||
valueKeys[SDLK_1]=1;
|
||||
|
|
|
@ -364,6 +364,35 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW,
|
||||
GUI_ACTION_SAMPLE_LIST_MAX,
|
||||
|
||||
GUI_ACTION_SAMPLE_MIN,
|
||||
GUI_ACTION_SAMPLE_SELECT,
|
||||
GUI_ACTION_SAMPLE_DRAW,
|
||||
GUI_ACTION_SAMPLE_CUT,
|
||||
GUI_ACTION_SAMPLE_COPY,
|
||||
GUI_ACTION_SAMPLE_PASTE,
|
||||
GUI_ACTION_SAMPLE_PASTE_REPLACE,
|
||||
GUI_ACTION_SAMPLE_PASTE_MIX,
|
||||
GUI_ACTION_SAMPLE_SELECT_ALL,
|
||||
GUI_ACTION_SAMPLE_RESIZE,
|
||||
GUI_ACTION_SAMPLE_RESAMPLE,
|
||||
GUI_ACTION_SAMPLE_AMPLIFY,
|
||||
GUI_ACTION_SAMPLE_NORMALIZE,
|
||||
GUI_ACTION_SAMPLE_FADE_IN,
|
||||
GUI_ACTION_SAMPLE_FADE_OUT,
|
||||
GUI_ACTION_SAMPLE_SILENCE,
|
||||
GUI_ACTION_SAMPLE_DELETE,
|
||||
GUI_ACTION_SAMPLE_TRIM,
|
||||
GUI_ACTION_SAMPLE_REVERSE,
|
||||
GUI_ACTION_SAMPLE_INVERT,
|
||||
GUI_ACTION_SAMPLE_SIGN,
|
||||
GUI_ACTION_SAMPLE_FILTER,
|
||||
GUI_ACTION_SAMPLE_PREVIEW,
|
||||
GUI_ACTION_SAMPLE_STOP_PREVIEW,
|
||||
GUI_ACTION_SAMPLE_ZOOM_IN,
|
||||
GUI_ACTION_SAMPLE_ZOOM_OUT,
|
||||
GUI_ACTION_SAMPLE_ZOOM_AUTO,
|
||||
GUI_ACTION_SAMPLE_MAX,
|
||||
|
||||
GUI_ACTION_ORDERS_MIN,
|
||||
GUI_ACTION_ORDERS_UP,
|
||||
GUI_ACTION_ORDERS_DOWN,
|
||||
|
@ -677,6 +706,7 @@ class FurnaceGUI {
|
|||
std::map<int,int> actionMapGlobal;
|
||||
std::map<int,int> actionMapPat;
|
||||
std::map<int,int> actionMapOrders;
|
||||
std::map<int,int> actionMapSample;
|
||||
std::map<int,int> actionMapInsList;
|
||||
std::map<int,int> actionMapWaveList;
|
||||
std::map<int,int> actionMapSampleList;
|
||||
|
@ -778,8 +808,9 @@ class FurnaceGUI {
|
|||
unsigned int sampleDragLen;
|
||||
float sampleFilterL, sampleFilterB, sampleFilterH, sampleFilterRes, sampleFilterCutStart, sampleFilterCutEnd;
|
||||
unsigned char sampleFilterPower;
|
||||
void* sampleClipboard;
|
||||
short* sampleClipboard;
|
||||
size_t sampleClipboardLen;
|
||||
bool openSampleResizeOpt, openSampleResampleOpt, openSampleAmplifyOpt, openSampleFilterOpt;
|
||||
|
||||
// visualizer
|
||||
float keyHit[DIV_MAX_CHANS];
|
||||
|
|
|
@ -25,19 +25,7 @@
|
|||
#include "misc/cpp/imgui_stdlib.h"
|
||||
#include <fmt/printf.h>
|
||||
#include "guiConst.h"
|
||||
|
||||
#define SAMPLE_OP_BEGIN \
|
||||
unsigned int start=0; \
|
||||
unsigned int end=sample->samples; \
|
||||
if (sampleSelStart!=-1 && sampleSelEnd!=-1 && sampleSelStart!=sampleSelEnd) { \
|
||||
start=sampleSelStart; \
|
||||
end=sampleSelEnd; \
|
||||
if (start>end) { \
|
||||
start^=end; \
|
||||
end^=start; \
|
||||
start^=end; \
|
||||
} \
|
||||
} \
|
||||
#include "sampleUtil.h"
|
||||
|
||||
void FurnaceGUI::drawSampleEdit() {
|
||||
if (nextWindow==GUI_WINDOW_SAMPLE_EDIT) {
|
||||
|
@ -164,6 +152,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Resize");
|
||||
}
|
||||
if (openSampleResizeOpt) {
|
||||
openSampleResizeOpt=false;
|
||||
ImGui::OpenPopup("SResizeOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SResizeOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
if (ImGui::InputInt("Samples",&resizeSize,1,64)) {
|
||||
if (resizeSize<0) resizeSize=0;
|
||||
|
@ -194,6 +186,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Resample");
|
||||
}
|
||||
if (openSampleResampleOpt) {
|
||||
openSampleResampleOpt=false;
|
||||
ImGui::OpenPopup("SResampleOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SResampleOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::Text("Rate");
|
||||
if (ImGui::InputDouble("##SRRate",&resampleTarget,1.0,50.0,"%g")) {
|
||||
|
@ -243,6 +239,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Amplify");
|
||||
}
|
||||
if (openSampleAmplifyOpt) {
|
||||
openSampleAmplifyOpt=false;
|
||||
ImGui::OpenPopup("SAmplifyOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SAmplifyOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
ImGui::Text("Volume");
|
||||
if (ImGui::InputFloat("##SRVolume",&lifyVol,10.0,50.0,"%g%%")) {
|
||||
|
@ -283,165 +283,42 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROWS_V "##SNormalize")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
float maxVal=0.0f;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data16[i]/32767.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
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) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=fabs((float)sample->data8[i]/127.0f);
|
||||
if (val>maxVal) maxVal=val;
|
||||
}
|
||||
if (maxVal>1.0f) maxVal=1.0f;
|
||||
if (maxVal>0.0f) {
|
||||
float vol=1.0f/maxVal;
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*vol;
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_NORMALIZE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Normalize");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_UP "##SFadeIn")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data16[i]*float(i-start)/float(end-start);
|
||||
if (val<-32768) val=-32768;
|
||||
if (val>32767) val=32767;
|
||||
sample->data16[i]=val;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*float(i-start)/float(end-start);
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_FADE_IN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Fade in");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_DOWN "##SFadeOut")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data16[i]*float(end-i)/float(end-start);
|
||||
if (val<-32768) val=-32768;
|
||||
if (val>32767) val=32767;
|
||||
sample->data16[i]=val;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
float val=sample->data8[i]*float(end-i)/float(end-start);
|
||||
if (val<-128) val=-128;
|
||||
if (val>127) val=127;
|
||||
sample->data8[i]=val;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_FADE_OUT);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Fade out");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ERASER "##SSilence")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data16[i]=0;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data8[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_SILENCE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Apply silence");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_TIMES "##SDelete")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
sample->strip(start,end);
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_DELETE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Delete");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_CROP "##STrim")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
sample->trim(start,end);
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
sampleSelStart=-1;
|
||||
sampleSelEnd=-1;
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_TRIM);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Trim");
|
||||
|
@ -450,82 +327,21 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
ImGui::Dummy(ImVec2(4.0*dpiScale,dpiScale));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_BACKWARD "##SReverse")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
unsigned int ri=end-i-1+start;
|
||||
if (ri<=i) break;
|
||||
sample->data16[i]^=sample->data16[ri];
|
||||
sample->data16[ri]^=sample->data16[i];
|
||||
sample->data16[i]^=sample->data16[ri];
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
unsigned int ri=end-i-1+start;
|
||||
if (ri<=i) break;
|
||||
sample->data8[i]^=sample->data8[ri];
|
||||
sample->data8[ri]^=sample->data8[i];
|
||||
sample->data8[i]^=sample->data8[ri];
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_REVERSE);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Reverse");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_SORT_AMOUNT_ASC "##SInvert")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data16[i]=-sample->data16[i];
|
||||
if (sample->data16[i]==-32768) sample->data16[i]=32767;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data8[i]=-sample->data8[i];
|
||||
if (sample->data16[i]==-128) sample->data16[i]=127;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_INVERT);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Invert");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_LEVEL_DOWN "##SSign")) {
|
||||
e->lockEngine([this,sample]() {
|
||||
SAMPLE_OP_BEGIN;
|
||||
|
||||
if (sample->depth==16) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data16[i]^=0x8000;
|
||||
}
|
||||
} else if (sample->depth==8) {
|
||||
for (unsigned int i=start; i<end; i++) {
|
||||
sample->data8[i]^=0x80;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleTex=true;
|
||||
|
||||
e->renderSamples();
|
||||
});
|
||||
MARK_MODIFIED;
|
||||
doAction(GUI_ACTION_SAMPLE_SIGN);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Signed/unsigned exchange");
|
||||
|
@ -535,6 +351,10 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Apply filter");
|
||||
}
|
||||
if (openSampleFilterOpt) {
|
||||
openSampleFilterOpt=false;
|
||||
ImGui::OpenPopup("SFilterOpt");
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("SFilterOpt",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
float lowP=sampleFilterL*100.0f;
|
||||
float bandP=sampleFilterB*100.0f;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#define SAMPLE_OP_BEGIN \
|
||||
unsigned int start=0; \
|
||||
unsigned int end=sample->samples; \
|
||||
if (sampleSelStart!=-1 && sampleSelEnd!=-1 && sampleSelStart!=sampleSelEnd) { \
|
||||
start=sampleSelStart; \
|
||||
end=sampleSelEnd; \
|
||||
if (start>end) { \
|
||||
start^=end; \
|
||||
end^=start; \
|
||||
start^=end; \
|
||||
} \
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
#include "ImGuiFileDialog.h"
|
||||
#include "IconsFontAwesome4.h"
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
#include <SDL_keycode.h>
|
||||
#include <SDL_scancode.h>
|
||||
#include <fmt/printf.h>
|
||||
#include <imgui.h>
|
||||
|
@ -865,6 +866,39 @@ void FurnaceGUI::drawSettings() {
|
|||
KEYBIND_CONFIG_END;
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Sample editor")) {
|
||||
KEYBIND_CONFIG_BEGIN("keysSampleEdit");
|
||||
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_SELECT,"Edit mode: Select");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_DRAW,"Edit mode: Draw");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_CUT,"Cut");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_COPY,"Copy");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_PASTE,"Paste");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_PASTE_REPLACE,"Paste replace");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_PASTE_MIX,"Paste mix");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_SELECT_ALL,"Select all");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_RESIZE,"Resize");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_RESAMPLE,"Resample");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_AMPLIFY,"Amplify");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_NORMALIZE,"Normalize");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_FADE_IN,"Fade in");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_FADE_OUT,"Fade out");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_SILENCE,"Apply silence");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_DELETE,"Delete");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_TRIM,"Trim");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_REVERSE,"Reverse");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_INVERT,"Invert");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_SIGN,"Signed/unsigned exchange");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_FILTER,"Apply filter");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_PREVIEW,"Preview sample");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_STOP_PREVIEW,"Stop sample preview");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_ZOOM_IN,"Zoom in");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_ZOOM_OUT,"Zoom out");
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_SAMPLE_ZOOM_AUTO,"Toggle auto-zoom");
|
||||
|
||||
KEYBIND_CONFIG_END;
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
|
@ -1119,6 +1153,33 @@ void FurnaceGUI::syncSettings() {
|
|||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_LIST_PREVIEW,0);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW,0);
|
||||
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_SELECT,FURKMOD_SHIFT|SDLK_i);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_DRAW,FURKMOD_SHIFT|SDLK_d);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_CUT,FURKMOD_CMD|SDLK_x);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_COPY,FURKMOD_CMD|SDLK_c);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_PASTE,FURKMOD_CMD|SDLK_v);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_PASTE_REPLACE,FURKMOD_CMD|FURKMOD_SHIFT|SDLK_x);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_PASTE_MIX,FURKMOD_CMD|FURKMOD_ALT|SDLK_x);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_SELECT_ALL,FURKMOD_CMD|SDLK_a);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_RESIZE,FURKMOD_CMD|SDLK_r);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_RESAMPLE,FURKMOD_CMD|SDLK_e);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_AMPLIFY,FURKMOD_CMD|SDLK_b);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_NORMALIZE,FURKMOD_CMD|SDLK_n);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_FADE_IN,FURKMOD_CMD|SDLK_i);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_FADE_OUT,FURKMOD_CMD|SDLK_o);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_SILENCE,FURKMOD_SHIFT|SDLK_DELETE);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_DELETE,SDLK_DELETE);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_TRIM,FURKMOD_CMD|SDLK_DELETE);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_REVERSE,FURKMOD_CMD|SDLK_t);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_INVERT,FURKMOD_CMD|FURKMOD_SHIFT|SDLK_t);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_SIGN,FURKMOD_CMD|SDLK_u);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_FILTER,FURKMOD_CMD|SDLK_f);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_PREVIEW,0);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_STOP_PREVIEW,0);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_ZOOM_IN,FURKMOD_CMD|SDLK_EQUALS);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_ZOOM_OUT,FURKMOD_CMD|SDLK_MINUS);
|
||||
LOAD_KEYBIND(GUI_ACTION_SAMPLE_ZOOM_AUTO,FURKMOD_CMD|SDLK_0);
|
||||
|
||||
LOAD_KEYBIND(GUI_ACTION_ORDERS_UP,SDLK_UP);
|
||||
LOAD_KEYBIND(GUI_ACTION_ORDERS_DOWN,SDLK_DOWN);
|
||||
LOAD_KEYBIND(GUI_ACTION_ORDERS_LEFT,SDLK_LEFT);
|
||||
|
@ -1404,6 +1465,33 @@ void FurnaceGUI::commitSettings() {
|
|||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_LIST_PREVIEW);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_LIST_STOP_PREVIEW);
|
||||
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_SELECT);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_DRAW);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_CUT);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_COPY);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_PASTE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_PASTE_REPLACE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_PASTE_MIX);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_SELECT_ALL);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_RESIZE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_RESAMPLE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_AMPLIFY);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_NORMALIZE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_FADE_IN);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_FADE_OUT);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_SILENCE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_DELETE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_TRIM);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_REVERSE);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_INVERT);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_SIGN);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_FILTER);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_PREVIEW);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_STOP_PREVIEW);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_ZOOM_IN);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_ZOOM_OUT);
|
||||
SAVE_KEYBIND(GUI_ACTION_SAMPLE_ZOOM_AUTO);
|
||||
|
||||
SAVE_KEYBIND(GUI_ACTION_ORDERS_UP);
|
||||
SAVE_KEYBIND(GUI_ACTION_ORDERS_DOWN);
|
||||
SAVE_KEYBIND(GUI_ACTION_ORDERS_LEFT);
|
||||
|
@ -1454,6 +1542,7 @@ void FurnaceGUI::parseKeybinds() {
|
|||
actionMapInsList.clear();
|
||||
actionMapWaveList.clear();
|
||||
actionMapSampleList.clear();
|
||||
actionMapSample.clear();
|
||||
actionMapOrders.clear();
|
||||
|
||||
for (int i=GUI_ACTION_GLOBAL_MIN+1; i<GUI_ACTION_GLOBAL_MAX; i++) {
|
||||
|
@ -1486,6 +1575,12 @@ void FurnaceGUI::parseKeybinds() {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i=GUI_ACTION_SAMPLE_MIN+1; i<GUI_ACTION_SAMPLE_MAX; i++) {
|
||||
if (actionKeys[i]&FURK_MASK) {
|
||||
actionMapSample[actionKeys[i]]=i;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=GUI_ACTION_ORDERS_MIN+1; i<GUI_ACTION_ORDERS_MAX; i++) {
|
||||
if (actionKeys[i]&FURK_MASK) {
|
||||
actionMapOrders[actionKeys[i]]=i;
|
||||
|
|
Loading…
Reference in New Issue