Example #1
0
static int sync_to_timecode(struct player_t *pl)
{
    float when;
    double tcpos;
    signed int timecode;

    timecode = timecoder_get_position(pl->timecoder, &when);

    /* Instruct the caller to disconnect the timecoder if the needle
     * is outside the 'safe' zone of the record */

    if(timecode != -1 && timecode > timecoder_get_safe(pl->timecoder))
        return -1;

    /* If the timecoder is alive, use the pitch from the sine wave */

    pl->pitch = timecoder_get_pitch(pl->timecoder);

    /* If we can read an absolute time from the timecode, then use it */

    if(timecode == -1)
        pl->target_valid = 0;

    else {
        tcpos = (double)timecode / timecoder_get_resolution(pl->timecoder);
        pl->target_position = tcpos + pl->pitch * when;
        pl->target_valid = 1;
    }

    return 0;
}
Example #2
0
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_dDisplayPitch(0.0),
          m_pSteadySubtle(new SteadyPitch(0.12)),
          m_pSteadyGross(new SteadyPitch(0.5)),
          m_bCDControl(false),
          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) {
        timecode = (char*)"serato_cd";
        m_bCDControl = true;
    } else if (strVinylType == MIXXX_VINYL_TRAKTORSCRATCHSIDEA) {
        timecode = (char*)"traktor_a";
    } else if (strVinylType == MIXXX_VINYL_TRAKTORSCRATCHSIDEB) {
        timecode = (char*)"traktor_b";
    } else if (strVinylType == MIXXX_VINYL_MIXVIBESDVS) {
        timecode = (char*)"mixvibes_v2";
    } 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) {
        qDebug() << "Error finding timecode definition for " << timecode << ", defaulting to serato_2a";
        timecode = (char*)"serato_2a";
        tc_def = timecoder_find_definition(timecode);
    }

    double speed = 1.0;
    double rpm = 100.0 / 3.0;
    if (strVinylSpeed == MIXXX_VINYL_SPEED_45) {
        rpm = 45.0;
        speed = 1.35;
    }

    double latency = ControlObject::getControl(
            ConfigKey("[Master]", "latency"))->get();
    if (latency <= 0 || latency > 200) {
        qDebug() << "Failed to get sane latency, assuming 20 as a reasonable value";
        latency = 20;
    }

    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. 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, /* phono */ false);
    timecoder_monitor_init(&timecoder, MIXXX_VINYL_SCOPE_SIZE);
    //Note that timecoder_init will not double-malloc the LUTs, and after this we are guaranteed
    //that the LUT has been generated unless we ran out of memory.
    s_bLUTInitialized = true;
    m_uiSafeZone = timecoder_get_safe(&timecoder);
    //}
    s_xwaxLUTMutex.unlock();

    qDebug() << "Starting vinyl control xwax thread";
}