fix sample overflow when loading lossy

This commit is contained in:
tildearrow 2025-10-23 03:22:26 -05:00
parent d09a8b6b4c
commit 693e795768

View file

@ -309,18 +309,22 @@ std::vector<DivSample*> DivEngine::sampleFromFile(const char* path) {
logD("sample is 8-bit unsigned");
buf=new unsigned char[si.channels*si.frames];
sampleLen=sizeof(unsigned char);
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_FLOAT) {
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_FLOAT) {
logD("sample is 32-bit float");
buf=new float[si.channels*si.frames];
sampleLen=sizeof(float);
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_DOUBLE) {
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_DOUBLE) {
logD("sample is 64-bit float");
buf=new float[si.channels*si.frames];
buf=new double[si.channels*si.frames];
sampleLen=sizeof(double);
} else {
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_16) {
logD("sample is 16-bit signed");
buf=new short[si.channels*si.frames];
sampleLen=sizeof(short);
} else {
logD("sample is in a different format - reading as floats");
buf=new float[si.channels*si.frames];
sampleLen=sizeof(float);
}
if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_U8 ||
(si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_FLOAT ||
@ -328,10 +332,14 @@ std::vector<DivSample*> DivEngine::sampleFromFile(const char* path) {
if (sf_read_raw(f,buf,si.frames*si.channels*sampleLen)!=(si.frames*si.channels*sampleLen)) {
logW("sample read size mismatch!");
}
} else {
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_16) {
if (sf_read_short(f,(short*)buf,si.frames*si.channels)!=(si.frames*si.channels)) {
logW("sample read size mismatch!");
}
} else {
if (sf_read_float(f,(float*)buf,si.frames*si.channels)!=(si.frames*si.channels)) {
logW("sample read size mismatch!");
}
}
DivSample* sample=new DivSample;
int sampleCount=(int)song.sample.size();
@ -354,20 +362,7 @@ std::vector<DivSample*> DivEngine::sampleFromFile(const char* path) {
sample->data8[index++]=averaged;
}
delete[] (unsigned char*)buf;
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_FLOAT) {
for (int i=0; i<si.frames*si.channels; i+=si.channels) {
float averaged=0.0f;
for (int j=0; j<si.channels; j++) {
averaged+=((float*)buf)[i+j];
}
averaged/=si.channels;
averaged*=32767.0;
if (averaged<-32768.0) averaged=-32768.0;
if (averaged>32767.0) averaged=32767.0;
sample->data16[index++]=averaged;
}
delete[] (float*)buf;
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_DOUBLE) {
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_DOUBLE) {
for (int i=0; i<si.frames*si.channels; i+=si.channels) {
double averaged=0.0f;
for (int j=0; j<si.channels; j++) {
@ -380,7 +375,7 @@ std::vector<DivSample*> DivEngine::sampleFromFile(const char* path) {
sample->data16[index++]=averaged;
}
delete[] (double*)buf;
} else {
} else if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_16) {
for (int i=0; i<si.frames*si.channels; i+=si.channels) {
int averaged=0;
for (int j=0; j<si.channels; j++) {
@ -390,6 +385,19 @@ std::vector<DivSample*> DivEngine::sampleFromFile(const char* path) {
sample->data16[index++]=averaged;
}
delete[] (short*)buf;
} else {
for (int i=0; i<si.frames*si.channels; i+=si.channels) {
float averaged=0.0f;
for (int j=0; j<si.channels; j++) {
averaged+=((float*)buf)[i+j];
}
averaged/=si.channels;
averaged*=32767.0;
if (averaged<-32768.0) averaged=-32768.0;
if (averaged>32767.0) averaged=32767.0;
sample->data16[index++]=averaged;
}
delete[] (float*)buf;
}
sample->rate=si.samplerate;