dev126 - new ins format
This commit is contained in:
parent
1b79f9d7f3
commit
d6ae735ffe
11 changed files with 408 additions and 196 deletions
|
|
@ -39,6 +39,185 @@ DivSampleHistory::~DivSampleHistory() {
|
|||
if (data!=NULL) delete[] data;
|
||||
}
|
||||
|
||||
void DivSample::putSampleData(SafeWriter* w) {
|
||||
size_t blockStartSeek, blockEndSeek;
|
||||
|
||||
w->write("SMP2",4);
|
||||
blockStartSeek=w->tell();
|
||||
w->writeI(0);
|
||||
|
||||
w->writeString(name,false);
|
||||
w->writeI(samples);
|
||||
w->writeI(rate);
|
||||
w->writeI(centerRate);
|
||||
w->writeC(depth);
|
||||
w->writeC(loopMode);
|
||||
w->writeC(0); // reserved
|
||||
w->writeC(0);
|
||||
w->writeI(loop?loopStart:-1);
|
||||
w->writeI(loop?loopEnd:-1);
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
w->writeI(0xffffffff);
|
||||
}
|
||||
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
// store 16-bit samples as little-endian
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
unsigned char* sampleBuf=(unsigned char*)getCurBuf();
|
||||
size_t bufLen=getCurBufLen();
|
||||
for (size_t i=0; i<bufLen; i+=2) {
|
||||
w->writeC(sampleBuf[i+1]);
|
||||
w->writeC(sampleBuf[i]);
|
||||
}
|
||||
} else {
|
||||
w->write(getCurBuf(),getCurBufLen());
|
||||
}
|
||||
#else
|
||||
w->write(getCurBuf(),getCurBufLen());
|
||||
#endif
|
||||
|
||||
blockEndSeek=w->tell();
|
||||
w->seek(blockStartSeek,SEEK_SET);
|
||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||
w->seek(0,SEEK_END);
|
||||
}
|
||||
|
||||
// Delek why
|
||||
static double samplePitchesSD[11]={
|
||||
0.1666666666, 0.2, 0.25, 0.333333333, 0.5,
|
||||
1,
|
||||
2, 3, 4, 5, 6
|
||||
};
|
||||
|
||||
DivDataErrors DivSample::readSampleData(SafeReader& reader, short version) {
|
||||
int vol=0;
|
||||
int pitch=0;
|
||||
char magic[4];
|
||||
|
||||
reader.read(magic,4);
|
||||
if (strcmp(magic,"SMPL")!=0 && strcmp(magic,"SMP2")!=0) {
|
||||
return DIV_DATA_INVALID_HEADER;
|
||||
}
|
||||
bool isNewSample=(strcmp(magic,"SMP2")==0);
|
||||
reader.readI();
|
||||
if (!isNewSample) logV("(old sample)");
|
||||
|
||||
name=reader.readString();
|
||||
samples=reader.readI();
|
||||
if (!isNewSample) {
|
||||
loopEnd=samples;
|
||||
}
|
||||
rate=reader.readI();
|
||||
|
||||
if (isNewSample) {
|
||||
centerRate=reader.readI();
|
||||
depth=(DivSampleDepth)reader.readC();
|
||||
if (version>=123) {
|
||||
loopMode=(DivSampleLoopMode)reader.readC();
|
||||
} else {
|
||||
loopMode=DIV_SAMPLE_LOOP_FORWARD;
|
||||
reader.readC();
|
||||
}
|
||||
|
||||
// reserved
|
||||
reader.readC();
|
||||
reader.readC();
|
||||
|
||||
loopStart=reader.readI();
|
||||
loopEnd=reader.readI();
|
||||
loop=(loopStart>=0)&&(loopEnd>=0);
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
reader.readI();
|
||||
}
|
||||
} else {
|
||||
if (version<58) {
|
||||
vol=reader.readS();
|
||||
pitch=reader.readS();
|
||||
} else {
|
||||
reader.readI();
|
||||
}
|
||||
depth=(DivSampleDepth)reader.readC();
|
||||
|
||||
// reserved
|
||||
reader.readC();
|
||||
|
||||
// while version 32 stored this value, it was unused.
|
||||
if (version>=38) {
|
||||
centerRate=(unsigned short)reader.readS();
|
||||
} else {
|
||||
reader.readS();
|
||||
}
|
||||
|
||||
if (version>=19) {
|
||||
loopStart=reader.readI();
|
||||
loop=(loopStart>=0)&&(loopEnd>=0);
|
||||
} else {
|
||||
reader.readI();
|
||||
}
|
||||
}
|
||||
|
||||
if (version>=58) { // modern sample
|
||||
init(samples);
|
||||
reader.read(getCurBuf(),getCurBufLen());
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
// convert 16-bit samples to big-endian
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
unsigned char* sampleBuf=(unsigned char*)getCurBuf();
|
||||
size_t sampleBufLen=getCurBufLen();
|
||||
for (size_t pos=0; pos<sampleBufLen; pos+=2) {
|
||||
sampleBuf[pos]^=sampleBuf[pos+1];
|
||||
sampleBuf[pos+1]^=sampleBuf[pos];
|
||||
sampleBuf[pos]^=sampleBuf[pos+1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else { // legacy sample
|
||||
int length=samples;
|
||||
short* data=new short[length];
|
||||
reader.read(data,2*length);
|
||||
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
// convert 16-bit samples to big-endian
|
||||
for (int pos=0; pos<length; pos++) {
|
||||
data[pos]=((unsigned short)data[pos]>>8)|((unsigned short)data[pos]<<8);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pitch!=5) {
|
||||
logD("scaling from %d...",pitch);
|
||||
}
|
||||
|
||||
// render data
|
||||
if (depth!=DIV_SAMPLE_DEPTH_8BIT && depth!=DIV_SAMPLE_DEPTH_16BIT) {
|
||||
logW("sample depth is wrong! (%d)",depth);
|
||||
depth=DIV_SAMPLE_DEPTH_16BIT;
|
||||
}
|
||||
samples=(double)samples/samplePitchesSD[pitch];
|
||||
init(samples);
|
||||
|
||||
unsigned int k=0;
|
||||
float mult=(float)(vol)/50.0f;
|
||||
for (double j=0; j<length; j+=samplePitchesSD[pitch]) {
|
||||
if (k>=samples) {
|
||||
break;
|
||||
}
|
||||
if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
float next=(float)(data[(unsigned int)j]-0x80)*mult;
|
||||
data8[k++]=fmin(fmax(next,-128),127);
|
||||
} else {
|
||||
float next=(float)data[(unsigned int)j]*mult;
|
||||
data16[k++]=fmin(fmax(next,-32768),32767);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
return DIV_DATA_SUCCESS;
|
||||
}
|
||||
|
||||
bool DivSample::isLoopable() {
|
||||
return loop && ((loopStart>=0 && loopStart<loopEnd) && (loopEnd>loopStart && loopEnd<=(int)samples));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue