mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-29 02:51:24 +00:00
Merge pull request #216 from superctr/220223_smpl
Update center rate and loop information when loading and saving samples
This commit is contained in:
commit
3804e45042
2 changed files with 40 additions and 1 deletions
|
@ -1890,7 +1890,6 @@ bool DivEngine::addSampleFromFile(const char* path) {
|
|||
if (sf_readf_short(f,buf,si.frames)!=si.frames) {
|
||||
logW("sample read size mismatch!\n");
|
||||
}
|
||||
sf_close(f);
|
||||
DivSample* sample=new DivSample;
|
||||
int sampleCount=(int)song.sample.size();
|
||||
const char* sName=strrchr(path,DIR_SEPARATOR);
|
||||
|
@ -1923,7 +1922,28 @@ bool DivEngine::addSampleFromFile(const char* path) {
|
|||
sample->rate=si.samplerate;
|
||||
if (sample->rate<4000) sample->rate=4000;
|
||||
if (sample->rate>96000) sample->rate=96000;
|
||||
sample->centerRate=si.samplerate;
|
||||
|
||||
SF_INSTRUMENT inst;
|
||||
if (sf_command(f, SFC_GET_INSTRUMENT, &inst, sizeof(inst)) == SF_TRUE)
|
||||
{
|
||||
// There's no documentation on libsndfile detune range, but the code
|
||||
// implies -50..50. Yet when loading a file you can get a >50 value.
|
||||
if(inst.detune > 50)
|
||||
inst.detune = inst.detune - 100;
|
||||
short pitch = ((0x3c-inst.basenote)*100) + inst.detune;
|
||||
sample->centerRate=si.samplerate*pow(2.0,pitch/(12.0 * 100.0));
|
||||
if(inst.loop_count && inst.loops[0].mode == SF_LOOP_FORWARD)
|
||||
{
|
||||
sample->loopStart=inst.loops[0].start;
|
||||
if(inst.loops[0].end < (unsigned int)sampleCount)
|
||||
sampleCount=inst.loops[0].end;
|
||||
}
|
||||
}
|
||||
|
||||
if (sample->centerRate<4000) sample->centerRate=4000;
|
||||
if (sample->centerRate>64000) sample->centerRate=64000;
|
||||
sf_close(f);
|
||||
song.sample.push_back(sample);
|
||||
song.sampleLen=sampleCount+1;
|
||||
renderSamples();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../ta-log.h"
|
||||
#include <string.h>
|
||||
#include <sndfile.h>
|
||||
#include <math.h>
|
||||
|
||||
bool DivSample::save(const char* path) {
|
||||
SNDFILE* f;
|
||||
|
@ -44,6 +45,23 @@ bool DivSample::save(const char* path) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SF_INSTRUMENT inst;
|
||||
memset(&inst, 0, sizeof(inst));
|
||||
inst.gain = 1;
|
||||
short pitch = (0x3c * 100) + 50 - (log2((double)centerRate/rate) * 12.0 * 100.0);
|
||||
inst.basenote = pitch / 100;
|
||||
inst.detune = 50 - (pitch % 100);
|
||||
inst.velocity_hi = 0x7f;
|
||||
inst.key_hi = 0x7f;
|
||||
if(loopStart != -1)
|
||||
{
|
||||
inst.loop_count = 1;
|
||||
inst.loops[0].mode = SF_LOOP_FORWARD;
|
||||
inst.loops[0].start = loopStart;
|
||||
inst.loops[0].end = length;
|
||||
}
|
||||
sf_command(f, SFC_SET_INSTRUMENT, &inst, sizeof(inst));
|
||||
|
||||
if (depth==16) {
|
||||
sf_writef_short(f,data,length);
|
||||
} else {
|
||||
|
@ -54,6 +72,7 @@ bool DivSample::save(const char* path) {
|
|||
sf_writef_short(f,cbuf,length);
|
||||
delete[] cbuf;
|
||||
}
|
||||
|
||||
sf_close(f);
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue