Пример #1
0
// Remove DC offset
float RemoveDCOffset(modplug::tracker::modsample_t& smp,
                                     SmpLength iStart,
                                     SmpLength iEnd,
                                     const MODTYPE modtype,
                                     module_renderer* const pSndFile)
//----------------------------------------------
{
    if(smp.sample_data == nullptr || smp.length < 1)
            return 0;

    modplug::tracker::modsample_t* const pSmp = &smp;

    if (iEnd > pSmp->length) iEnd = pSmp->length;
    if (iStart > iEnd) iStart = iEnd;
    if (iStart == iEnd)
    {
            iStart = 0;
            iEnd = pSmp->length;
    }

    iStart *= pSmp->GetNumChannels();
    iEnd *= pSmp->GetNumChannels();

    const double dMaxAmplitude = (pSmp->GetElementarySampleSize() == 2) ? GetMaxAmplitude<int16_t>() : GetMaxAmplitude<int8_t>();

    // step 1: Calculate offset.
    OffsetData oData = {0,0,0};
    if(pSmp->GetElementarySampleSize() == 2)
            oData = CalculateOffset(reinterpret_cast<int16_t*>(pSmp->sample_data) + iStart, iEnd - iStart);
    else if(pSmp->GetElementarySampleSize() == 1)
            oData = CalculateOffset(reinterpret_cast<int8_t*>(pSmp->sample_data) + iStart, iEnd - iStart);

    double dMin = oData.dMin, dMax = oData.dMax, dOffset = oData.dOffset;

    const float fReportOffset = (float)dOffset;

    if((int)(dOffset * dMaxAmplitude) == 0)
            return 0;

    // those will be changed...
    dMax += dOffset;
    dMin += dOffset;

    // ... and that might cause distortion, so we will normalize this.
    const double dAmplify = 1 / bad_max(dMax, -dMin);

    // step 2: centralize + normalize sample
    dOffset *= dMaxAmplitude * dAmplify;
    if(pSmp->GetElementarySampleSize() == 2)
            RemoveOffsetAndNormalize( reinterpret_cast<int16_t*>(pSmp->sample_data) + iStart, iEnd - iStart, dOffset, dAmplify);
    else if(pSmp->GetElementarySampleSize() == 1)
            RemoveOffsetAndNormalize( reinterpret_cast<int8_t*>(pSmp->sample_data) + iStart, iEnd - iStart, dOffset, dAmplify);

    // step 3: adjust global vol (if available)
    if((modtype & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (iStart == 0) && (iEnd == pSmp->length * pSmp->GetNumChannels()))
    {
            BEGIN_CRITICAL();
            pSmp->global_volume = bad_min((uint16_t)(pSmp->global_volume / dAmplify), 64);
            for (modplug::tracker::chnindex_t i = 0; i < MAX_VIRTUAL_CHANNELS; i++)
            {
                    if(pSndFile->Chn[i].sample_data == pSmp->sample_data)
                    {
                            pSndFile->Chn[i].nGlobalVol = pSmp->global_volume;
                    }
            }
            END_CRITICAL();
    }

    AdjustEndOfSample(smp, pSndFile);

    return fReportOffset;
}
Пример #2
0
// Remove DC offset
float RemoveDCOffset(ModSample &smp,
					 SmpLength iStart,
					 SmpLength iEnd,
					 const MODTYPE modtype,
					 CSoundFile &sndFile)
//---------------------------------------
{
	if(smp.pSample == nullptr || smp.nLength < 1)
		return 0;

	if (iEnd > smp.nLength) iEnd = smp.nLength;
	if (iStart > iEnd) iStart = iEnd;
	if (iStart == iEnd)
	{
		iStart = 0;
		iEnd = smp.nLength;
	}

	iStart *= smp.GetNumChannels();
	iEnd *= smp.GetNumChannels();

	const double dMaxAmplitude = (smp.GetElementarySampleSize() == 2) ? GetMaxAmplitude<int16>() : GetMaxAmplitude<int8>();

	// step 1: Calculate offset.
	OffsetData oData = {0,0,0};
	if(smp.GetElementarySampleSize() == 2)
		oData = CalculateOffset(static_cast<int16 *>(smp.pSample) + iStart, iEnd - iStart);
	else if(smp.GetElementarySampleSize() == 1)
		oData = CalculateOffset(static_cast<int8*>(smp.pSample) + iStart, iEnd - iStart);

	double dMin = oData.dMin, dMax = oData.dMax, dOffset = oData.dOffset;

	const float fReportOffset = (float)dOffset;

	if((int)(dOffset * dMaxAmplitude) == 0)
		return 0;

	// those will be changed...
	dMax += dOffset;
	dMin += dOffset;

	// ... and that might cause distortion, so we will normalize this.
	const double dAmplify = 1 / MAX(dMax, -dMin);

	// step 2: centralize + normalize sample
	dOffset *= dMaxAmplitude * dAmplify;
	if(smp.GetElementarySampleSize() == 2)
		RemoveOffsetAndNormalize( static_cast<int16 *>(smp.pSample) + iStart, iEnd - iStart, dOffset, dAmplify);
	else if(smp.GetElementarySampleSize() == 1)
		RemoveOffsetAndNormalize( static_cast<int8 *>(smp.pSample) + iStart, iEnd - iStart, dOffset, dAmplify);

	// step 3: adjust global vol (if available)
	if((modtype & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (iStart == 0) && (iEnd == smp.nLength * smp.GetNumChannels()))
	{
		CriticalSection cs;

		smp.nGlobalVol = std::min((uint16)(smp.nGlobalVol / dAmplify), uint16(64));
		for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++)
		{
			if(sndFile.m_PlayState.Chn[i].pModSample == &smp)
			{
				sndFile.m_PlayState.Chn[i].nInsVol = smp.nGlobalVol;
				if(sndFile.m_PlayState.Chn[i].pModInstrument)
				{
					sndFile.m_PlayState.Chn[i].nInsVol = (smp.nGlobalVol * sndFile.m_PlayState.Chn[i].pModInstrument->nGlobalVol) >> 6;
				}
			}