diff options
author | RJ Ryan <rryan@mixxx.org> | 2013-12-23 17:12:46 -0500 |
---|---|---|
committer | RJ Ryan <rryan@mixxx.org> | 2013-12-23 17:12:46 -0500 |
commit | 1a3a4419429849f381bba9c026a432dc340dd2a2 (patch) | |
tree | 4dadb58cd95b755c95428a30b326f959477ee248 /src/vinylcontrol/vinylcontrolxwax.cpp | |
parent | 231caa64c27c133e8ef69156a517f6a50ec36362 (diff) | |
parent | 9a63fde4f87b6fd794a956bda3bd5a63dff10244 (diff) |
Merge branch 'master' into engine_refactor
Conflicts:
src/vinylcontrol/vinylcontrol.cpp
src/vinylcontrol/vinylcontrol.h
src/vinylcontrol/vinylcontrolxwax.cpp
src/vinylcontrol/vinylcontrolxwax.h
Diffstat (limited to 'src/vinylcontrol/vinylcontrolxwax.cpp')
-rw-r--r-- | src/vinylcontrol/vinylcontrolxwax.cpp | 681 |
1 files changed, 299 insertions, 382 deletions
diff --git a/src/vinylcontrol/vinylcontrolxwax.cpp b/src/vinylcontrol/vinylcontrolxwax.cpp index 0a910d1ed4..25bcd5655b 100644 --- a/src/vinylcontrol/vinylcontrolxwax.cpp +++ b/src/vinylcontrol/vinylcontrolxwax.cpp @@ -41,62 +41,75 @@ bool VinylControlXwax::s_bLUTInitialized = false; QMutex VinylControlXwax::s_xwaxLUTMutex; -VinylControlXwax::VinylControlXwax(ConfigObject<ConfigValue> * pConfig, QString group) - : VinylControl(pConfig, group) { - dOldPos = 0.0f; - m_pWorkBuffer = new short[MAX_BUFFER_LEN]; - m_workBufferSize = MAX_BUFFER_LEN; - char * timecode = NULL; - bForceResync = false; - iOldMode = MIXXX_VCMODE_ABSOLUTE; - dUiUpdateTime = -1.0f; - m_bNeedleSkipPrevention = (bool)(m_pConfig->getValueString( ConfigKey( VINYL_PREF_KEY, "needle_skip_prevention" ) ).toInt()); - signalenabled->slotSet(m_pConfig->getValueString( ConfigKey( VINYL_PREF_KEY, "show_signal_quality" ) ).toInt()); - - dLastTrackSelectPos = 0.0; - dCurTrackSelectPos = 0.0; - trackSelector = trackLoader = NULL; - bTrackSelectMode = false; - - tSinceSteadyPitch = QTime(); - m_pSteadySubtle = new SteadyPitch(0.12); - m_pSteadyGross = new SteadyPitch(0.5); - - iQualPos = 0; - iQualFilled = 0; - - m_bCDControl = false; - - //this is all needed because libxwax indexes by C-strings - //so we go and pass libxwax a pointer into our local stack... +VinylControlXwax::VinylControlXwax(ConfigObject<ConfigValue>* pConfig, QString group) + : VinylControl(pConfig, group), + m_dVinylPositionOld(0.0), + m_pWorkBuffer(new short[MAX_BUFFER_LEN]), + m_workBufferSize(MAX_BUFFER_LEN), + m_iQualPos(0), + m_iQualFilled(0), + m_iPosition(-1), + m_bAtRecordEnd(false), + m_bForceResync(false), + m_iVCMode(mode->get()), + m_iOldVCMode(MIXXX_VCMODE_ABSOLUTE), + m_dOldFilePos(0.0), + m_dOldDuration(0.0), + m_dOldDurationInaccurate(-1.0), + m_pPitchRing(NULL), + m_iPitchRingSize(0), + m_iPitchRingPos(0), + m_iPitchRingFilled(0), + m_pSteadySubtle(new SteadyPitch(0.12)), + m_pSteadyGross(new SteadyPitch(0.5)), + m_bCDControl(false), + m_bNeedleSkipPrevention(static_cast<bool>(m_pConfig->getValueString( + ConfigKey(VINYL_PREF_KEY, "needle_skip_prevention")).toInt())), + m_bTrackSelectMode(false), + m_pControlTrackSelector(NULL), + m_pControlTrackLoader(NULL), + m_dLastTrackSelectPos(0.0), + m_dCurTrackSelectPos(0.0), + m_dDriftAmt(0.0), + m_dUiUpdateTime(-1.0) { + // TODO(rryan): Should probably live in VinylControlManager since it's not + // specific to a VC deck. + signalenabled->slotSet(m_pConfig->getValueString( + ConfigKey(VINYL_PREF_KEY, "show_signal_quality")).toInt()); + + // Get the vinyl type and speed. + QString strVinylType = m_pConfig->getValueString( + ConfigKey(group,"vinylcontrol_vinyl_type")); + QString strVinylSpeed = m_pConfig->getValueString( + ConfigKey(group,"vinylcontrol_speed_type")); + + // libxwax indexes by C-strings so we pass libxwax string literals so we + // don't have to deal with freeing the strings later + char* timecode = NULL; + + if (strVinylType == MIXXX_VINYL_SERATOCV02VINYLSIDEA) { timecode = (char*)"serato_2a"; } else if (strVinylType == MIXXX_VINYL_SERATOCV02VINYLSIDEB) { timecode = (char*)"serato_2b"; - } - else if (strVinylType == MIXXX_VINYL_SERATOCD) { + } else if (strVinylType == MIXXX_VINYL_SERATOCD) { timecode = (char*)"serato_cd"; m_bNeedleSkipPrevention = false; m_bCDControl = true; - } - else if (strVinylType == MIXXX_VINYL_TRAKTORSCRATCHSIDEA) { + } else if (strVinylType == MIXXX_VINYL_TRAKTORSCRATCHSIDEA) { timecode = (char*)"traktor_a"; - } - else if (strVinylType == MIXXX_VINYL_TRAKTORSCRATCHSIDEB) { + } else if (strVinylType == MIXXX_VINYL_TRAKTORSCRATCHSIDEB) { timecode = (char*)"traktor_b"; - } - else if (strVinylType == MIXXX_VINYL_MIXVIBESDVS) { + } else if (strVinylType == MIXXX_VINYL_MIXVIBESDVS) { timecode = (char*)"mixvibes_v2"; - } - else { + } else { qDebug() << "Unknown vinyl type, defaulting to serato_2a"; timecode = (char*)"serato_2a"; } - timecode_def *tc_def = timecoder_find_definition(timecode); - if (tc_def == NULL) - { + timecode_def* tc_def = timecoder_find_definition(timecode); + if (tc_def == NULL) { qDebug() << "Error finding timecode definition for " << timecode << ", defaulting to serato_2a"; timecode = (char*)"serato_2a"; tc_def = timecoder_find_definition(timecode); @@ -115,17 +128,21 @@ VinylControlXwax::VinylControlXwax(ConfigObject<ConfigValue> * pConfig, QString qDebug() << "Failed to get sane latency, assuming 20 as a reasonable value"; latency = 20; } - // Set pitch ring size to 1/4 of one revolution -- a full revolution adds too much stickiness - // to the pitch. - iPitchRingSize = static_cast<int>(60000 / (rpm * latency * 4)); - m_pPitchRing = new double[iPitchRingSize]; + + int iSampleRate = m_pConfig->getValueString( + ConfigKey("[Soundcard]","Samplerate")).toULong(); + + // Set pitch ring size to 1/4 of one revolution -- a full revolution adds + // too much stickiness to the pitch. + m_iPitchRingSize = static_cast<int>(60000 / (rpm * latency * 4)); + m_pPitchRing = new double[m_iPitchRingSize]; qDebug() << "Xwax Vinyl control starting with a sample rate of:" << iSampleRate; qDebug() << "Building timecode lookup tables for" << strVinylType << "with speed" << strVinylSpeed; - - //Initialize the timecoder structure. - s_xwaxLUTMutex.lock(); //Static mutex! We don't want two threads doing this! + // Initialize the timecoder structure. Use the static mutex so that we only + // do this once across the VinylControlXwax instances. + s_xwaxLUTMutex.lock(); timecoder_init(&timecoder, tc_def, speed, iSampleRate); timecoder_monitor_init(&timecoder, MIXXX_VINYL_SCOPE_SIZE); @@ -137,39 +154,28 @@ VinylControlXwax::VinylControlXwax(ConfigObject<ConfigValue> * pConfig, QString s_xwaxLUTMutex.unlock(); qDebug() << "Starting vinyl control xwax thread"; - - // Variable initialization Copied over from run() - dVinylPosition = 0.0f; - dVinylPitch = 0.0f; - - iPosition = -1; - filePosition = 0.0f; - dDriftAmt = 0.0f; - ringPos = 0; - ringFilled = 0; - old_duration = -1.0f; - tSinceSteadyPitch.start(); - iVCMode = mode->get(); + m_timeSinceSteadyPitch.start(); } -VinylControlXwax::~VinylControlXwax() -{ +VinylControlXwax::~VinylControlXwax() { delete m_pSteadySubtle; delete m_pSteadyGross; delete [] m_pPitchRing; delete [] m_pWorkBuffer; - //Cleanup xwax nicely + // Cleanup xwax nicely timecoder_monitor_clear(&timecoder); timecoder_clear(&timecoder); + + // TODO(rryan): This looks wrong. freeLUTs is called later by + // VinylControlProcessor so we are probably leaking the LUTs. s_bLUTInitialized = false; controlScratch->slotSet(0.0f); } //static -void VinylControlXwax::freeLUTs() -{ +void VinylControlXwax::freeLUTs() { s_xwaxLUTMutex.lock(); //Static mutex! We don't want two threads doing this! if (s_bLUTInitialized) { timecoder_free_lookup(); //Frees all the LUTs in xwax. @@ -233,157 +239,123 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { // polling everytime we get a buffer. - //Check if vinyl control is enabled... - bIsEnabled = checkEnabled(bIsEnabled, enabled->get()); + // Check if vinyl control is enabled... + m_bIsEnabled = checkEnabled(m_bIsEnabled, enabled->get()); - //Get the pitch range from the prefs. - fRateRange = rateRange->get(); - - if(bHaveSignal) - { + if(bHaveSignal) { // Always analyze the input samples - iPosition = timecoder_get_position(&timecoder, NULL); + m_iPosition = timecoder_get_position(&timecoder, NULL); //Notify the UI if the timecode quality is good - establishQuality(iPosition != -1); + establishQuality(m_iPosition != -1); } //are we even playing and enabled at all? - if (!bIsEnabled) - return; - - dVinylPitch = timecoder_get_pitch(&timecoder); - - //if no track loaded, let track selection work but that's it - if (duration == NULL) - { - //until I can figure out how to detect "track 2" on serato CD, - //don't try track selection - if (!m_bCDControl) - { - bTrackSelectMode = true; - doTrackSelection(false, dVinylPitch, iPosition); - } + if (!m_bIsEnabled) return; - } - //qDebug() << m_group << id << iPosition << when << dVinylPitch; - - double cur_duration = duration->get(); - - //Has a new track been loaded? - //FIXME? we should really sync on all track changes - if (cur_duration != old_duration) - { - bForceResync=true; - bTrackSelectMode = false; //just in case - old_duration = cur_duration; - //duration from the control object is an integer. We need - //more precision: - fTrackDuration = trackSamples->get() / 2 / trackSampleRate->get(); - - //we were at record end, so turn it off and restore mode - if(atRecordEnd) - { + double dVinylPitch = timecoder_get_pitch(&timecoder); + + // Has a new track been loaded? Currently we use track duration which is + // integer seconds in the song. However, for calculations we need the + // higher-accuracy duration found by dividing the track samples by the + // samplerate. + // TODO(XXX): we should really sync on all track changes + // TODO(rryan): Should we calculate the true duration to check if it + // changed? It's just an extra division by trackSampleRate. + double duration_inaccurate = duration->get(); + if (duration_inaccurate != m_dOldDurationInaccurate) { + m_bForceResync = true; + m_bTrackSelectMode = false; //just in case + m_dOldDurationInaccurate = duration_inaccurate; + m_dOldDuration = trackSamples->get() / 2 / trackSampleRate->get(); + + // we were at record end, so turn it off and restore mode + if(m_bAtRecordEnd) { disableRecordEndMode(); - if (iOldMode == MIXXX_VCMODE_CONSTANT) - iVCMode = MIXXX_VCMODE_RELATIVE; + if (m_iOldVCMode == MIXXX_VCMODE_CONSTANT) + m_iVCMode = MIXXX_VCMODE_RELATIVE; else - iVCMode = iOldMode; + m_iVCMode = m_iOldVCMode; } } - //make sure dVinylPosition only has good values - if (iPosition != -1) - { - dVinylPosition = iPosition; - dVinylPosition = dVinylPosition / 1000.0f; - dVinylPosition -= iLeadInTime; + // make sure m_dVinylPosition only has good values + if (m_iPosition != -1) { + m_dVinylPosition = static_cast<double>(m_iPosition) / 1000.0 - m_iLeadInTime; } + // Initialize drift control to zero in case we don't get any position data + // to calculate it with. + double dDriftControl = 0.0; - - //Initialize drift control to zero in case we don't get any position data to calculate it with. - dDriftControl = 0.0f; - - filePosition = playPos->get() * fTrackDuration; //Get the playback position in the file in seconds. + // Get the playback position in the file in seconds. + double filePosition = playPos->get() * m_dOldDuration; int reportedMode = mode->get(); bool reportedPlayButton = playButton->get(); - if (iVCMode != reportedMode) - { + if (m_iVCMode != reportedMode) { //if we are playing, don't allow change //to absolute mode (would cause sudden track skip) - if (reportedPlayButton && reportedMode == MIXXX_VCMODE_ABSOLUTE) - { - iVCMode = MIXXX_VCMODE_RELATIVE; - mode->slotSet((double)iVCMode); - } - else //go ahead and switch - { - iVCMode = reportedMode; + if (reportedPlayButton && reportedMode == MIXXX_VCMODE_ABSOLUTE) { + m_iVCMode = MIXXX_VCMODE_RELATIVE; + mode->slotSet((double)m_iVCMode); + } else { + // go ahead and switch + m_iVCMode = reportedMode; if (reportedMode == MIXXX_VCMODE_ABSOLUTE) - bForceResync = true; + m_bForceResync = true; } //if we are out of error mode... - if (vinylStatus->get() == VINYL_STATUS_ERROR && iVCMode == MIXXX_VCMODE_RELATIVE) - { + if (vinylStatus->get() == VINYL_STATUS_ERROR && + m_iVCMode == MIXXX_VCMODE_RELATIVE) { vinylStatus->slotSet(VINYL_STATUS_OK); } } //if looping has been enabled, don't allow absolute mode - if (loopEnabled->get() && iVCMode == MIXXX_VCMODE_ABSOLUTE) - { - iVCMode = MIXXX_VCMODE_RELATIVE; - mode->slotSet((double)iVCMode); + if (loopEnabled->get() && m_iVCMode == MIXXX_VCMODE_ABSOLUTE) { + m_iVCMode = MIXXX_VCMODE_RELATIVE; + mode->slotSet((double)m_iVCMode); } //are we newly playing near the end of the record? (in absolute mode, this happens //when the filepos is past safe (more accurate), //but it can also happen in relative mode if the vinylpos is nearing the end //If so, change to constant mode so DJ can move the needle safely - if (!atRecordEnd && reportedPlayButton) - { - if (iVCMode == MIXXX_VCMODE_ABSOLUTE) - { - if ((filePosition + iLeadInTime) * 1000.0f > m_uiSafeZone && - !bForceResync) //corner case: we are waiting for resync so don't enable just yet - enableRecordEndMode(); - } - else if (iVCMode == MIXXX_VCMODE_RELATIVE || iVCMode == MIXXX_VCMODE_CONSTANT) - { - if (iPosition != -1 && iPosition > static_cast<int>(m_uiSafeZone)) - enableRecordEndMode(); + if (!m_bAtRecordEnd && reportedPlayButton) { + if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && + (filePosition + m_iLeadInTime) * 1000.0f > m_uiSafeZone && + !m_bForceResync) { + // corner case: we are waiting for resync so don't enable just yet + enableRecordEndMode(); + } else if ((m_iVCMode == MIXXX_VCMODE_RELATIVE || m_iVCMode == MIXXX_VCMODE_CONSTANT) && + m_iPosition != -1 && + m_iPosition > static_cast<int>(m_uiSafeZone)) { + enableRecordEndMode(); } } - if (atRecordEnd) - { - //if atRecordEnd was true, maybe it no longer applies: + if (m_bAtRecordEnd) { + //if m_bAtRecordEnd was true, maybe it no longer applies: - if (!reportedPlayButton) - { + if (!reportedPlayButton) { //if we turned off play button, also disable disableRecordEndMode(); - } - else if (iPosition != -1 && - iPosition <= static_cast<int>(m_uiSafeZone) && - dVinylPosition > 0 && - checkSteadyPitch(dVinylPitch, filePosition) > 0.5) - - { + } else if (m_iPosition != -1 && + m_iPosition <= static_cast<int>(m_uiSafeZone) && + m_dVinylPosition > 0 && + checkSteadyPitch(dVinylPitch, filePosition) > 0.5) { //if good position, and safe, and not in leadin, and steady, //disable disableRecordEndMode(); } - if (atRecordEnd) - { + if (m_bAtRecordEnd) { //ok, it's still valid, blink if ((reportedPlayButton && (int)(filePosition * 2.0f) % 2) || - (!reportedPlayButton && (int)(iPosition / 500.0f) % 2)) + (!reportedPlayButton && (int)(m_iPosition / 500.0f) % 2)) vinylStatus->slotSet(VINYL_STATUS_WARNING); else vinylStatus->slotSet(VINYL_STATUS_DISABLED); @@ -394,27 +366,22 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { //then trigger track selection mode. just pass position to it //and ignore pitch - if (!atRecordEnd) - { - if (iPosition != -1 && iPosition > static_cast<int>(m_uiSafeZone)) - { + if (!m_bAtRecordEnd) { + if (m_iPosition != -1 && m_iPosition > static_cast<int>(m_uiSafeZone)) { //only enable if pitch is steady, though. Heavy scratching can //produce crazy results and trigger this mode - if (bTrackSelectMode || checkSteadyPitch(dVinylPitch, filePosition) > 0.1) - { + if (m_bTrackSelectMode || checkSteadyPitch(dVinylPitch, filePosition) > 0.1) { //until I can figure out how to detect "track 2" on serato CD, //don't try track selection - if (!m_bCDControl) - { - if (!bTrackSelectMode) - { - qDebug() << "position greater than safe, select mode" << iPosition << m_uiSafeZone; - bTrackSelectMode = true; + if (!m_bCDControl) { + if (!m_bTrackSelectMode) { + qDebug() << "position greater than safe, select mode" << m_iPosition << m_uiSafeZone; + m_bTrackSelectMode = true; togglePlayButton(false); resetSteadyPitch(0.0f, 0.0f); controlScratch->slotSet(0.0f); } - doTrackSelection(true, dVinylPitch, iPosition); + doTrackSelection(true, dVinylPitch, m_iPosition); } //hm I wonder if track will keep playing while this happens? @@ -425,48 +392,40 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { return; } //if it's not steady yet we process as normal - } - else - { + } else { //so we're not unsafe.... but //if no position, but we were in select mode, do select mode - if (iPosition == -1 && bTrackSelectMode) - { + if (m_iPosition == -1 && m_bTrackSelectMode) { //qDebug() << "no position, but were in select mode"; - doTrackSelection(false, dVinylPitch, iPosition); + doTrackSelection(false, dVinylPitch, m_iPosition); //again, force stop? return; - } - else if (bTrackSelectMode) - { + } else if (m_bTrackSelectMode) { //qDebug() << "discontinuing select mode, selecting track"; - if (trackLoader == NULL) - trackLoader = new ControlObjectThread(m_group,"LoadSelectedTrack"); + if (m_pControlTrackLoader == NULL) + m_pControlTrackLoader = new ControlObjectThread(m_group,"LoadSelectedTrack"); - if (!trackLoader) + if (!m_pControlTrackLoader) { qDebug() << "ERROR: couldn't get track loading object?"; - else - { - trackLoader->slotSet(1.0); - trackLoader->slotSet(0.0); //I think I have to do this... + } else { + m_pControlTrackLoader->slotSet(1.0); + m_pControlTrackLoader->slotSet(0.0); //I think I have to do this... } //if position is known and safe then no track select mode - bTrackSelectMode = false; + m_bTrackSelectMode = false; } } } - if (iVCMode == MIXXX_VCMODE_CONSTANT) - { + if (m_iVCMode == MIXXX_VCMODE_CONSTANT) { //when we enabled constant mode we set the rate slider //now we just either set scratch val to 0 (stops playback) //or 1 (plays back at that rate) - if (reportedPlayButton) - controlScratch->slotSet(rateDir->get() * (rateSlider->get() * fRateRange) + 1.0f); - else - controlScratch->slotSet(0.0f); + double newScratch = reportedPlayButton ? rateDir->get() * + (rateSlider->get() * rateRange->get()) + 1.0f : 0.0; + controlScratch->slotSet(newScratch); //is there any reason we'd need to do anything else? return; @@ -476,132 +435,113 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { // When there's a timecode signal available // This is set when we analyze samples (no need for lock I think) - if(bHaveSignal) - { + if(bHaveSignal) { //POSITION: MAYBE PITCH: YES //We have pitch, but not position. so okay signal but not great (scratching / cueing?) //qDebug() << "Pitch" << dVinylPitch; - if (iPosition != -1) - { + if (m_iPosition != -1) { //POSITION: YES PITCH: YES //add a value to the pitch ring (for averaging / smoothing the pitch) - //qDebug() << fabs(((dVinylPosition - dOldPos) * (dVinylPitch / fabs(dVinylPitch)))); + //qDebug() << fabs(((m_dVinylPosition - m_dVinylPositionOld) * (dVinylPitch / fabs(dVinylPitch)))); //save the absolute amount of drift for when we need to estimate vinyl position - dDriftAmt = dVinylPosition - filePosition; + m_dDriftAmt = m_dVinylPosition - filePosition; - //qDebug() << "drift" << dDriftAmt; + //qDebug() << "drift" << m_dDriftAmt; - if (bForceResync) - { + if (m_bForceResync) { //if forceresync was set but we're no longer absolute, //it no longer applies //if we're in relative mode then we'll do a sync //because it might select a cue - if (iVCMode == MIXXX_VCMODE_ABSOLUTE || (iVCMode == MIXXX_VCMODE_RELATIVE && cueing->get())) - { + if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE || + (m_iVCMode == MIXXX_VCMODE_RELATIVE && cueing->get())) { syncPosition(); - resetSteadyPitch(dVinylPitch, dVinylPosition); + resetSteadyPitch(dVinylPitch, m_dVinylPosition); } - bForceResync = false; - } - else if (fabs(dVinylPosition - filePosition) > 0.1f && - dVinylPosition < -2.0f) - { + m_bForceResync = false; + } else if (fabs(m_dVinylPosition - filePosition) > 0.1f && + m_dVinylPosition < -2.0f) { //At first I thought it was a bug to resync to leadin in relative mode, //but after using it that way it's actually pretty convenient. //qDebug() << "Vinyl leadin"; syncPosition(); - resetSteadyPitch(dVinylPitch, dVinylPosition); + resetSteadyPitch(dVinylPitch, m_dVinylPosition); if (uiUpdateTime(filePosition)) - rateSlider->slotSet(rateDir->get() * (fabs(dVinylPitch) - 1.0f) / fRateRange); - } - else if (iVCMode == MIXXX_VCMODE_ABSOLUTE && (fabs(dVinylPosition - dOldPos) >= 15.0f)) - { + rateSlider->slotSet(rateDir->get() * (fabs(dVinylPitch) - 1.0f) / rateRange->get()); + } else if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && + (fabs(m_dVinylPosition - m_dVinylPositionOld) >= 15.0f)) { //If the position from the timecode is more than a few seconds off, resync the position. //qDebug() << "resync position (>15.0 sec)"; - //qDebug() << dVinylPosition << dOldPos << dVinylPosition - dOldPos; + //qDebug() << m_dVinylPosition << m_dVinylPositionOld << m_dVinylPosition - m_dVinylPositionOld; syncPosition(); - resetSteadyPitch(dVinylPitch, dVinylPosition); - } - else if (iVCMode == MIXXX_VCMODE_ABSOLUTE && m_bNeedleSkipPrevention && - fabs(dVinylPosition - dOldPos) > 0.4 && - (tSinceSteadyPitch.elapsed() < 400 || reportedPlayButton)) - { + resetSteadyPitch(dVinylPitch, m_dVinylPosition); + } else if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && m_bNeedleSkipPrevention && + fabs(m_dVinylPosition - m_dVinylPositionOld) > 0.4 && + (m_timeSinceSteadyPitch.elapsed() < 400 || reportedPlayButton)) { //red alert, moved wrong direction or jumped forward a lot, //and we were just playing nicely... //move to constant mode and keep playing qDebug() << "WARNING: needle skip detected!:"; - qDebug() << filePosition << dOldFilePos << dVinylPosition << dOldPos; - qDebug() << (dVinylPosition - dOldPos) * (dVinylPitch / fabs(dVinylPitch)); + qDebug() << filePosition << m_dOldFilePos << m_dVinylPosition << m_dVinylPositionOld; + qDebug() << (m_dVinylPosition - m_dVinylPositionOld) * (dVinylPitch / fabs(dVinylPitch)); //try setting the rate to the steadypitch value enableConstantMode(m_pSteadySubtle->steadyValue()); vinylStatus->slotSet(VINYL_STATUS_ERROR); - } - else if (iVCMode == MIXXX_VCMODE_ABSOLUTE && m_bCDControl && - fabs(dVinylPosition - dOldPos) >= 0.1f) - { + } else if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && m_bCDControl && + fabs(m_dVinylPosition - m_dVinylPositionOld) >= 0.1f) { //qDebug() << "CDJ resync position (>0.1 sec)"; syncPosition(); - resetSteadyPitch(dVinylPitch, dVinylPosition); - } - else if (playPos->get() >= 1.0 && dVinylPitch > 0) - { + resetSteadyPitch(dVinylPitch, m_dVinylPosition); + } else if (playPos->get() >= 1.0 && dVinylPitch > 0) { //end of track, force stop togglePlayButton(false); resetSteadyPitch(0.0f, 0.0f); controlScratch->slotSet(0.0f); - ringPos = 0; - ringFilled = 0; + m_iPitchRingPos = 0; + m_iPitchRingFilled = 0; return; - } - else - { + } else { togglePlayButton(checkSteadyPitch(dVinylPitch, filePosition) > 0.5); } // Calculate how much the vinyl's position has drifted from it's timecode and compensate for it. // (This is caused by the manufacturing process of the vinyl.) - if (iVCMode == MIXXX_VCMODE_ABSOLUTE && - fabs(dDriftAmt) > 0.1 && fabs(dDriftAmt) < 5.0) { - dDriftControl = dDriftAmt * .01; + if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && + fabs(m_dDriftAmt) > 0.1 && fabs(m_dDriftAmt) < 5.0) { + dDriftControl = m_dDriftAmt * .01; } else { dDriftControl = 0.0; } - dOldPos = dVinylPosition; - } - else - { + m_dVinylPositionOld = m_dVinylPosition; + } else { //POSITION: NO PITCH: YES //if we don't have valid position, we're not playing so reset time to current //estimate vinyl position - if (playPos->get() >= 1.0 && dVinylPitch > 0) - { + if (playPos->get() >= 1.0 && dVinylPitch > 0) { //end of track, force stop togglePlayButton(false); resetSteadyPitch(0.0f, 0.0f); controlScratch->slotSet(0.0f); - ringPos = 0; - ringFilled = 0; + m_iPitchRingPos = 0; + m_iPitchRingFilled = 0; return; } - if (iVCMode == MIXXX_VCMODE_ABSOLUTE && + if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && fabs(dVinylPitch) < 0.05 && - fabs(dDriftAmt) >= 0.3f) - { + fabs(m_dDriftAmt) >= 0.3f) { //qDebug() << "slow, out of sync, syncing position"; syncPosition(); } - dOldPos = filePosition + dDriftAmt; + m_dVinylPositionOld = filePosition + m_dDriftAmt; - if (dVinylPitch > 0.2) - { + if (dVinylPitch > 0.2) { togglePlayButton(checkSteadyPitch(dVinylPitch, filePosition) > 0.5); } } @@ -611,24 +551,24 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { if (reportedPlayButton) { // Only add to the ring if pitch is stable - m_pPitchRing[ringPos] = dVinylPitch; - if (ringFilled < iPitchRingSize) { - ringFilled++; + m_pPitchRing[m_iPitchRingPos] = dVinylPitch; + if (m_iPitchRingFilled < m_iPitchRingSize) { + m_iPitchRingFilled++; } - ringPos = (ringPos + 1) % iPitchRingSize; + m_iPitchRingPos = (m_iPitchRingPos + 1) % m_iPitchRingSize; } else { // Reset ring if pitch isn't steady - ringPos = 0; - ringFilled = 0; + m_iPitchRingPos = 0; + m_iPitchRingFilled = 0; } //only smooth when we have good position (no smoothing for scratching) double averagePitch = 0.0f; - if (iPosition != -1 && reportedPlayButton) { - for (int i = 0; i < ringFilled; ++i) { + if (m_iPosition != -1 && reportedPlayButton) { + for (int i = 0; i < m_iPitchRingFilled; ++i) { averagePitch += m_pPitchRing[i]; } - averagePitch /= ringFilled; + averagePitch /= m_iPitchRingFilled; // Round out some of the noise averagePitch = round(averagePitch * 10000.0f); averagePitch /= 10000.0f; @@ -637,16 +577,17 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { } controlScratch->slotSet(averagePitch + dDriftControl); - if (iPosition != -1 && reportedPlayButton && uiUpdateTime(filePosition)) { + if (m_iPosition != -1 && reportedPlayButton && uiUpdateTime(filePosition)) { rateSlider->slotSet(rateDir->get() * - (fabs(averagePitch + dDriftControl) - 1.0f) / fRateRange); - dUiUpdateTime = filePosition; + (fabs(averagePitch + dDriftControl) - 1.0f) / rateRange->get()); + m_dUiUpdateTime = filePosition; } - dOldFilePos = filePosition; - } - else //No pitch data available (the needle is up/stopped.... or *really* crappy signal) - { + m_dOldFilePos = filePosition; + } else { + // No pitch data available (the needle is up/stopped.... or *really* + // crappy signal) + //POSITION: NO PITCH: NO //if it's been a long time, we're stopped. //if it hasn't been long, and we're preventing needle skips, @@ -654,83 +595,75 @@ void VinylControlXwax::analyzeSamples(CSAMPLE* pSamples, size_t nFrames) { rateSlider->slotSet(0.0f); - if (iVCMode == MIXXX_VCMODE_ABSOLUTE && - fabs(dVinylPosition - filePosition) >= 0.1f) - { + if (m_iVCMode == MIXXX_VCMODE_ABSOLUTE && + fabs(m_dVinylPosition - filePosition) >= 0.1f) { //qDebug() << "stopped, out of sync, syncing position"; syncPosition(); } - if(fabs(filePosition - dOldFilePos) >= 0.1 || - !m_bNeedleSkipPrevention || - filePosition == dOldFilePos) - { + if(fabs(filePosition - m_dOldFilePos) >= 0.1 || + !m_bNeedleSkipPrevention || + filePosition == m_dOldFilePos) { //We are not playing any more togglePlayButton(false); resetSteadyPitch(0.0f, 0.0f); controlScratch->slotSet(0.0f); //resetSteadyPitch(dVinylPitch, filePosition); - //Notify the UI that the timecode quality is garbage/missing. + // Notify the UI that the timecode quality is garbage/missing. m_fTimecodeQuality = 0.0f; - ringPos = 0; - ringFilled = 0; - iQualPos = 0; - iQualFilled = 0; - bForceResync=true; + m_iPitchRingPos = 0; + m_iPitchRingFilled = 0; + m_iQualPos = 0; + m_iQualFilled = 0; + m_bForceResync = true; vinylStatus->slotSet(VINYL_STATUS_OK); } } } -void VinylControlXwax::enableRecordEndMode() -{ +void VinylControlXwax::enableRecordEndMode() { qDebug() << "record end, setting constant mode"; vinylStatus->slotSet(VINYL_STATUS_WARNING); enableConstantMode(); - atRecordEnd = true; + m_bAtRecordEnd = true; } -void VinylControlXwax::enableConstantMode() -{ - iOldMode = iVCMode; - iVCMode = MIXXX_VCMODE_CONSTANT; - mode->slotSet((double)iVCMode); +void VinylControlXwax::enableConstantMode() { + m_iOldVCMode = m_iVCMode; + m_iVCMode = MIXXX_VCMODE_CONSTANT; + mode->slotSet((double)m_iVCMode); togglePlayButton(true); double rate = controlScratch->get(); - rateSlider->slotSet(rateDir->get() * (fabs(rate) - 1.0f) / fRateRange); + rateSlider->slotSet(rateDir->get() * (fabs(rate) - 1.0f) / rateRange->get()); controlScratch->slotSet(rate); } -void VinylControlXwax::enableConstantMode(double rate) -{ - iOldMode = iVCMode; - iVCMode = MIXXX_VCMODE_CONSTANT; - mode->slotSet((double)iVCMode); +void VinylControlXwax::enableConstantMode(double rate) { + m_iOldVCMode = m_iVCMode; + m_iVCMode = MIXXX_VCMODE_CONSTANT; + mode->slotSet((double)m_iVCMode); togglePlayButton(true); - rateSlider->slotSet(rateDir->get() * (fabs(rate) - 1.0f) / fRateRange); + rateSlider->slotSet(rateDir->get() * (fabs(rate) - 1.0f) / rateRange->get()); controlScratch->slotSet(rate); } -void VinylControlXwax::disableRecordEndMode() -{ +void VinylControlXwax::disableRecordEndMode() { vinylStatus->slotSet(VINYL_STATUS_OK); - atRecordEnd = false; - iVCMode = MIXXX_VCMODE_RELATIVE; - mode->slotSet((double)iVCMode); + m_bAtRecordEnd = false; + m_iVCMode = MIXXX_VCMODE_RELATIVE; + mode->slotSet((double)m_iVCMode); } -void VinylControlXwax::togglePlayButton(bool on) -{ - if (bIsEnabled && (playButton->get() > 0) != on) { +void VinylControlXwax::togglePlayButton(bool on) { + if (m_bIsEnabled && (playButton->get() > 0) != on) { //switching from on to off -- restart counter for checking needleskip if (!on) - tSinceSteadyPitch.restart(); + m_timeSinceSteadyPitch.restart(); playButton->slotSet((float)on); //and we all float on all right } } -void VinylControlXwax::doTrackSelection(bool valid_pos, double pitch, double position) -{ +void VinylControlXwax::doTrackSelection(bool valid_pos, double pitch, double position) { //compare positions, fabricating if we don't have position data, and //move the selector every so often //track will be selected when the needle is moved back to play area @@ -739,59 +672,52 @@ void VinylControlXwax::doTrackSelection(bool valid_pos, double pitch, double pos const int SELECT_INTERVAL = 150; const double NOPOS_SPEED = 0.50; - if (trackSelector == NULL) - { + if (m_pControlTrackSelector == NULL) { //this isn't done in the constructor because |