⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snd_wave_mixer.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// If we are terminating this wave prematurely, then make sure we detect the limit
	if ( m_forcedEndSample )
	{
		// How many total input samples will we need?
		int samplesRequired = (int)(sampleCount * rate);
		// will this hit the end?
		if ( m_sample + samplesRequired >= m_forcedEndSample )
		{
			// yes, mark finished and truncate the sample request
			m_finished = true;
			sampleCount = (int)( (m_forcedEndSample - m_sample) / rate );
		}
	}

	while ( sampleCount > 0 )
	{
		bool advanceSample = true;
		int availableSamples, outputSampleCount;
		char *pData = NULL;

		// compute number of input samples required
		double end = m_sample + rate * sampleCount;
		int inputSampleCount = (int)(ceil(end) - floor(m_sample));

		// ask the source for the data
		char copyBuf[AUDIOSOURCE_COPYBUF_SIZE];

		if ( m_delaySamples > 0 )
		{
			int num_zero_samples = min( m_delaySamples, inputSampleCount );

			// Decrement data amount
			m_delaySamples -= num_zero_samples;

			int sampleSize = m_pData->Source().SampleSize();
			int readBytes = sampleSize * num_zero_samples;

			Assert( readBytes <= sizeof( copyBuf ) );

			pData = &copyBuf[0];
			// Now copy in some zeroes
			memset( pData, 0, readBytes );

			availableSamples = num_zero_samples;

			advanceSample = false;
		}
		else
		{
			availableSamples = GetOutputData((void**)&pData, inputSampleCount, copyBuf);
		}

		// none available, bail out
		if ( !availableSamples )
		{
			break;
		}

		double sampleFraction = m_sample - floor(m_sample);
		if ( availableSamples < inputSampleCount )
		{
			// How many samples are there given the number of input samples and the rate.
			outputSampleCount = (int)ceil((availableSamples - sampleFraction) / rate);
		}
		else
		{
			outputSampleCount = sampleCount;
		}

		// Verify that we won't get a buffer overrun.
		assert(floor(sampleFraction + rate * (outputSampleCount-1)) <= availableSamples);

		if ( advanceSample )
		{
			m_sample += outputSampleCount * rate;
		}
		outputOffset += outputSampleCount;
		sampleCount -= outputSampleCount;
	}

	// Did we run out of samples? if so, mark finished
	if ( sampleCount > 0 )
	{
		m_finished = true;
	}

	// total number of samples mixed !!! at the output clock rate !!!
	return outputOffset - startingOffset;
}

//-----------------------------------------------------------------------------
// Purpose: The device calls this to request data.  The mixer must provide the
//			full amount of samples or have silence in its output stream.
//			Mix channel to all active paintbuffers.
//			NOTE: cannot be called consecutively to mix into multiple paintbuffers!
// Input  : *pDevice - requesting device
//			sampleCount - number of samples at the output rate
//			outputRate - sampling rate of the request
// Output : Returns true to keep mixing, false to delete this mixer
//-----------------------------------------------------------------------------
int CAudioMixerWave::MixDataToDevice( IAudioDevice *pDevice, channel_t *pChannel, int sampleCount, int outputRate, int outputOffset )
{
	// shouldn't be playing this if finished, but return if we are
	if ( m_finished )
		return 0;

	// save this to compute total output
	int startingOffset = outputOffset;

	float inputRate = (pChannel->pitch * m_pData->Source().SampleRate());
	float rate = inputRate / outputRate;


	// If we are terminating this wave prematurely, then make sure we detect the limit
	if ( m_forcedEndSample )
	{
		// How many total input samples will we need?
		int samplesRequired = (int)(sampleCount * rate);
		// will this hit the end?
		if ( m_sample + samplesRequired >= m_forcedEndSample )
		{
			// yes, mark finished and truncate the sample request
			m_finished = true;
			sampleCount = (int)( (m_forcedEndSample - m_sample) / rate );
		}
	}

	while ( sampleCount > 0 )
	{
		bool advanceSample = true;
		int availableSamples, outputSampleCount;
		char *pData = NULL;

		// compute number of input samples required
		double end = m_sample + rate * sampleCount;
		int inputSampleCount = (int)(ceil(end) - floor(m_sample));

		// ask the source for the data
		char copyBuf[AUDIOSOURCE_COPYBUF_SIZE];

		if ( m_delaySamples > 0 )
		{
			int num_zero_samples = min( m_delaySamples, inputSampleCount );

			// Decrement data amount
			m_delaySamples -= num_zero_samples;

			int sampleSize = m_pData->Source().SampleSize();
			int readBytes = sampleSize * num_zero_samples;

			Assert( readBytes <= sizeof( copyBuf ) );

			pData = &copyBuf[0];
			// Now copy in some zeroes
			memset( pData, 0, readBytes );

			availableSamples = num_zero_samples;

			advanceSample = false;
		}
		else
		{
			availableSamples = GetOutputData((void**)&pData, inputSampleCount, copyBuf);
		}

		// none available, bail out
		if ( !availableSamples )
		{
			break;
		}

		double sampleFraction = m_sample - floor(m_sample);
		if ( availableSamples < inputSampleCount )
		{
			// How many samples are there given the number of input samples and the rate.
			outputSampleCount = (int)ceil((availableSamples - sampleFraction) / rate);
		}
		else
		{
			outputSampleCount = sampleCount;
		}

		// Verify that we won't get a buffer overrun.
		assert(floor(sampleFraction + rate * (outputSampleCount-1)) <= availableSamples);

		// mix this data to all active paintbuffers
		int i, j;
		
		// save current paintbuffer
		j = MIX_GetCurrentPaintbufferIndex();
		
		for (i = 0 ; i < CPAINTBUFFERS; i++)
		{
			if (paintbuffers[i].factive)
			{
				// mix chan into all active paintbuffers
				MIX_SetCurrentPaintbuffer(i);

				Mix( 
					pDevice,						// Device.
					pChannel,						// Channel.
					pData,							// Input buffer.
					outputOffset,					// Output position.
					FIX_FLOAT(sampleFraction),		// Iterators.
					FIX_FLOAT(rate), 
					outputSampleCount,	
					0 
					);
			}
		}
		MIX_SetCurrentPaintbuffer(j);

		if ( advanceSample )
		{
			m_sample += outputSampleCount * rate;
		}
		outputOffset += outputSampleCount;
		sampleCount -= outputSampleCount;
	}

	// Did we run out of samples? if so, mark finished
	if ( sampleCount > 0 )
	{
		m_finished = true;
	}

	// total number of samples mixed !!! at the output clock rate !!!
	return outputOffset - startingOffset;
}


bool CAudioMixerWave::ShouldContinueMixing( void )
{
	return !m_finished;
}

float CAudioMixerWave::ModifyPitch( float pitch )
{
	return pitch;
}

float CAudioMixerWave::GetVolumeScale( void )
{
	return 1.0f;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -