예제 #1
0
static bool allocChanBuffers(BASS_VST_PLUGIN* this_, long numInputs, long numOutputs, long numBytes)
{
	if( numInputs > MAX_CHANS
	 || numInputs <= 0
	 || numOutputs > MAX_CHANS
	 || numOutputs <= 0 )
	{
		freeChansBuffers(this_);
		return false;
	}

	if( numBytes > this_->bytesPerInOutBuffer
	 || this_->buffersIn[numInputs-1] == NULL
	 || this_->buffersOut[numOutputs-1] == NULL )
	{
		// we allcate silently the double number of bytes to be prepared for double processing ...
		#define BUFFER_HEADROOM_MULT 2
		assert( sizeof(double)==sizeof(float)*BUFFER_HEADROOM_MULT );

		// free previously allocated buffers
		freeChansBuffers(this_);
	
		// allocated the new buffers
		int i;
		for( i = 0; i < numInputs; i++ )
		{ 
			if( (this_->buffersIn[i]=(float*)malloc(numBytes*BUFFER_HEADROOM_MULT)) == NULL )
			{
				freeChansBuffers(this_);
				return false;
			}
		}

		for( i = 0; i < numOutputs; i++ )
		{
			if( (this_->buffersOut[i]=(float*)malloc(numBytes*BUFFER_HEADROOM_MULT)) == NULL )
			{
				freeChansBuffers(this_);
				return false;
			}
		}

		this_->bytesPerInOutBuffer = numBytes;

		this_->effBlockSize = numBytes/sizeof(float)/*sample count*/;
		callMainsChanged(this_, this_->effBlockSize);

		EnterCriticalSection(&s_forwardCritical);
			for( i = 0; i < this_->forwardDataToOtherCnt; i++ )
			{
				BASS_VST_PLUGIN* other_ = refHandle(this_->forwardDataToOtherVstHandles[i]);
					if( other_ && other_->effStartProcessCalled )
						callMainsChanged(other_, this_->effBlockSize);
				unrefHandle(this_->forwardDataToOtherVstHandles[i]);
			}
		LeaveCriticalSection(&s_forwardCritical);
	}

	return true;
}
예제 #2
0
	//--------------------------------------------------------------------------------
	COSWindow::refType CClipboardHelper::GetOpenClipboardWindow()
	{
		_WINQ_FCONTEXT( "CClipboardHelper::GetOpenClipboardWindow" );		
		__QOR_PROTECT
		{
			CWindowHandle WindowHandle( 0, (void*)( m_User32Library.GetOpenClipboardWindow() ) );
			CWindowHandle::refType refHandle( &WindowHandle, false );
			return COSWindow::FromHandle( refHandle );
		}__QOR_ENDPROTECT
	}
예제 #3
0
	//--------------------------------------------------------------------------------
	CClipboardViewerSession::CClipboardViewerSession( COSWindow& Wnd, int* pbResult ) : m_Wnd( Wnd ), m_User32Library( CUser32::Instance() )
	{
		_WINQ_FCONTEXT( "CClipboardViewerSession::CClipboardViewerSession" );
		__QOR_PROTECT
		{
			m_pResult = pbResult;
			CWindowHandle WindowHandle( 0, (void*)m_User32Library.SetClipboardViewer( reinterpret_cast< ::HWND >( m_Wnd.Handle()->Use() ) ) );
			CWindowHandle::refType refHandle( &WindowHandle, 0 );
			m_Next = COSWindow::FromHandle( refHandle );
		}__QOR_ENDPROTECT
	}
예제 #4
0
void CALLBACK doEffectProcess(HDSP dspHandle, DWORD channelHandle, void* buffer__, DWORD bufferBytes__, USERPTR vstHandle__)
{
	DWORD				vstHandle = (DWORD)vstHandle__;
	BASS_CHANNELINFO	channelInfo;
	int					i;
	long				requiredInputs;
	long				requiredOutputs;

	float*				floatBuffer;
	long				numSamples;
	bool				cnvPcm2Float;
	bool				cnvMonoToStereo = false;

	BASS_VST_PLUGIN* this_ = refHandle(vstHandle);
	if( this_ == NULL || channelHandle != this_->channelHandle || dspHandle != this_->dspHandle || buffer__ == NULL || bufferBytes__ <= 0 )
		goto Cleanup; // error already logged

	// get the channel information
	if( !BASS_ChannelGetInfo(channelHandle, &channelInfo)
	 ||  channelInfo.chans <= 0 )
		goto Cleanup;

	requiredInputs = this_->aeffect->numInputs;
	if( (long)channelInfo.chans > requiredInputs )
		requiredInputs = channelInfo.chans;

	requiredOutputs = this_->aeffect->numOutputs;
	if( (long)channelInfo.chans > requiredOutputs )
		requiredOutputs = channelInfo.chans;

	// get the data as floats.
	// this is not lossy.
	cnvPcm2Float = ((channelInfo.flags&BASS_SAMPLE_FLOAT)==0 && (this_->type==VSTinstrument || BASS_GetConfig(BASS_CONFIG_FLOATDSP)==0));
	if( cnvPcm2Float )
	{
		if( channelInfo.flags & BASS_SAMPLE_8BITS )
			goto Cleanup; // can't and won't do this

		if( !allocTempBuffer(this_, bufferBytes__*2) )
			goto Cleanup;
		cnvPcm16ToFloat((signed short*)buffer__, this_->bufferTemp, bufferBytes__);

		floatBuffer = this_->bufferTemp;
		numSamples = (bufferBytes__ / sizeof(signed short)) / channelInfo.chans;
	}
	else
	{
		floatBuffer = (float*)buffer__;
		numSamples = (bufferBytes__ / sizeof(float)) / channelInfo.chans;
	}

	if( numSamples <= 0 )
		goto Cleanup;

	// copy the given LRLRLR buffer to the VST LLLRRR buffers
	// this is not lossy
	if( !allocChanBuffers(this_, requiredInputs, requiredOutputs, numSamples*sizeof(float)) )
		goto Cleanup;
	
	{
		long chans = channelInfo.chans, c = 0;
		float* buffer = (float*)floatBuffer;
		float* end = &buffer[numSamples * chans];
		float** in = this_->buffersIn;
		i = 0;
		while( buffer < end )
		{
			in[c][i] = *buffer;
			buffer ++;
			c++;
			if( c == chans )
			{
				c = 0;
				i++;
			}
		}

		for( c = chans; c < requiredInputs; c++ )
			memset(in[c], 0, numSamples * sizeof(float));
	}

	// special mono-processing effect handling
	if(   this_->aeffect->numInputs == 1
	 &&   this_->aeffect->numOutputs <= 2
	 &&   channelInfo.chans > 1
	 && !(this_->createFlags&BASS_VST_KEEP_CHANS) )
	{
		cnvFloatLLRR_To_Mono(this_->buffersIn[0], this_->buffersIn[1], numSamples,
			this_->aeffect->numOutputs == 1? 1.0F : 0.5F);
		
		if( this_->aeffect->numOutputs == 1 )
			cnvMonoToStereo = true;
	}

	// empty the output buffers and process
	// (normally this is needed only for process() and not for processReplacing();
	// however, this has to be done even in processReplacing() since some VSTIs
	// (most notably those from Steinberg... hehe) obviously don't implement 
	// processReplacing() as a separate function but rather use process())
	enterVstCritical(this_);
		if( !this_->doBypass )
		{
			this_->vstTimeInfo.samplePos += numSamples;
			if( this_->vstTimeInfo.samplePos < 0.0 )
				this_->vstTimeInfo.samplePos = 0.0;

			EnterCriticalSection(&s_forwardCritical);
				for( i = 0; i < this_->forwardDataToOtherCnt; i++ )
				{
					clearOutputBuffers(this_, numSamples);
					BASS_VST_PLUGIN* other_ = refHandle(this_->forwardDataToOtherVstHandles[i]);
						if( other_ )
						{
							if( tryEnterVstCritical(other_) )
							{
								callProcess(other_, this_/*buffers to use*/, numSamples);
								leaveVstCritical(other_);
							}
						}
					unrefHandle(this_->forwardDataToOtherVstHandles[i]);
				}
			LeaveCriticalSection(&s_forwardCritical);

			// the "real" sound processing (the one above is only for the editors to get data)
			clearOutputBuffers(this_, numSamples);
			callProcess(this_, this_/*buffers to use*/, numSamples);

			// special mono-processing effect handling
			if( cnvMonoToStereo )
			{
				cnvFloatLLRR_To_Stereo(this_->buffersOut[0], this_->buffersOut[1], numSamples);
			}

			// convert the returned data back to our channel representation (LLLLLRRRRR to LRLRLRLR)
			// this is not lossy
			{
				long chans = channelInfo.chans, c = 0;
				float* buffer = (float*)floatBuffer;
				float* end = &buffer[numSamples * chans];
				float** out = this_->buffersOut;
				i = 0;
				while( buffer < end )
				{
					*buffer = out[c][i];
					buffer++;
					c++;
					if( c == chans )
					{
						c = 0;
						i++;
					}
				}		
			}

			// convert the data back to PCM, if needed
			// this is lossy
			if( cnvPcm2Float )
			{
				cnvFloatToPcm16(floatBuffer, (signed short*)buffer__, numSamples * sizeof(float) * channelInfo.chans);
			}
		}
	leaveVstCritical(this_);
	
	// done
Cleanup:
	unrefHandle(vstHandle);
}