Exemplo n.º 1
0
HRESULT CParamsManager::GetParam(DWORD dwParamIndex,MP_DATA *pValue)
{
    V_INAME(CParams::GetParam);
    V_PTR_WRITE(pValue, MP_DATA);

	if (dwParamIndex >= m_cParams)
		return E_INVALIDARG;

    EnterCriticalSection(&m_ParamsCriticalSection);

	CCurveList *pList = &m_pCurveLists[dwParamIndex];
	ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
	// if no points, then neutral value
	CCurveItem *pCurve = pList->GetHead();
	if (pCurve)
	{
		*pValue = pCurve->m_Envelope.valEnd;
	}
    else
    {
        *pValue = pInfo->MParamInfo.mpdNeutralValue;
    }
    LeaveCriticalSection(&m_ParamsCriticalSection);
    return S_OK;
}
Exemplo n.º 2
0
HRESULT CParamsManager::AddEnvelope(
        DWORD dwParamIndex,
        DWORD cPoints,
        MP_ENVELOPE_SEGMENT *ppEnvelope)
{
    V_INAME(CParams::AddEnvelope);
    V_PTR_READ(ppEnvelope, *ppEnvelope);

    if (dwParamIndex >= m_cParams)
        return E_INVALIDARG;

    if (!m_pParamInfos)
        return DMUS_E_NOT_INIT;

    HRESULT hr = S_OK;
    EnterCriticalSection(&m_ParamsCriticalSection);
    m_fDirty = TRUE;

    CCurveList *pList = &m_pCurveLists[dwParamIndex];
    ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];

    DWORD dwCount;
    for (dwCount = 0; dwCount < cPoints; dwCount++)
    {
        CCurveItem *pCurve = new CCurveItem;
        if (!pCurve) 
        {
            hr = E_OUTOFMEMORY;
            break;
        }

        pCurve->m_Envelope = ppEnvelope[dwCount];

        pCurve->m_Envelope.valEnd = ValRange(pCurve->m_Envelope.valEnd, 
            pInfo->MParamInfo.mpdMinValue, pInfo->MParamInfo.mpdMaxValue);

        pCurve->m_Envelope.valStart = ValRange(pCurve->m_Envelope.valStart, 
            pInfo->MParamInfo.mpdMinValue, pInfo->MParamInfo.mpdMaxValue);

        pList->AddHead(pCurve);

        // next call to UpdateActiveParams will ensure the parameter's value is recalculated
        m_dwActiveBits |= 1 << dwParamIndex; 

        //TraceI(6, "DMO envelope: time %I64d-%I64d, param #%d, value %hf-%hf\n",
        //      pCurve->m_Envelope.rtStart, pCurve->m_Envelope.rtEnd,
        //      dwParamIndex, pCurve->m_Envelope.valStart, pCurve->m_Envelope.valEnd);
    }

    LeaveCriticalSection(&m_ParamsCriticalSection);

    return hr;
}
Exemplo n.º 3
0
HRESULT CParamsManager::SetParam(DWORD dwParamIndex,MP_DATA value)
{
	V_INAME(CParams::SetParam);
    
	if (dwParamIndex >= m_cParams)
		return E_INVALIDARG;

    EnterCriticalSection(&m_ParamsCriticalSection);
    m_fDirty = TRUE;
	CCurveList *pList = &m_pCurveLists[dwParamIndex];
	// ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];

	// If we've already got a list, just force the most recent curve item to this value.
    // Otherwise, create a node and add it.
	CCurveItem *pCurve = pList->GetHead();
	if (!pCurve)
	{
        pCurve = new CCurveItem;
        if (pCurve)
        {
            pCurve->m_Envelope.rtStart =    0x8000000000000000; // Max negative.
            pCurve->m_Envelope.rtEnd =      0x7FFFFFFFFFFFFFFF; // Max positive.
            pCurve->m_Envelope.flags = 0;
            pList->AddHead(pCurve);
        }
		else 
        {
            LeaveCriticalSection(&m_ParamsCriticalSection);
            return E_OUTOFMEMORY;
        }
	}
    pCurve->m_Envelope.valStart = value;
    pCurve->m_Envelope.valEnd = value;
    pCurve->m_Envelope.iCurve = MP_CURVE_JUMP;
    LeaveCriticalSection(&m_ParamsCriticalSection);

    return S_OK;
}
Exemplo n.º 4
0
HRESULT CParamsManager::FlushEnvelope(
        DWORD dwParamIndex,
        REFERENCE_TIME refTimeStart,
        REFERENCE_TIME refTimeEnd)
{
    if (dwParamIndex >= m_cParams)
        return E_INVALIDARG;

    if (!m_pParamInfos)
        return DMUS_E_NOT_INIT;

    if (refTimeStart >= refTimeEnd)
        return E_INVALIDARG;

    EnterCriticalSection(&m_ParamsCriticalSection);
    m_fDirty = TRUE;

    CCurveList *pList = &m_pCurveLists[dwParamIndex];
    CCurveList TempList;
    CCurveItem *pCurve;

    while ((pCurve = pList->RemoveHead()) != 0)
    {
        if ((pCurve->m_Envelope.rtStart >= refTimeStart) && 
            (pCurve->m_Envelope.rtEnd <= refTimeEnd))
        {
            delete pCurve;
        }
        else 
        {
            TempList.AddHead(pCurve);
        }
    }

    while ((pCurve = TempList.RemoveHead()) != 0)
    {
        pList->AddHead(pCurve);
    }

    LeaveCriticalSection(&m_ParamsCriticalSection);

    return S_OK;
}
Exemplo n.º 5
0
HRESULT CParamsManager::GetParamFloat(DWORD dwParamIndex,REFERENCE_TIME rtTime,float *pval)
{
	HRESULT hr = S_OK;

	if (dwParamIndex >= m_cParams)
		return E_INVALIDARG;

    EnterCriticalSection(&m_ParamsCriticalSection);
	CCurveList *pList = &m_pCurveLists[dwParamIndex];
	ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];

	// if no points, then neutral value
	CCurveItem *pCurveHead = pList->GetHead();
	if (!pCurveHead)
	{
		*pval = pInfo->MParamInfo.mpdNeutralValue;
        LeaveCriticalSection(&m_ParamsCriticalSection);
		return S_FALSE;
	}

	// Find the curve during or before the requested time
    // If the time is during a curve, we will use that.
    // If not, we need the end value of the previous curve.
    // Our list keeps these in backwards order, so we are scanning from the 
    // highest point in time backwards.

	for (CCurveItem *pCurve = pCurveHead; pCurve && pCurve->m_Envelope.rtStart > rtTime;pCurve = pCurve->GetNext());

    // If there is no pCurve, there was no curve prior to or during rtTime. Give up.
    if (!pCurve)
    {
        *pval = pInfo->MParamInfo.mpdNeutralValue;
        LeaveCriticalSection(&m_ParamsCriticalSection);
		return S_OK;
    }
    // Now, if pCurve ends before the requested time,
    // return the final value of pCurve, since that will hold until the start of the next curve.
    if (pCurve->m_Envelope.rtEnd < rtTime)
    {
		*pval = pCurve->m_Envelope.valEnd;
        LeaveCriticalSection(&m_ParamsCriticalSection);
		if (pCurve == pCurveHead)
			return S_FALSE; // past last curve
		else
			return S_OK; // there are more curves ahead
	}

    // If we get this far, the curve must bound rtTime.

	if (pCurve->m_Envelope.iCurve & MP_CURVE_JUMP)
	{
		*pval = pCurve->m_Envelope.valEnd;
        LeaveCriticalSection(&m_ParamsCriticalSection);
		return S_OK;
	}

	REFERENCE_TIME rtTimeChange = pCurve->m_Envelope.rtEnd - pCurve->m_Envelope.rtStart;
	REFERENCE_TIME rtTimeIntermediate = rtTime - pCurve->m_Envelope.rtStart; 

	float fltScalingX = static_cast<float>(rtTimeIntermediate) / rtTimeChange; // horizontal distance along curve between 0 and 1
	float fltScalingY; // height of curve at that point between 0 and 1 based on curve function
    switch (pCurve->m_Envelope.iCurve)
    {
    case MP_CURVE_SQUARE:
		fltScalingY = fltScalingX * fltScalingX;
        break;
    case MP_CURVE_INVSQUARE:
		fltScalingY = (float) sqrt(fltScalingX);
        break;
    case MP_CURVE_SINE:
        // §§ Maybe we should have a lookup table here?
        fltScalingY = (float) (sin(fltScalingX * 3.1415926535 - (3.1415926535/2)) + 1) / 2;
        break;
    case MP_CURVE_LINEAR:
    default:
		fltScalingY = fltScalingX;
    }

    // Find out if we need to pull the start point from the previous curve,
    // the default neutral value, or the current curve.
    float fStartVal = pCurve->m_Envelope.valStart;
    if (pCurve->m_Envelope.flags & MPF_ENVLP_BEGIN_NEUTRALVAL)
    {
        fStartVal = pInfo->MParamInfo.mpdNeutralValue;
    }
    // Currentval, if it exists, will override neutralval.
    if (pCurve->m_Envelope.flags & MPF_ENVLP_BEGIN_CURRENTVAL)
    {
        // Take advantage of the fact that these are inserted in backwards order.
        // Scan for the previous curve that ends before this time.
        CCurveItem *pPrevious = pCurve->GetNext();
       	for (;pPrevious && pPrevious->m_Envelope.rtEnd > rtTime;pPrevious = pPrevious->GetNext());
        if (pPrevious)
        {
            fStartVal = pPrevious->m_Envelope.valEnd;
        }
    }
    
    // Apply that scaling to the range of the actual points
    *pval = (pCurve->m_Envelope.valEnd - fStartVal) * fltScalingY + fStartVal;

    LeaveCriticalSection(&m_ParamsCriticalSection);
    return hr;
}