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; }
//-------------------------------------------------------------------------------- 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 }
//-------------------------------------------------------------------------------- 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 }
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); }