mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 06:53:01 +00:00
S3M import: stereo samples and SCx/SDx effects
This commit is contained in:
parent
63f8289847
commit
55a8bb2448
1 changed files with 57 additions and 18 deletions
|
@ -353,8 +353,6 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
||||||
logV("length: %x",length);
|
logV("length: %x",length);
|
||||||
|
|
||||||
DivSample* s=new DivSample;
|
DivSample* s=new DivSample;
|
||||||
s->depth=DIV_SAMPLE_DEPTH_8BIT;
|
|
||||||
s->init(length);
|
|
||||||
|
|
||||||
s->loopStart=reader.readI();
|
s->loopStart=reader.readI();
|
||||||
s->loopEnd=reader.readI();
|
s->loopEnd=reader.readI();
|
||||||
|
@ -393,16 +391,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
s->loop=flags&1;
|
s->loop=flags&1;
|
||||||
s->depth=(flags&4)?DIV_SAMPLE_DEPTH_16BIT:DIV_SAMPLE_DEPTH_8BIT;
|
s->depth=(flags&4)?DIV_SAMPLE_DEPTH_16BIT:DIV_SAMPLE_DEPTH_8BIT;
|
||||||
s->init(length>>(s->depth==DIV_SAMPLE_DEPTH_16BIT?1:0));
|
s->init(length);
|
||||||
|
|
||||||
if (flags&2) {
|
|
||||||
logE("stereo sample!");
|
|
||||||
lastError="stereo sample";
|
|
||||||
delete ins;
|
|
||||||
delete s;
|
|
||||||
delete[] file;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPacked) {
|
if (isPacked) {
|
||||||
logE("ADPCM not supported!");
|
logE("ADPCM not supported!");
|
||||||
|
@ -413,16 +402,51 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.read(s->getCurBuf(),length);
|
if (flags&2) {
|
||||||
|
// downmix stereo
|
||||||
if (!signedSamples) {
|
|
||||||
if (s->depth==DIV_SAMPLE_DEPTH_16BIT) {
|
if (s->depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||||
for (unsigned int i=0; i<s->samples; i++) {
|
for (unsigned int i=0; i<s->samples; i++) {
|
||||||
s->data16[i]^=0x8000;
|
short l=reader.readS();
|
||||||
|
if (!signedSamples) {
|
||||||
|
l^=0x8000;
|
||||||
|
}
|
||||||
|
s->data16[i]=l;
|
||||||
|
}
|
||||||
|
for (unsigned int i=0; i<s->samples; i++) {
|
||||||
|
short r=reader.readS();
|
||||||
|
if (!signedSamples) {
|
||||||
|
r^=0x8000;
|
||||||
|
}
|
||||||
|
s->data16[i]=(s->data16[i]+r)>>1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (unsigned int i=0; i<s->samples; i++) {
|
for (unsigned int i=0; i<s->samples; i++) {
|
||||||
s->data8[i]^=0x80;
|
signed char l=reader.readC();
|
||||||
|
if (!signedSamples) {
|
||||||
|
l^=0x80;
|
||||||
|
}
|
||||||
|
s->data8[i]=l;
|
||||||
|
}
|
||||||
|
for (unsigned int i=0; i<s->samples; i++) {
|
||||||
|
signed char r=reader.readC();
|
||||||
|
if (!signedSamples) {
|
||||||
|
r^=0x80;
|
||||||
|
}
|
||||||
|
s->data8[i]=(s->data8[i]+r)>>1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reader.read(s->getCurBuf(),s->samples);
|
||||||
|
|
||||||
|
if (!signedSamples) {
|
||||||
|
if (s->depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||||
|
for (unsigned int i=0; i<s->samples; i++) {
|
||||||
|
s->data16[i]^=0x8000;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned int i=0; i<s->samples; i++) {
|
||||||
|
s->data8[i]^=0x80;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -673,7 +697,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
||||||
if (porting[j]!=portingOld[j] || portaStatusChanged[j]) {
|
if (porting[j]!=portingOld[j] || portaStatusChanged[j]) {
|
||||||
if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) {
|
if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) {
|
||||||
p->data[curRow][effectCol[j]++]=portaType[j]|0xf0;
|
p->data[curRow][effectCol[j]++]=portaType[j]|0xf0;
|
||||||
p->data[curRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?4:1);
|
p->data[curRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
|
||||||
porting[j]=false;
|
porting[j]=false;
|
||||||
} else {
|
} else {
|
||||||
p->data[curRow][effectCol[j]++]=portaType[j];
|
p->data[curRow][effectCol[j]++]=portaType[j];
|
||||||
|
@ -872,12 +896,27 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
||||||
case 'R': // tremolo
|
case 'R': // tremolo
|
||||||
break;
|
break;
|
||||||
case 'S': // special...
|
case 'S': // special...
|
||||||
|
switch (effectVal>>4) {
|
||||||
|
case 0xc:
|
||||||
|
p->data[curRow][effectCol[chan]++]=0xec;
|
||||||
|
p->data[curRow][effectCol[chan]++]=effectVal&15;
|
||||||
|
break;
|
||||||
|
case 0xd:
|
||||||
|
p->data[curRow][effectCol[chan]++]=0xed;
|
||||||
|
p->data[curRow][effectCol[chan]++]=effectVal&15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'T': // tempo
|
case 'T': // tempo
|
||||||
p->data[curRow][effectCol[chan]++]=0xf0;
|
p->data[curRow][effectCol[chan]++]=0xf0;
|
||||||
p->data[curRow][effectCol[chan]++]=effectVal;
|
p->data[curRow][effectCol[chan]++]=effectVal;
|
||||||
break;
|
break;
|
||||||
case 'U': // fine vibrato
|
case 'U': // fine vibrato
|
||||||
|
if (effectVal!=0) {
|
||||||
|
vibStatus[chan]=effectVal;
|
||||||
|
vibStatusChanged[chan]=true;
|
||||||
|
}
|
||||||
|
vibing[chan]=true;
|
||||||
break;
|
break;
|
||||||
case 'V': // global volume (!)
|
case 'V': // global volume (!)
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue