Implement sample loop end position, enum-ise sample depth (#557)
TODO: new sample format
This commit is contained in:
parent
a137eefd20
commit
5127d5ef18
29 changed files with 461 additions and 306 deletions
|
|
@ -38,6 +38,65 @@ DivSampleHistory::~DivSampleHistory() {
|
|||
if (data!=NULL) delete[] data;
|
||||
}
|
||||
|
||||
bool DivSample::isLoopable() {
|
||||
return (loopStart>=0 && loopStart<loopEnd) && (loopEnd>loopStart && loopEnd<=(int)samples);
|
||||
}
|
||||
|
||||
unsigned int DivSample::getEndPosition(DivSampleDepth depth) {
|
||||
int end=loopEnd;
|
||||
unsigned int len=samples;
|
||||
switch (depth) {
|
||||
case DIV_SAMPLE_DEPTH_1BIT:
|
||||
end=(loopEnd+7)/8;
|
||||
len=length1;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_1BIT_DPCM:
|
||||
end=(loopEnd+7)/8;
|
||||
len=lengthDPCM;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_YMZ_ADPCM:
|
||||
end=(loopEnd+1)/2;
|
||||
len=lengthZ;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM:
|
||||
end=(loopEnd+1)/2;
|
||||
len=lengthQSoundA;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_A:
|
||||
end=(loopEnd+1)/2;
|
||||
len=lengthA;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_B:
|
||||
end=(loopEnd+1)/2;
|
||||
len=lengthB;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_8BIT:
|
||||
end=loopEnd;
|
||||
len=length8;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_BRR:
|
||||
end=9*((loopEnd+15)/16);
|
||||
len=lengthBRR;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
end=(loopEnd+1)/2;
|
||||
len=lengthVOX;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
end=loopEnd*2;
|
||||
len=length16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return isLoopable()?end:len;
|
||||
}
|
||||
|
||||
void DivSample::setSampleCount(unsigned int count) {
|
||||
samples=count;
|
||||
if ((!isLoopable()) || loopEnd<0 || loopEnd>(int)samples) loopEnd=samples;
|
||||
}
|
||||
|
||||
bool DivSample::save(const char* path) {
|
||||
#ifndef HAVE_SNDFILE
|
||||
logE("Furnace was not compiled with libsndfile!");
|
||||
|
|
@ -53,7 +112,7 @@ bool DivSample::save(const char* path) {
|
|||
si.channels=1;
|
||||
si.samplerate=rate;
|
||||
switch (depth) {
|
||||
case 8: // 8-bit
|
||||
case DIV_SAMPLE_DEPTH_8BIT: // 8-bit
|
||||
si.format=SF_FORMAT_PCM_U8|SF_FORMAT_WAV;
|
||||
break;
|
||||
default: // 16-bit
|
||||
|
|
@ -76,17 +135,17 @@ bool DivSample::save(const char* path) {
|
|||
inst.detune = 50 - (pitch % 100);
|
||||
inst.velocity_hi = 0x7f;
|
||||
inst.key_hi = 0x7f;
|
||||
if(loopStart != -1)
|
||||
if(isLoopable())
|
||||
{
|
||||
inst.loop_count = 1;
|
||||
inst.loops[0].mode = SF_LOOP_FORWARD;
|
||||
inst.loops[0].start = loopStart;
|
||||
inst.loops[0].end = samples;
|
||||
inst.loops[0].end = loopEnd;
|
||||
}
|
||||
sf_command(f, SFC_SET_INSTRUMENT, &inst, sizeof(inst));
|
||||
|
||||
switch (depth) {
|
||||
case 8: {
|
||||
case DIV_SAMPLE_DEPTH_8BIT: {
|
||||
// convert from signed to unsigned
|
||||
unsigned char* buf=new unsigned char[length8];
|
||||
for (size_t i=0; i<length8; i++) {
|
||||
|
|
@ -108,65 +167,65 @@ bool DivSample::save(const char* path) {
|
|||
}
|
||||
|
||||
// 16-bit memory is padded to 512, to make things easier for ADPCM-A/B.
|
||||
bool DivSample::initInternal(unsigned char d, int count) {
|
||||
bool DivSample::initInternal(DivSampleDepth d, int count) {
|
||||
switch (d) {
|
||||
case 0: // 1-bit
|
||||
case DIV_SAMPLE_DEPTH_1BIT: // 1-bit
|
||||
if (data1!=NULL) delete[] data1;
|
||||
length1=(count+7)/8;
|
||||
data1=new unsigned char[length1];
|
||||
memset(data1,0,length1);
|
||||
break;
|
||||
case 1: // DPCM
|
||||
case DIV_SAMPLE_DEPTH_1BIT_DPCM: // DPCM
|
||||
if (dataDPCM!=NULL) delete[] dataDPCM;
|
||||
lengthDPCM=(count+7)/8;
|
||||
dataDPCM=new unsigned char[lengthDPCM];
|
||||
memset(dataDPCM,0,lengthDPCM);
|
||||
break;
|
||||
case 3: // YMZ ADPCM
|
||||
case DIV_SAMPLE_DEPTH_YMZ_ADPCM: // YMZ ADPCM
|
||||
if (dataZ!=NULL) delete[] dataZ;
|
||||
lengthZ=(count+1)/2;
|
||||
// for padding AICA sample
|
||||
dataZ=new unsigned char[(lengthZ+3)&(~0x03)];
|
||||
memset(dataZ,0,(lengthZ+3)&(~0x03));
|
||||
break;
|
||||
case 4: // QSound ADPCM
|
||||
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM: // QSound ADPCM
|
||||
if (dataQSoundA!=NULL) delete[] dataQSoundA;
|
||||
lengthQSoundA=(count+1)/2;
|
||||
dataQSoundA=new unsigned char[lengthQSoundA];
|
||||
memset(dataQSoundA,0,lengthQSoundA);
|
||||
break;
|
||||
case 5: // ADPCM-A
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_A: // ADPCM-A
|
||||
if (dataA!=NULL) delete[] dataA;
|
||||
lengthA=(count+1)/2;
|
||||
dataA=new unsigned char[(lengthA+255)&(~0xff)];
|
||||
memset(dataA,0,(lengthA+255)&(~0xff));
|
||||
break;
|
||||
case 6: // ADPCM-B
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_B: // ADPCM-B
|
||||
if (dataB!=NULL) delete[] dataB;
|
||||
lengthB=(count+1)/2;
|
||||
dataB=new unsigned char[(lengthB+255)&(~0xff)];
|
||||
memset(dataB,0,(lengthB+255)&(~0xff));
|
||||
break;
|
||||
case 8: // 8-bit
|
||||
case DIV_SAMPLE_DEPTH_8BIT: // 8-bit
|
||||
if (data8!=NULL) delete[] data8;
|
||||
length8=count;
|
||||
// for padding X1-010 sample
|
||||
data8=new signed char[(count+4095)&(~0xfff)];
|
||||
memset(data8,0,(count+4095)&(~0xfff));
|
||||
break;
|
||||
case 9: // BRR
|
||||
case DIV_SAMPLE_DEPTH_BRR: // BRR
|
||||
if (dataBRR!=NULL) delete[] dataBRR;
|
||||
lengthBRR=9*((count+15)/16);
|
||||
dataBRR=new unsigned char[lengthBRR];
|
||||
memset(dataBRR,0,lengthBRR);
|
||||
break;
|
||||
case 10: // VOX
|
||||
case DIV_SAMPLE_DEPTH_VOX: // VOX
|
||||
if (dataVOX!=NULL) delete[] dataVOX;
|
||||
lengthVOX=(count+1)/2;
|
||||
dataVOX=new unsigned char[lengthVOX];
|
||||
memset(dataVOX,0,lengthVOX);
|
||||
break;
|
||||
case 16: // 16-bit
|
||||
case DIV_SAMPLE_DEPTH_16BIT: // 16-bit
|
||||
if (data16!=NULL) delete[] data16;
|
||||
length16=count*2;
|
||||
data16=new short[(count+511)&(~0x1ff)];
|
||||
|
|
@ -180,34 +239,34 @@ bool DivSample::initInternal(unsigned char d, int count) {
|
|||
|
||||
bool DivSample::init(unsigned int count) {
|
||||
if (!initInternal(depth,count)) return false;
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DivSample::resize(unsigned int count) {
|
||||
if (depth==8) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
if (data8!=NULL) {
|
||||
signed char* oldData8=data8;
|
||||
data8=NULL;
|
||||
initInternal(8,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,count);
|
||||
memcpy(data8,oldData8,MIN(count,samples));
|
||||
delete[] oldData8;
|
||||
} else {
|
||||
initInternal(8,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,count);
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
} else if (depth==16) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (data16!=NULL) {
|
||||
short* oldData16=data16;
|
||||
data16=NULL;
|
||||
initInternal(16,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,count);
|
||||
memcpy(data16,oldData16,sizeof(short)*MIN(count,samples));
|
||||
delete[] oldData16;
|
||||
} else {
|
||||
initInternal(16,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,count);
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -218,11 +277,11 @@ bool DivSample::strip(unsigned int begin, unsigned int end) {
|
|||
if (end>samples) end=samples;
|
||||
int count=samples-(end-begin);
|
||||
if (count<=0) return resize(0);
|
||||
if (depth==8) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
if (data8!=NULL) {
|
||||
signed char* oldData8=data8;
|
||||
data8=NULL;
|
||||
initInternal(8,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,count);
|
||||
if (begin>0) {
|
||||
memcpy(data8,oldData8,begin);
|
||||
}
|
||||
|
|
@ -234,13 +293,13 @@ bool DivSample::strip(unsigned int begin, unsigned int end) {
|
|||
// do nothing
|
||||
return true;
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
} else if (depth==16) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (data16!=NULL) {
|
||||
short* oldData16=data16;
|
||||
data16=NULL;
|
||||
initInternal(16,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,count);
|
||||
if (begin>0) {
|
||||
memcpy(data16,oldData16,sizeof(short)*begin);
|
||||
}
|
||||
|
|
@ -252,7 +311,7 @@ bool DivSample::strip(unsigned int begin, unsigned int end) {
|
|||
// do nothing
|
||||
return true;
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -262,31 +321,31 @@ bool DivSample::trim(unsigned int begin, unsigned int end) {
|
|||
int count=end-begin;
|
||||
if (count==0) return true;
|
||||
if (begin==0 && end==samples) return true;
|
||||
if (depth==8) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
if (data8!=NULL) {
|
||||
signed char* oldData8=data8;
|
||||
data8=NULL;
|
||||
initInternal(8,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,count);
|
||||
memcpy(data8,oldData8+begin,count);
|
||||
delete[] oldData8;
|
||||
} else {
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
} else if (depth==16) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (data16!=NULL) {
|
||||
short* oldData16=data16;
|
||||
data16=NULL;
|
||||
initInternal(16,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,count);
|
||||
memcpy(data16,&(oldData16[begin]),sizeof(short)*count);
|
||||
delete[] oldData16;
|
||||
} else {
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -294,11 +353,11 @@ bool DivSample::trim(unsigned int begin, unsigned int end) {
|
|||
|
||||
bool DivSample::insert(unsigned int pos, unsigned int length) {
|
||||
unsigned int count=samples+length;
|
||||
if (depth==8) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
if (data8!=NULL) {
|
||||
signed char* oldData8=data8;
|
||||
data8=NULL;
|
||||
initInternal(8,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,count);
|
||||
if (pos>0) {
|
||||
memcpy(data8,oldData8,pos);
|
||||
}
|
||||
|
|
@ -307,15 +366,15 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
|
|||
}
|
||||
delete[] oldData8;
|
||||
} else {
|
||||
initInternal(8,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,count);
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
} else if (depth==16) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (data16!=NULL) {
|
||||
short* oldData16=data16;
|
||||
data16=NULL;
|
||||
initInternal(16,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,count);
|
||||
if (pos>0) {
|
||||
memcpy(data16,oldData16,sizeof(short)*pos);
|
||||
}
|
||||
|
|
@ -324,9 +383,9 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
|
|||
}
|
||||
delete[] oldData16;
|
||||
} else {
|
||||
initInternal(16,count);
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,count);
|
||||
}
|
||||
samples=count;
|
||||
setSampleCount(count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -337,15 +396,15 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
|
|||
int finalCount=(double)samples*(r/(double)rate); \
|
||||
signed char* oldData8=data8; \
|
||||
short* oldData16=data16; \
|
||||
if (depth==16) { \
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) { \
|
||||
if (data16!=NULL) { \
|
||||
data16=NULL; \
|
||||
initInternal(16,finalCount); \
|
||||
initInternal(DIV_SAMPLE_DEPTH_16BIT,finalCount); \
|
||||
} \
|
||||
} else if (depth==8) { \
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) { \
|
||||
if (data8!=NULL) { \
|
||||
data8=NULL; \
|
||||
initInternal(8,finalCount); \
|
||||
initInternal(DIV_SAMPLE_DEPTH_8BIT,finalCount); \
|
||||
} \
|
||||
} else { \
|
||||
return false; \
|
||||
|
|
@ -353,19 +412,20 @@ bool DivSample::insert(unsigned int pos, unsigned int length) {
|
|||
|
||||
#define RESAMPLE_END \
|
||||
if (loopStart>=0) loopStart=(double)loopStart*(r/(double)rate); \
|
||||
if (loopEnd>=0) loopEnd=(double)loopEnd*(r/(double)rate); \
|
||||
centerRate=(int)((double)centerRate*(r/(double)rate)); \
|
||||
rate=r; \
|
||||
samples=finalCount; \
|
||||
if (depth==16) { \
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) { \
|
||||
delete[] oldData16; \
|
||||
} else if (depth==8) { \
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) { \
|
||||
delete[] oldData8; \
|
||||
}
|
||||
|
||||
bool DivSample::resampleNone(double r) {
|
||||
RESAMPLE_BEGIN;
|
||||
|
||||
if (depth==16) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
unsigned int pos=(unsigned int)((double)i*((double)rate/r));
|
||||
if (pos>=samples) {
|
||||
|
|
@ -374,7 +434,7 @@ bool DivSample::resampleNone(double r) {
|
|||
data16[i]=oldData16[pos];
|
||||
}
|
||||
}
|
||||
} else if (depth==8) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
unsigned int pos=(unsigned int)((double)i*((double)rate/r));
|
||||
if (pos>=samples) {
|
||||
|
|
@ -396,7 +456,7 @@ bool DivSample::resampleLinear(double r) {
|
|||
unsigned int posInt=0;
|
||||
double factor=(double)rate/r;
|
||||
|
||||
if (depth==16) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
short s1=(posInt>=samples)?0:oldData16[posInt];
|
||||
short s2=(posInt+1>=samples)?((loopStart>=0 && loopStart<(int)samples)?oldData16[loopStart]:0):oldData16[posInt+1];
|
||||
|
|
@ -409,7 +469,7 @@ bool DivSample::resampleLinear(double r) {
|
|||
posInt++;
|
||||
}
|
||||
}
|
||||
} else if (depth==8) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
short s1=(posInt>=samples)?0:oldData8[posInt];
|
||||
short s2=(posInt+1>=samples)?((loopStart>=0 && loopStart<(int)samples)?oldData8[loopStart]:0):oldData8[posInt+1];
|
||||
|
|
@ -436,7 +496,7 @@ bool DivSample::resampleCubic(double r) {
|
|||
double factor=(double)rate/r;
|
||||
float* cubicTable=DivFilterTables::getCubicTable();
|
||||
|
||||
if (depth==16) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
unsigned int n=((unsigned int)(posFrac*1024.0))&1023;
|
||||
float* t=&cubicTable[n<<2];
|
||||
|
|
@ -456,7 +516,7 @@ bool DivSample::resampleCubic(double r) {
|
|||
posInt++;
|
||||
}
|
||||
}
|
||||
} else if (depth==8) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
unsigned int n=((unsigned int)(posFrac*1024.0))&1023;
|
||||
float* t=&cubicTable[n<<2];
|
||||
|
|
@ -493,7 +553,7 @@ bool DivSample::resampleBlep(double r) {
|
|||
|
||||
memset(s,0,16*sizeof(float));
|
||||
|
||||
if (depth==16) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
memset(data16,0,finalCount*sizeof(short));
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
if (posInt<samples) {
|
||||
|
|
@ -529,7 +589,7 @@ bool DivSample::resampleBlep(double r) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (depth==8) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
memset(data8,0,finalCount);
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
if (posInt<samples) {
|
||||
|
|
@ -582,7 +642,7 @@ bool DivSample::resampleSinc(double r) {
|
|||
|
||||
memset(s,0,16*sizeof(float));
|
||||
|
||||
if (depth==16) {
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
for (int i=0; i<finalCount+8; i++) {
|
||||
unsigned int n=((unsigned int)(posFrac*8192.0))&8191;
|
||||
float result=0;
|
||||
|
|
@ -607,7 +667,7 @@ bool DivSample::resampleSinc(double r) {
|
|||
s[15]=(posInt>=samples)?0:oldData16[posInt];
|
||||
}
|
||||
}
|
||||
} else if (depth==8) {
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
for (int i=0; i<finalCount+8; i++) {
|
||||
unsigned int n=((unsigned int)(posFrac*8192.0))&8191;
|
||||
float result=0;
|
||||
|
|
@ -639,7 +699,7 @@ bool DivSample::resampleSinc(double r) {
|
|||
}
|
||||
|
||||
bool DivSample::resample(double r, int filter) {
|
||||
if (depth!=8 && depth!=16) return false;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_8BIT && depth!=DIV_SAMPLE_DEPTH_16BIT) return false;
|
||||
switch (filter) {
|
||||
case DIV_RESAMPLE_NONE:
|
||||
return resampleNone(r);
|
||||
|
|
@ -669,15 +729,15 @@ bool DivSample::resample(double r, int filter) {
|
|||
|
||||
void DivSample::render() {
|
||||
// step 1: convert to 16-bit if needed
|
||||
if (depth!=16) {
|
||||
if (!initInternal(16,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_16BIT,samples)) return;
|
||||
switch (depth) {
|
||||
case 0: // 1-bit
|
||||
case DIV_SAMPLE_DEPTH_1BIT: // 1-bit
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
data16[i]=((data1[i>>3]>>(i&7))&1)?0x7fff:-0x7fff;
|
||||
}
|
||||
break;
|
||||
case 1: { // DPCM
|
||||
case DIV_SAMPLE_DEPTH_1BIT_DPCM: { // DPCM
|
||||
int accum=0;
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
accum+=((dataDPCM[i>>3]>>(i&7))&1)?1:-1;
|
||||
|
|
@ -687,27 +747,27 @@ void DivSample::render() {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 3: // YMZ ADPCM
|
||||
case DIV_SAMPLE_DEPTH_YMZ_ADPCM: // YMZ ADPCM
|
||||
ymz_decode(dataZ,data16,samples);
|
||||
break;
|
||||
case 4: // QSound ADPCM
|
||||
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM: // QSound ADPCM
|
||||
bs_decode(dataQSoundA,data16,samples);
|
||||
break;
|
||||
case 5: // ADPCM-A
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_A: // ADPCM-A
|
||||
yma_decode(dataA,data16,samples);
|
||||
break;
|
||||
case 6: // ADPCM-B
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_B: // ADPCM-B
|
||||
ymb_decode(dataB,data16,samples);
|
||||
break;
|
||||
case 8: // 8-bit PCM
|
||||
case DIV_SAMPLE_DEPTH_8BIT: // 8-bit PCM
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
data16[i]=data8[i]<<8;
|
||||
}
|
||||
break;
|
||||
case 9: // BRR
|
||||
case DIV_SAMPLE_DEPTH_BRR: // BRR
|
||||
// TODO!
|
||||
break;
|
||||
case 10: // VOX
|
||||
case DIV_SAMPLE_DEPTH_VOX: // VOX
|
||||
oki_decode(dataVOX,data16,samples);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -716,16 +776,16 @@ void DivSample::render() {
|
|||
}
|
||||
|
||||
// step 2: render to other formats
|
||||
if (depth!=0) { // 1-bit
|
||||
if (!initInternal(0,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_1BIT) { // 1-bit
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_1BIT,samples)) return;
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
if (data16[i]>0) {
|
||||
data1[i>>3]|=1<<(i&7);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (depth!=1) { // DPCM
|
||||
if (!initInternal(1,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_1BIT_DPCM) { // DPCM
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_1BIT_DPCM,samples)) return;
|
||||
int accum=63;
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
int next=((unsigned short)(data16[i]^0x8000))>>9;
|
||||
|
|
@ -739,84 +799,88 @@ void DivSample::render() {
|
|||
if (accum>127) accum=127;
|
||||
}
|
||||
}
|
||||
if (depth!=3) { // YMZ ADPCM
|
||||
if (!initInternal(3,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_YMZ_ADPCM) { // YMZ ADPCM
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_YMZ_ADPCM,samples)) return;
|
||||
ymz_encode(data16,dataZ,(samples+7)&(~0x7));
|
||||
}
|
||||
if (depth!=4) { // QSound ADPCM
|
||||
if (!initInternal(4,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_QSOUND_ADPCM) { // QSound ADPCM
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_QSOUND_ADPCM,samples)) return;
|
||||
bs_encode(data16,dataQSoundA,samples);
|
||||
}
|
||||
// TODO: pad to 256.
|
||||
if (depth!=5) { // ADPCM-A
|
||||
if (!initInternal(5,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_ADPCM_A) { // ADPCM-A
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_ADPCM_A,samples)) return;
|
||||
yma_encode(data16,dataA,(samples+511)&(~0x1ff));
|
||||
}
|
||||
if (depth!=6) { // ADPCM-B
|
||||
if (!initInternal(6,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_ADPCM_B) { // ADPCM-B
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_ADPCM_B,samples)) return;
|
||||
ymb_encode(data16,dataB,(samples+511)&(~0x1ff));
|
||||
}
|
||||
if (depth!=8) { // 8-bit PCM
|
||||
if (!initInternal(8,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_8BIT) { // 8-bit PCM
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_8BIT,samples)) return;
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
data8[i]=data16[i]>>8;
|
||||
}
|
||||
}
|
||||
// TODO: BRR!
|
||||
if (depth!=10) { // VOX
|
||||
if (!initInternal(10,samples)) return;
|
||||
if (depth!=DIV_SAMPLE_DEPTH_VOX) { // VOX
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_VOX,samples)) return;
|
||||
oki_encode(data16,dataVOX,samples);
|
||||
}
|
||||
}
|
||||
|
||||
void* DivSample::getCurBuf() {
|
||||
switch (depth) {
|
||||
case 0:
|
||||
case DIV_SAMPLE_DEPTH_1BIT:
|
||||
return data1;
|
||||
case 1:
|
||||
case DIV_SAMPLE_DEPTH_1BIT_DPCM:
|
||||
return dataDPCM;
|
||||
case 3:
|
||||
case DIV_SAMPLE_DEPTH_YMZ_ADPCM:
|
||||
return dataZ;
|
||||
case 4:
|
||||
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM:
|
||||
return dataQSoundA;
|
||||
case 5:
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_A:
|
||||
return dataA;
|
||||
case 6:
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_B:
|
||||
return dataB;
|
||||
case 8:
|
||||
case DIV_SAMPLE_DEPTH_8BIT:
|
||||
return data8;
|
||||
case 9:
|
||||
case DIV_SAMPLE_DEPTH_BRR:
|
||||
return dataBRR;
|
||||
case 10:
|
||||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
return dataVOX;
|
||||
case 16:
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
return data16;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int DivSample::getCurBufLen() {
|
||||
switch (depth) {
|
||||
case 0:
|
||||
case DIV_SAMPLE_DEPTH_1BIT:
|
||||
return length1;
|
||||
case 1:
|
||||
case DIV_SAMPLE_DEPTH_1BIT_DPCM:
|
||||
return lengthDPCM;
|
||||
case 3:
|
||||
case DIV_SAMPLE_DEPTH_YMZ_ADPCM:
|
||||
return lengthZ;
|
||||
case 4:
|
||||
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM:
|
||||
return lengthQSoundA;
|
||||
case 5:
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_A:
|
||||
return lengthA;
|
||||
case 6:
|
||||
case DIV_SAMPLE_DEPTH_ADPCM_B:
|
||||
return lengthB;
|
||||
case 8:
|
||||
case DIV_SAMPLE_DEPTH_8BIT:
|
||||
return length8;
|
||||
case 9:
|
||||
case DIV_SAMPLE_DEPTH_BRR:
|
||||
return lengthBRR;
|
||||
case 10:
|
||||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
return lengthVOX;
|
||||
case 16:
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
return length16;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -831,9 +895,9 @@ DivSampleHistory* DivSample::prepareUndo(bool data, bool doNotPush) {
|
|||
duplicate=new unsigned char[getCurBufLen()];
|
||||
memcpy(duplicate,getCurBuf(),getCurBufLen());
|
||||
}
|
||||
h=new DivSampleHistory(duplicate,getCurBufLen(),samples,depth,rate,centerRate,loopStart);
|
||||
h=new DivSampleHistory(duplicate,getCurBufLen(),samples,depth,rate,centerRate,loopStart,loopEnd);
|
||||
} else {
|
||||
h=new DivSampleHistory(depth,rate,centerRate,loopStart);
|
||||
h=new DivSampleHistory(depth,rate,centerRate,loopStart,loopEnd);
|
||||
}
|
||||
if (!doNotPush) {
|
||||
while (!redoHist.empty()) {
|
||||
|
|
@ -863,7 +927,8 @@ DivSampleHistory* DivSample::prepareUndo(bool data, bool doNotPush) {
|
|||
} \
|
||||
rate=h->rate; \
|
||||
centerRate=h->centerRate; \
|
||||
loopStart=h->loopStart;
|
||||
loopStart=h->loopStart; \
|
||||
loopEnd=h->loopEnd;
|
||||
|
||||
|
||||
int DivSample::undo() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue