79
80
m_bScalerChanged(false),
80
81
m_bLastBufferPaused(true),
82
m_iRampState(ENGINE_RAMP_NONE)
83
m_iRampState(ENGINE_RAMP_NONE),
84
m_pDitherBuffer(new CSAMPLE[MAX_BUFFER_LEN]),
85
m_iDitherBufferReadIndex(0) {
87
// Generate dither values
88
for (int i = 0; i < MAX_BUFFER_LEN; ++i) {
89
m_pDitherBuffer[i] = static_cast<float>(rand() % 32768) / 32768.0 - 0.5;
85
92
m_fLastSampleValue[0] = 0;
86
93
m_fLastSampleValue[1] = 0;
140
147
// Actual rate (used in visuals, not for control)
141
148
rateEngine = new ControlObject(ConfigKey(group, "rateEngine"));
143
150
// BPM to display in the UI (updated more slowly than the actual bpm)
144
151
visualBpm = new ControlObject(ConfigKey(group, "visual_bpm"));
410
419
if (!even((int)new_playpos))
413
// Give EngineControl's a chance to veto or correct the seek target.
417
seek_hint.sample = new_playpos;
418
seek_hint.length = 0;
419
seek_hint.priority = 1;
420
QList<Hint> hint_list;
421
hint_list.append(seek_hint);
422
m_pReader->hintAndMaybeWake(hint_list);
423
422
setNewPlaypos(new_playpos);
558
556
if (!bCurBufferPaused) {
561
Q_ASSERT(even(iBufferSize));
563
559
// The fileposition should be: (why is this thing a double anyway!?
564
560
// Integer valued.
565
Q_ASSERT(round(filepos_play) == filepos_play);
561
double filepos_play_rounded = round(filepos_play);
562
if (filepos_play_rounded != filepos_play) {
563
qWarning() << __FILE__ << __LINE__ << "ERROR: filepos_play is not round:" << filepos_play;
564
filepos_play = filepos_play_rounded;
567
Q_ASSERT(even(filepos_play));
568
if (!even(filepos_play)) {
569
qWarning() << "ERROR: filepos_play is not even:" << filepos_play;
569
573
// Perform scaling of Reader buffer into buffer.
570
574
output = m_pScale->scale(0,
605
609
// stats-pipe once we have them.
607
611
filepos_play = control_seek;
608
Q_ASSERT(round(filepos_play) == filepos_play);
612
double filepos_play_rounded = round(filepos_play);
613
if (filepos_play_rounded != filepos_play) {
614
qWarning() << __FILE__ << __LINE__ << "ERROR: filepos_play is not round:" << filepos_play;
615
filepos_play = filepos_play_rounded;
610
618
// Fix filepos_play so that it is not out of bounds.
611
619
if (file_length_old > 0) {
691
699
//let's try holding the last sample value constant, and pull it
693
701
float ramp_inc = 0;
694
if (m_iRampState == ENGINE_RAMP_UP ||
702
if (m_iRampState == ENGINE_RAMP_UP ||
695
703
m_iRampState == ENGINE_RAMP_DOWN) {
696
ramp_inc = m_iRampState * 1000 / m_pSampleRate->get();
699
//float fakerate = rate * 30000 == 0 ? -5000 : rate*30000;
700
for (int i=0; i<iBufferSize; i+=2) {
701
if (bCurBufferPaused) {
702
float dither = (float)(rand() % 32768) / 32768 - 0.5; // dither
703
pOutput[i] = m_fLastSampleValue[0] * m_fRampValue + dither;
704
pOutput[i+1] = m_fLastSampleValue[1] * m_fRampValue + dither;
706
pOutput[i] = pOutput[i] * m_fRampValue;
707
pOutput[i+1] = pOutput[i+1] * m_fRampValue;
710
//writer << pOutput[i] << "\n";
711
m_fRampValue += ramp_inc;
712
if (m_fRampValue >= 1.0) {
713
m_iRampState = ENGINE_RAMP_NONE;
716
if (m_fRampValue <= 0.0) {
717
m_iRampState = ENGINE_RAMP_NONE;
704
ramp_inc = m_iRampState * 300 / m_pSampleRate->get();
706
for (int i=0; i<iBufferSize; i+=2) {
707
if (bCurBufferPaused) {
708
float dither = m_pDitherBuffer[m_iDitherBufferReadIndex];
709
m_iDitherBufferReadIndex = (m_iDitherBufferReadIndex + 1) % MAX_BUFFER_LEN;
710
pOutput[i] = m_fLastSampleValue[0] * m_fRampValue + dither;
711
pOutput[i+1] = m_fLastSampleValue[1] * m_fRampValue + dither;
713
pOutput[i] = pOutput[i] * m_fRampValue;
714
pOutput[i+1] = pOutput[i+1] * m_fRampValue;
717
m_fRampValue += ramp_inc;
718
if (m_fRampValue >= 1.0) {
719
m_iRampState = ENGINE_RAMP_NONE;
722
if (m_fRampValue <= 0.0) {
723
m_iRampState = ENGINE_RAMP_NONE;
727
} else if (m_fRampValue == 0.0) {
728
SampleUtil::applyGain(pOutput, 0.0, iBufferSize);
722
731
if ((!bCurBufferPaused && m_iRampState == ENGINE_RAMP_NONE) ||
725
734
m_fLastSampleValue[1] = pOutput[iBufferSize-1];
737
/*for (int i=0; i<iBufferSize; i+=2) {
738
writer << pOutput[i] << "\n";
728
741
m_bLastBufferPaused = bCurBufferPaused;
732
void EngineBuffer::rampOut(const CSAMPLE* pOut, int iBufferSize)
734
CSAMPLE * pOutput = (CSAMPLE *)pOut;
736
//qDebug() << "ramp out";
740
if (m_fLastSampleValue[0]!=0.) {
742
if (pOutput[0] == 0) {
743
while (i<iBufferSize) {
744
float sigmoid = sigmoid_zero((float)(iBufferSize - i), (float)iBufferSize);
745
float dither = (float)(rand() % 32768) / 32768 - 0.5; // dither
746
pOutput[i] = (float)m_fLastSampleValue[0] * sigmoid + dither;
747
pOutput[i+1] = (float)m_fLastSampleValue[1] * sigmoid + dither;
751
while (i<iBufferSize) {
752
float sigmoid = sigmoid_zero((float)(iBufferSize - i), (float)iBufferSize);
753
float dither = (float)(rand() % 32768) / 32768 - 0.5; // dither
754
pOutput[i] = (float)pOutput[i] * sigmoid + dither;
755
pOutput[i+1] = (float)pOutput[i+1] * sigmoid + dither;
762
// Reset rest of buffer
763
while (i<iBufferSize)
770
744
void EngineBuffer::updateIndicators(double rate, int iBufferSize) {
772
746
// Increase samplesCalculated by the buffer size