Example #1
0
void DrVertexProcessStatus::CopyFrom(DrVertexProcessStatusPtr src,
                                     bool includeLengths)
{
    int i;

    SetVertexId(src->GetVertexId());
    SetVertexInstanceVersion(src->GetVertexInstanceVersion());
    SetVertexMetaData(src->GetVertexMetaData());
    SetVertexErrorCode(src->GetVertexErrorCode());
    SetVertexErrorString(src->GetVertexErrorString());

    SetInputChannelCount(src->GetInputChannels()->Allocated());
    DrInputChannelArrayRef srcInputs = src->GetInputChannels();
    for (i=0; i<m_inputChannel->Allocated(); ++i)
    {
        m_inputChannel[i]->CopyFrom(srcInputs[i], includeLengths);
    }
    SetMaxOpenInputChannelCount(src->GetMaxOpenInputChannelCount());

    SetOutputChannelCount(src->GetOutputChannels()->Allocated());
    DrOutputChannelArrayRef srcOutputs = src->GetOutputChannels();
    for (i=0; i<m_outputChannel->Allocated(); ++i)
    {
        m_outputChannel[i]->CopyFrom(srcOutputs[i], includeLengths);
    }
    SetMaxOpenOutputChannelCount(src->GetMaxOpenOutputChannelCount());
}
Example #2
0
HRESULT DrVertexProcessStatus::ParseProperty(DrPropertyReaderPtr reader,
                                             UINT16 enumID, UINT32 /* unused dataLen */)
{
    HRESULT err;

    switch (enumID)
    {
    default:
        DrLogW("Unknown property in vertex status message enumID %u", (UINT32) enumID);
        err = reader->SkipNextPropertyOrAggregate();
        break;

    case DrProp_VertexId:
        UINT32 id;
        err = reader->ReadNextProperty(enumID, id);
        if (err == S_OK)
        {
            if (id >= 0x80000000)
            {
                DrLogW("Vertex ID out of range %u", id);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
            else
            {
                m_id = id;
            }
        }
        break;

    case DrProp_VertexVersion:
        UINT32 version;
        err = reader->ReadNextProperty(enumID, version);
        if (err == S_OK)
        {
            if (version >= 0x80000000)
            {
                DrLogW("Vertex version out of range %u", version);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
            else
            {
                m_version = version;
            }
        }
        break;

    case DrProp_VertexErrorCode:
        err = reader->ReadNextProperty(enumID, m_errorCode);
        break;

    case DrProp_VertexErrorString:
        {
            DrString errorString;
            err = reader->ReadNextProperty(enumID, errorString);
            if (err == S_OK)
            {
                SetVertexErrorString(errorString);
            }
        }
        break;

    case DrProp_VertexInputChannelCount:
        UINT32 nInputChannels;
        err = reader->ReadNextProperty(enumID, nInputChannels);
        if (err == S_OK)
        {
            if (nInputChannels >= 0x80000000)
            {
                DrLogW("Too many input channels %u", nInputChannels);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
            else
            {
                SetInputChannelCount((int) nInputChannels);
            }
        }
        break;

    case DrProp_VertexMaxOpenInputChannelCount:
        UINT32 maxInputChannels;
        err = reader->ReadNextProperty(enumID, maxInputChannels);
        if (err == S_OK)
        {
            if (maxInputChannels >= 0x80000000)
            {
                DrLogW("Too many max input channels %u", maxInputChannels);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
            else
            {
                m_maxInputChannels = (int) maxInputChannels;
            }
        }
        break;

    case DrProp_VertexOutputChannelCount:
        UINT32 nOutputChannels;
        err = reader->ReadNextProperty(enumID, nOutputChannels);
        if (err == S_OK)
        {
            if (nOutputChannels >= 0x80000000)
            {
                DrLogW("Too many output channels %u", nOutputChannels);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
            else
            {
                SetOutputChannelCount((int) nOutputChannels);
            }
        }
        break;

    case DrProp_VertexMaxOpenOutputChannelCount:
        UINT32 maxOutputChannels;
        err = reader->ReadNextProperty(enumID, maxOutputChannels);
        if (err == S_OK)
        {
            if (maxOutputChannels >= 0x80000000)
            {
                DrLogW("Too many max output channels %d", maxOutputChannels);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
            else
            {
                m_maxOutputChannels = (int) maxOutputChannels;
            }
        }
        break;

    case DrProp_CanShareWorkQueue:
        err = reader->ReadNextProperty(enumID, m_canShareWorkQueue);
        break;

    case DrProp_BeginTag:
        UINT16 tagValue;
        err = reader->PeekNextAggregateTag(&tagValue);
        if (err != S_OK)
        {
            DrLogW("Error reading DrProp_BeginTag %d", err);
        }
        else
        {
            switch (tagValue)
            {
            case DrTag_InputChannelDescription:
                if (m_nextInputChannelToRead >= m_inputChannel->Allocated())
                {
                    DrLogW("Too many input channel descriptions nextInputChannelToRead=%d, nInputChannels=%d",
                           m_nextInputChannelToRead, m_inputChannel->Allocated());
                    err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
                }
                else
                {
                    err = reader->ReadAggregate(tagValue, m_inputChannel[m_nextInputChannelToRead]);
                    if (err == S_OK)
                    {
                        ++m_nextInputChannelToRead;
                    }
                }
                break;

            case DrTag_OutputChannelDescription:
                if (m_nextOutputChannelToRead >= m_outputChannel->Allocated())
                {
                    DrLogW("Too many output channel descriptions nextOutputChannelToRead=%d, nOutputChannels=%d",
                           m_nextOutputChannelToRead, m_outputChannel->Allocated());
                    err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
                }
                else
                {
                    err = reader->ReadAggregate(tagValue, m_outputChannel[m_nextOutputChannelToRead]);
                    if (err == S_OK)
                    {
                        ++m_nextOutputChannelToRead;
                    }
                }
                break;

            case DrTag_VertexMetaData:
                {
                    DrMetaDataRef metaData = DrNew DrMetaData();
                    err = reader->ReadAggregate(tagValue, metaData);
                    if (err == S_OK)
                    {
                        m_metaData = metaData;
                    }
                }
                break;

            default:
                DrLogW("Unexpected tag %d", tagValue);
                err = reader->SkipNextPropertyOrAggregate();
            }
        }
        break;
    }

    return err;
}
void CTrack_DSP::Process(tint32 iSamples)
{
	if (mbIsBusOrMix == true) {
		mpBuffer->SetChannelsNoConvert(2);
	}
	else
		mpBuffer->SetChannelsNoConvert(1);
		
	if (mbIsBusOrMix == false) {
		mpBuffer->Clear();
	}

	// (mo) Note: Currently if 2 sounds overlap, the second will be played out of sync

	// We use this temporary copy, so we can change it in the loop
	tuint64 uiSongPosTemp = muiSongPos;
	tuint64 iSamplesLeft = iSamples;
	tuint64 iBufferIndex = 0;
	while (mitRegionsInfo != mRegionInfoList.end() &&
			iSamplesLeft) {
		// Still region(s) to play
		CRegion_DSP* pRegion = (*mitRegionsInfo)->pRegion;
		tuint64 uiPosStart = (*mitRegionsInfo)->uiTrack_Pos;
		tuint64 uiPosEnd = uiPosStart + pRegion->Get_Duration() - 1;

		tint32 iChannels = pRegion->GetChannels();
		mpBuffer->SetChannels(iChannels);

		if (uiPosStart <= uiSongPosTemp) {
			if (uiPosEnd >= uiSongPosTemp) {
				tint32 iSamplesToGet = (tint32)(uiPosEnd - uiPosStart + 1);
				if (iSamplesToGet > iSamplesLeft) {
					iSamplesToGet = (tint32)iSamplesLeft;
				}
				if (iSamplesToGet > uiPosEnd - uiSongPosTemp + 1) {
					iSamplesToGet = (tint32)(uiPosEnd - uiSongPosTemp + 1);
				}

				if (iChannels == 1) {
					tfloat32* pfData = mpBuffer->GetData(0);
					tfloat32* ppfData[1];
					ppfData[0] = pfData + iBufferIndex;
					pRegion->GetSamples(ppfData, iSamplesToGet);
					if (mbLimitDataFromStream) {
						// Maybe silence some samples at start and/or end of portion

						// Silence at start?
						tint64 iSilentSamples_Start = miFirstStreamIx_Limited - uiSongPosTemp;
						if (iSilentSamples_Start > 0) {
							// We need to silence some samples at start of portion
							if (iSilentSamples_Start > iSamplesToGet) {
								iSilentSamples_Start = iSamplesToGet;
							}
							mpDSPTools->Clear(ppfData[0], iSilentSamples_Start);
						}

						// Silence at end?
						tint64 iSilentSamples_EndIx = miFinalStreamIx_Limited - uiSongPosTemp;
						if (iSilentSamples_EndIx < iSamplesToGet) {
							// We need to silence some samples at end of portion
							if (iSilentSamples_EndIx < 0) {
								iSilentSamples_EndIx = 0;
							}
							tint32 iSamplesToSilence = iSamplesToGet - iSilentSamples_EndIx;
							tfloat32* pf0Ix = ((tfloat32*)ppfData[0]) + iSilentSamples_EndIx;
							mpDSPTools->Clear(pf0Ix, iSamplesToSilence);
						}
					}
				}
				else {
					tfloat32* pfData1 = mpBuffer->GetData(0);
					tfloat32* pfData2 = mpBuffer->GetData(1);
					tfloat32* ppfData[2];
					ppfData[0] = pfData1 + iBufferIndex;
					ppfData[1] = pfData2 + iBufferIndex;
					pRegion->GetSamples(ppfData, iSamplesToGet);
					if (mbLimitDataFromStream) {
						// Maybe silence some samples at start and/or end of portion

						// Silence at start?
						tint64 iSilentSamples_Start = miFirstStreamIx_Limited - uiSongPosTemp;
						if (iSilentSamples_Start > 0) {
							// We need to silence some samples at start of portion
							if (iSilentSamples_Start > iSamplesToGet) {
								iSilentSamples_Start = iSamplesToGet;
							}
							mpDSPTools->Clear(ppfData[0], iSilentSamples_Start);
							mpDSPTools->Clear(ppfData[1], iSilentSamples_Start);
						}

						// Silence at end?
						tint64 iSilentSamples_EndIx = miFinalStreamIx_Limited - uiSongPosTemp;
						if (iSilentSamples_EndIx < iSamplesToGet) {
							// We need to silence some samples at end of portion
							if (iSilentSamples_EndIx < 0) {
								iSilentSamples_EndIx = 0;
							}
							tint32 iSamplesToSilence = iSamplesToGet - iSilentSamples_EndIx;
							tfloat32* pf0Ix = ((tfloat32*)ppfData[0]) + iSilentSamples_EndIx;
							tfloat32* pf1Ix = ((tfloat32*)ppfData[1]) + iSilentSamples_EndIx;
							mpDSPTools->Clear(pf0Ix, iSamplesToSilence);
							mpDSPTools->Clear(pf1Ix, iSamplesToSilence);
						}
					}
				}

				iSamplesLeft -= iSamplesToGet;
				uiSongPosTemp += iSamplesToGet;
				iBufferIndex += iSamplesToGet;
			}
			else {
				// Skip to next region
				mitRegionsInfo++;

				if (mitRegionsInfo != mRegionInfoList.end()) {
					(*mitRegionsInfo)->pRegion->SetPos(0);

					if ((*mitRegionsInfo)->pRegion->GetChannels() > iChannels) {
						iChannels = (*mitRegionsInfo)->pRegion->GetChannels();
					}
				}
			}
		}
		else {
			// Region not started yet
			tuint64 uiSamplesToClear = uiPosStart - uiSongPosTemp;
			if (uiSamplesToClear > iSamplesLeft) {
				uiSamplesToClear = iSamplesLeft;
			}

			tfloat32* pfData = mpBuffer->GetData(0);
			mpDSPTools->Clear(pfData + iBufferIndex, (tuint32)uiSamplesToClear);

			iSamplesLeft -= (tuint32)uiSamplesToClear;
			uiSongPosTemp += (tuint32)uiSamplesToClear;
			iBufferIndex += (tuint32)uiSamplesToClear;
		}
	}

/*	mpBuffer->SetChannels(2);
	muiSongPos += iSamples;
	return;*/

	if (mbArmed) {
		tint32 iInputChannel = miInputChannel;

		// (lasse) Huh? What's this for?
		tint32 iChannels = 1;
		if (miInputChannel >= 1000) {
			iChannels = 2;
			iInputChannel -= 1000;
		}

		mpBuffer->SetChannels(iChannels);

		mpDSP->GetInput(mpBuffer, iChannels, iInputChannel, iSamples);

		if (miRecordingChannels == -1) {
			// (lasse) This is a HACK - need a way to determine
			miRecordingChannels = 2;//iChannels;
			// .. (lasse)

			iChannels = miRecordingChannels;
		}

		if (mpFileRecording) {
			SetInputChannelCount(miRecordingChannels);
			SetTrackMode(miRecordingChannels);

			if (miRecordingChannels == 1) {
				tfloat32* pf = mpBuffer->GetData(0);
				for (tint32 iPeak = iSamples; iPeak > 0; iPeak--) {
					tfloat32 f = fabs(*pf++);
					if (f > mfPeak)	mfPeak = f;
				}
				mpFileRecording->Write((const tchar*)mpBuffer->GetData(0), iSamples * sizeof(tfloat32));
			}
			else {
				tfloat32* pfL = mpBuffer->GetData(0);
				tfloat32* pfR = mpBuffer->GetData(1);
				for (tint32 iPeak = iSamples; iPeak > 0; iPeak--) {
					tfloat32 fL = *pfL++;
					tfloat32 fR = *pfR++;
					tfloat32 fMono = fL + fR;
					fL = fabs(fL);
					fR = fabs(fR);
					fMono = fabs(fMono);
					if (fL > mfPeak)		mfPeak = fL;
					if (fR > mfPeak)		mfPeak = fR;
					if (fMono > mfPeakMono)	mfPeakMono = fMono;
				}
				mpFileRecording->Write((const tchar*)mpBuffer->GetData(0), iSamples * sizeof(tfloat32));
				mpFileRecording->Write((const tchar*)mpBuffer->GetData(1), iSamples * sizeof(tfloat32));
			}
		}
	}

	// Tell the buffer how many channels it has from outset
	mpBuffer->SetChannels(miInputChannelCount);

	// If the bus mode has more channels than the raw input we haven't done the up-mix yet - do it now
	if (miModeChannelCount > miInputChannelCount) {
		// Mix up
		mpBuffer->SetChannels(miModeChannelCount);
	}

	// Apply effects
	tint32 iInsert;
	for (iInsert = 0; iInsert < giNumber_Of_Inserts; iInsert++) {
		if (mppInsert[iInsert] && mpbInsertBypass[iInsert] == false) {
			tfloat32* ppfBuffersOut[2];
			ppfBuffersOut[0] = mpfBufferTmp1;
			ppfBuffersOut[1] = mpfBufferTmp2;
			tfloat32* pfData1 = mpBuffer->GetData(0);
			tfloat32* pfData2 = mpBuffer->GetData(1);
			tfloat* ppfData[2];
			ppfData[0] = pfData1;
			ppfData[1] = pfData2;
			mppInsert[iInsert]->ProcessNonInPlace(ppfBuffersOut, (const tfloat**)ppfData, iSamples);
			memcpy(pfData1, ppfBuffersOut[0], iSamples * sizeof(tfloat32));
			memcpy(pfData2, ppfBuffersOut[1], iSamples * sizeof(tfloat32));
		}
	}

	// Prepare for panning
	mpBuffer->SetChannels(miNumberOfChannelsForPanner);
	
	// Apply out amp
	for (tuint iChannel=0; iChannel<mpBuffer->GetChannels(); iChannel++) {
		CBaseDezipper2* pDezipper = mapDezipperOutAmp[iChannel];
			
		//tfloat32 fTest, fPeak;
			
		//tint32 iSamplesAlign8 = (iSamples % 8) * 8;
		tfloat32* pfData = mpBuffer->GetData(iChannel);
		//tfloat32* pfDataStop = pfData + iSamples;
		//tfloat32* pfDataStopAlign8 = pfData + iSamplesAlign8;
			
		if (pDezipper->IsDezipNeeded()) {
			// Out-amp is changing - do a de-zip
			tfloat afDezip[1024];
			pDezipper->DezipSamples(afDezip, iSamples, 44100);
			tfloat32* pfMul = afDezip;
				
			// Don't keep old peaks (if there) when amp is changing
			mbKillDecay = true;
				
			mpDSPTools->Mul(pfData, pfMul, iSamples);
			/*
			// Apply and collect 8 aligned
			while (pfData < pfDataStopAlign8) {
				// Apply amp and collect meter value
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//1
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//2
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//3
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//4
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//5
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//6
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//7
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//8
			}
				
			// Apply and collect remainder
			while (pfData < pfDataStop) {
				// Apply amp and collect meter value
				fTest = *pfData++ *= *pfMul++;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//1
			}
			*/
		}
		else {
			// Out-amp factor is the same for all samples - just multiply
			tfloat fOutAmp = pDezipper->GetCurrent();
				
			// Keep old peaks (if not yet read) because amp isn't changing
			//fPeak = mafPeakVolumes[iChannel];
				
			if ((fOutAmp < 0.99999) || (fOutAmp > 1.00001)) {

				mpDSPTools->Mul(pfData, fOutAmp, iSamples);
				/*
				// Apply and collect 8 aligned
				while (pfData < pfDataStopAlign8) {
					// Apply amp and collect meter value
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//1
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//2
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//3
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//4
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//5
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//6
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//7
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//8
				}
				
				// Apply and collect remainder
				while (pfData < pfDataStop) {
					// Apply amp and collect meter value
					fTest = *pfData++ *= fOutAmp;		fTest = fabsf(fTest);		if (fTest > fPeak) fPeak = fTest;	//1
				}
				 */
			}
			else {
				/*
				// No output amplification - just collect meter values
										
				// Collect alligned to 8
				while (pfData < pfDataStopAlign8) {
					// Collect meter value
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//1
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//2
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//3
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//4
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//5
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//6
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//7
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//8
				}

				// Collect any remainder
				while (pfData < pfDataStop) {
					// Collect meter value
					fTest = fabsf(*pfData++);		if (fTest > fPeak) fPeak = fTest;	//1
				}
				*/
			}
		}
			
		//mafPeakVolumes[iChannel] = fPeak;
	}

	tint32 iAUX;
	for (iAUX = 0; iAUX < 2; iAUX++) {
		if (mpfAUXVolume[iAUX] != 0) {
			CBuffer* pBufferAUX = mppAUXes[iAUX]->GetBuffer();

//			*pBufferAUX += *mpBuffer;
			pBufferAUX->Accumulate(*mpBuffer, mpfAUXVolume[iAUX]);
		}
	}

	// Maybe do down or up mix for destination
	mpBuffer->SetChannels(miDestinationNumberOfChannels);

	muiSongPos += iSamples;
} // Process