Last active
November 23, 2024 18:31
-
-
Save marvinh/f0f36dd176566f99ba2a252dbfe7005e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Grab coefficients from here | |
//http://www.mp3-tech.org/programmer/docs/resampler.pdf | |
//Grab NI Media from here https://github.com/NativeInstruments/ni-media | |
//DONT USE THIS METHOD// | |
//REWRITE WITH THE STREAMER BELOW THIS// | |
class StreamedSample { | |
public: | |
StreamedSample(juce::String newfilePath) { | |
filePath = newfilePath; | |
astream = std::make_unique<audio::ifstream>(newfilePath.toStdString()); | |
numSamples = astream->info().num_samples(); | |
sourceSampleRate = astream->info().sample_rate(); | |
numChannels = astream->info().num_channels(); | |
} | |
~StreamedSample() { | |
} | |
double sourceSampleRate{44100.0}; | |
size_t numSamples{4096}; | |
size_t numChannels{2}; | |
size_t numFrames{2}; | |
std::unique_ptr<audio::ifstream> astream; | |
private: | |
juce::String filePath; | |
}; | |
//Use this instead much easier and faster | |
class SampleReader { | |
public: | |
SampleReader(const std::string& filename){ | |
stream = audio::ifstream(filename); | |
num_frames = stream.info().num_frames(); | |
num_samples = stream.info().num_samples(); | |
num_channels = stream.info().num_channels(); | |
sample_rate = stream.info().sample_rate(); | |
fm = boost::interprocess::file_mapping(filename.c_str(), boost::interprocess::read_only); | |
mr = boost::interprocess::mapped_region(fm, boost::interprocess::read_only); | |
mr.advise( boost::interprocess::mapped_region::advice_willneed); | |
mr.advise( boost::interprocess::mapped_region::advice_sequential); | |
mm = static_cast<char*>(mr.get_address()) + 44; | |
rt_fmt = pcm::make_format(pcm::signed_integer,pcm::_24bit, pcm::little_endian); | |
rt_it = pcm::make_iterator<float>(mm, rt_fmt); | |
} | |
void readSample(uint32_t position) { | |
dleft = *(rt_it+position); | |
dright = *(rt_it+position+1); | |
} | |
float dleft; | |
float dright; | |
boost::interprocess::file_mapping fm; | |
boost::interprocess::mapped_region mr; | |
pcm::format rt_fmt; | |
pcm::iterator<float, char*> rt_it; | |
char * mm; | |
audio::ifstream stream; | |
size_t num_frames; | |
size_t num_samples; | |
size_t num_channels; | |
double sample_rate; | |
}; | |
double imp1x[NBR_PHASES][FIR_LEN_1X]; | |
double imp2x[NBR_PHASES][FIR_LEN_2X]; | |
double dif1x[NBR_PHASES][FIR_LEN_1X]; | |
double dif2x[NBR_PHASES][FIR_LEN_2X]; | |
void startNote (int midiNoteNumber, float velocity, | |
juce::SynthesiserSound* sd, | |
int /*currentPitchWheelPosition*/) override | |
{ | |
if(auto * sound = static_cast<SampSound*>(sd)) { | |
envUp = 0.0f; | |
envDown = 0.0f; | |
phasor = 0.0; | |
sourceSamplePosition = 0; | |
if(sound->SAMPLER_KEYTRACK == true) { | |
pitchRatio = std::pow (2.0, ((midiNoteNumber-60+sound->SAMPLER_TRANSPOSE)) / 12.0 ) | |
* sound->sourceSampleRate / sampleRate; | |
}else{ | |
pitchRatio = std::pow (2.0, (sound->SAMPLER_TRANSPOSE)/12.0 ) | |
* sound->sourceSampleRate / sampleRate; | |
} | |
lastMidiNote = midiNoteNumber; | |
int pos = sourceSamplePosition; | |
sound->getSample()->astream->clear(); | |
sound->getSample()->astream->frame_seekg(pos); | |
*sound->getSample()->astream >> l_data_ptr; | |
} | |
} | |
void setImpulse() { | |
double next_coef_dbl = 0.0; | |
for (int fir_pos = FIR_LEN_1X - 1; fir_pos >= 0; --fir_pos) | |
{ | |
for (int phase_cnt = NBR_PHASES - 1; phase_cnt >= 0; --phase_cnt) | |
{ | |
const int imp_pos = fir_pos * NBR_PHASES + phase_cnt; | |
const double coef_dbl = fir_interpolator_1[imp_pos]; | |
const float coef = static_cast <float> (coef_dbl); | |
const float dif = static_cast <float> (next_coef_dbl - coef_dbl); | |
const int table_pos = FIR_LEN_1X - 1 - fir_pos; | |
imp1x[phase_cnt][table_pos] = coef; | |
dif1x[phase_cnt][table_pos] = dif; | |
next_coef_dbl = coef_dbl; | |
} | |
} | |
next_coef_dbl = 0.0; | |
for (int fir_pos = FIR_LEN_2X - 1; fir_pos >= 0; --fir_pos) | |
{ | |
for (int phase_cnt = NBR_PHASES - 1; phase_cnt >= 0; --phase_cnt) | |
{ | |
const int imp_pos = fir_pos * NBR_PHASES + phase_cnt; | |
const double coef_dbl = fir_interpolator_2[imp_pos]; | |
const float coef = static_cast <float> (coef_dbl); | |
const float dif = static_cast <float> (next_coef_dbl - coef_dbl); | |
const int table_pos = FIR_LEN_2X - 1 - fir_pos; | |
imp2x[phase_cnt][table_pos] = coef; | |
dif2x[phase_cnt][table_pos] = dif; | |
next_coef_dbl = coef_dbl; | |
} | |
outBuffer[fir_pos] = 0.0; | |
} | |
} | |
void renderNextBlock (juce::AudioBuffer<float>& outputBuffer, int startSample, int numSamples) override | |
{ | |
if (auto * sound = static_cast<SampSound*> (getCurrentlyPlayingSound().get())) | |
{ | |
jassert (sound->getSample() != nullptr); | |
if(sound->SAMPLER_KEYTRACK == true) { | |
pitchRatio = pow(2,(lastMidiNote-60+sound->SAMPLER_TRANSPOSE) / 12.0) * sound->getSample()->sourceSampleRate / sampleRate; | |
}else{ | |
pitchRatio = pow(2,(sound->SAMPLER_TRANSPOSE+24.0)/12.0) * sound->getSample()->sourceSampleRate / sampleRate; | |
} | |
float* LL = outputBuffer.getWritePointer (0, startSample); | |
float* RR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getWritePointer (1, startSample) : nullptr; | |
auto numChannels = sound->getSample()->numChannels; | |
auto numFrames = sound->getSample()->numFrames; | |
int r = 0; | |
int N = numSamples; | |
int a = 0; | |
pitchRatio = 1.0; | |
while(--numSamples >= 0){ | |
int pos = sourceSamplePosition; | |
double q = (sourceSamplePosition - pos); | |
int ph = (sourceSamplePosition - pos) * 63; | |
int M = std::fmax(pitchRatio,1); | |
int s = 0; | |
double c_0 = 0.0; | |
double c_1 = 0.0; | |
c_0 += (imp2x[ph][0] + dif2x[ph][0] * q) * l_data_ptr[0]; | |
c_1 += (imp2x[ph][1] + dif2x[ph][1] * q) * l_data_ptr[2]; | |
c_0 += (imp2x[ph][2] + dif2x[ph][2] * q) * l_data_ptr[4]; | |
c_1 += (imp2x[ph][3] + dif2x[ph][3] * q) * l_data_ptr[6]; | |
c_0 += (imp2x[ph][4] + dif2x[ph][4] * q) * l_data_ptr[8]; | |
c_1 += (imp2x[ph][5] + dif2x[ph][5] * q) * l_data_ptr[10]; | |
c_0 += (imp2x[ph][6] + dif2x[ph][6] * q) * l_data_ptr[12]; | |
c_1 += (imp2x[ph][7] + dif2x[ph][7] * q) * l_data_ptr[14]; | |
c_0 += (imp2x[ph][8] + dif2x[ph][8] * q) * l_data_ptr[16]; | |
c_1 += (imp2x[ph][9] + dif2x[ph][9] * q) * l_data_ptr[18]; | |
c_0 +=(imp2x[ph][10] + dif2x[ph][10] * q) * l_data_ptr[20]; | |
c_1 +=(imp2x[ph][11] + dif2x[ph][11] * q) * l_data_ptr[22]; | |
c_0 +=(imp2x[ph][12] + dif2x[ph][12] * q) * l_data_ptr[24]; | |
c_1 +=(imp2x[ph][13] + dif2x[ph][13] * q) * l_data_ptr[26]; | |
c_0 +=(imp2x[ph][14] + dif2x[ph][14] * q) * l_data_ptr[28]; | |
c_1 +=(imp2x[ph][15] + dif2x[ph][15] * q) * l_data_ptr[30]; | |
c_0 +=(imp2x[ph][16] + dif2x[ph][16] * q) * l_data_ptr[32]; | |
c_1 +=(imp2x[ph][17] + dif2x[ph][17] * q) * l_data_ptr[34]; | |
c_0 +=(imp2x[ph][18] + dif2x[ph][18] * q) * l_data_ptr[36]; | |
c_1 +=(imp2x[ph][19] + dif2x[ph][19] * q) * l_data_ptr[38]; | |
c_0 +=(imp2x[ph][20] + dif2x[ph][20] * q) * l_data_ptr[40]; | |
c_1 +=(imp2x[ph][21] + dif2x[ph][21] * q) * l_data_ptr[42]; | |
c_0 +=(imp2x[ph][22] + dif2x[ph][22] * q) * l_data_ptr[44]; | |
c_1 +=(imp2x[ph][23] + dif2x[ph][23] * q) * l_data_ptr[46]; | |
for(int w = 23; w >= 0; w-- ){ | |
l_data_ptr[(w-1)*2] = l_data_ptr[w*2]; | |
} | |
sound->getSample()->astream->clear(); | |
sound->getSample()->astream->frame_seekg(pos+pitchRatio); | |
*sound->getSample()->astream >> l_data_ptr[46]; | |
float l = c_0 + c_1; | |
sourceSamplePosition += pitchRatio; | |
*LL++ = l; | |
*RR++ = l; | |
if(sourceSamplePosition > numFrames){ | |
clearCurrentNote(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment