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

📄 avccompressor.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  AvcCompressor.cpp  Vincent A. Busam**********************************************************************//*  TODO List:  1.  Add graph shows curve specified by grid, keep it up to date,        allow setting of grid points by moving points in grid.  2.  Better help  3.  Radio button selection so Adjustment Settings can be times instead		of samples.  4.  Radio button selection so Amplification Settings can be db instead        of raw values.  5.  Save settings by name  6.  Remove "help" text in window when Audacity help available.*/#include <math.h>#include <wx/defs.h>#include <wx/msgdlg.h>#include <wx/textdlg.h>#include <wx/dcmemory.h>#include "../WaveTrack.h"#include "../Envelope.h"#include "../widgets/Ruler.h"#include "../Prefs.h"// Including the following cpp file is quite unorthodox, but it gives the opportunity to//		use iAVC's capability of generating inline code for the important methods.  We//		can't trust compilers to generated inline code, even when the inline keyword is//		used.#ifdef _WINDOWS				// kludge for Audacity since we don't really have MS Windows	#define max(a,b)  ( (a<b)?b:a )#endif//!!!!!!!!!!!!!!!!!!!!!!!!!  I M P O R T A N T  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// IMPORTANT:  This define determines if iAVC generates in line code.//#define  IAVC_INLINE		// use inline code for get and put of samples#include "AvcCompressor.h"#include "../../lib-src/iAVC/iAVCsamples.h"#include "../../lib-src/iAVC/iAVC.cpp"#define ADJWIN_DEFAULT  DEFAULT_ADJUSTER_WINDOW_SIZE#define ADJWIN_MIN		1000#define ADJWIN_MAX		10000#define DELAY_DEFAULT	DEFAULT_MINIMUM_SAMPLES_BEFORE_SWITCH#define DELAY_MIN		0#define DELAY_MAX		5000#define CHANGE_DEFAULT  DEFAULT_MINIMUM_SAMPLES_BEFORE_SWITCH#define CHANGE_MIN		1000#define CHANGE_MAX		5000#define MINPCT_DEFAULT	DEFAULT_MAX_PCT_CHANGE_AT_ONCE#define MINPCT_MIN		5#define MINPCT_MAX		50EffectAvcCompressor::EffectAvcCompressor():			mpBufferList ( NULL ),			mpBufferPrevious ( NULL ),			mnDelay ( 0 ),			mpDialog ( NULL ){}EffectAvcCompressor::~EffectAvcCompressor(){	if ( mpDialog != NULL )		delete mpDialog;}wxString EffectAvcCompressor::GetEffectDescription() {    return "Applied effect: AVC"; // XXX: temporary   // Note: This is useful only after values have been set.    // FIX-ME: Compile error (cannot pass wxString to Format).   //return wxString::Format(_("Applied effect: %s"),   //                        this->GetEffectDescription());                           //old                              //return wxString::Format("Applied effect: %s change window = %d samples",    //(const char *)(this->GetEffectName()), mnChangeWindow); } inlinevoid EffectAvcCompressor::OutputSample ( IAVCSAMPLETYPE left, IAVCSAMPLETYPE right ){	if ( mpBufferList->mnNext >= mpBufferList->mnLen )	{	// have filled up this buffer, move to next		iAVCBufferList * pOld = mpBufferList;		mpBufferList = mpBufferList->mpNext;		delete pOld;	}	if ( mpBufferList == NULL )		return;	// set the output sample values	((IAVCSAMPLETYPE*)mpBufferList->mpLeftBuffer)[mpBufferList->mnNext] = left;	if ( mpBufferList->mpRightBuffer )		((IAVCSAMPLETYPE*)mpBufferList->mpRightBuffer)[mpBufferList->mnNext] = right;	++mpBufferList->mnNext;}bool EffectAvcCompressor::PromptUser(){   if ( mpDialog == NULL )	// reuse dialog so we keep user changes to values	   mpDialog = new AvcCompressorDialog(mParent, -1, _("Automatic Volume Control"));   mpDialog->CentreOnParent();   mpDialog->ShowModal();   if (!mpDialog->GetReturnCode())      return false;   mAutoVolCtrl.Reset();	// reset control before setting values   // Set parameters for iAVC class   unsigned short int *nTransform = new unsigned short int [ MULTIPLY_PCT_ARRAY_SIZE ];   mnChangeWindow=mpDialog->GetChangeWindow();   mpDialog->GetTransformArray(nTransform);   if ( mAutoVolCtrl.SetSampleWindowSize(mpDialog->GetAdjusterWindow()+mnChangeWindow,											mpDialog->GetAdjusterWindow(),											0) == false ||											mAutoVolCtrl.SetMinSamplesBeforeSwitch(mnChangeWindow) == false ) {            wxMessageBox("Error setting parameters for automatic volume control.");            return false;   }   mAutoVolCtrl.SetMaxPctChangeAtOnce(mpDialog->GetMinimumPercent());   mAutoVolCtrl.SetMultipliers(nTransform);   mAutoVolCtrl.SetNumberTracks(mnTracks);   mnDelay = mpDialog->GetDelay();   delete [] nTransform;   return true;}bool EffectAvcCompressor::TransferParameters( Shuttle & shuttle ){    wxASSERT( false );// Not yet implemented.//   shuttle.TransferInt("",,0);   return true;}bool EffectAvcCompressor::Init()	// invoked before PromptUser{	if ( EffectSimplePairedTwoTrack<IAVCSAMPLETYPE,AVCCOMPSAMPLETYPE>::Init() == false )		return false;	return true;}bool EffectAvcCompressor::ProcessSimplePairedTwoTrack(/*IAVCSAMPLETYPE*/ void *bufferLeft,													  /*IAVCSAMPLETYPE*/ void *bufferRight, // may be 0													  sampleCount len){	// build new iAVCBufferList node	iAVCBufferList *  pBufferNode = new iAVCBufferList;	if ( mpBufferPrevious != NULL )		mpBufferPrevious->mpNext = pBufferNode;	// link to end of list	else		mpBufferList = pBufferNode;				// have first node in list	mpBufferPrevious = pBufferNode;				// this node now the last added to list	pBufferNode->mpNext = NULL;	pBufferNode->mpLeftBuffer = bufferLeft;	pBufferNode->mpRightBuffer = bufferRight;	pBufferNode->mnLen = len;	pBufferNode->mnNext = 0;	// process samples in these buffer(s)	IAVCSAMPLETYPE* typedBufferLeft  = (IAVCSAMPLETYPE*)bufferLeft;	IAVCSAMPLETYPE* typedBufferRight = (IAVCSAMPLETYPE*)bufferRight;	sampleCount i;	IAVCSAMPLETYPE left;	IAVCSAMPLETYPE right = 0;	for ( i = 0 ; i < len ; ++i ) {		left = typedBufferLeft[i];		if ( typedBufferRight )			right = typedBufferRight[i];		#ifdef IAVC_INLINE			// use inline SetNextSample()			#define	IAVC_SETNEXTSAMPLE			#include "../../lib-src/iAVC/iAVC.cpp"			#undef  IAVC_SETNEXTSAMPLE			// use inline GetNextSample()			if ( mnDelay <= 0 )			{	// get a value only if past desired delay				#define IAVC_GETNEXTSAMPLE				#include "../../lib-src/iAVC/iAVC.cpp"				#undef  IAVC_SETNEXTSAMPLE			}		#else			// call SetNextSample() and GetNextSample()			mAutoVolCtrl.SetNextSample(left, right);			if ( mnDelay <= 0 )			{	// get a value only if past desired delay				mAutoVolCtrl.GetNextSample(left, right);			}		#endif			if ( mnDelay <= 0 )			{	// get a value only if past desired delay				OutputSample ( left, right );				typedBufferLeft[i] = left;				if ( typedBufferRight )					typedBufferRight[i] = right;			}			else			{	// count down the delay amount				--mnDelay;			}	}	return true;}void EffectAvcCompressor::End(){	IAVCSAMPLETYPE left;	IAVCSAMPLETYPE right = 0;	// We now need to output any samples still waiting because	while ( mpBufferList != NULL )	{		#ifdef IAVC_INLINE			// use inline GetNextSample()			#define IAVC_GETNEXTSAMPLE			#include "../../lib-src/iAVC/iAVC.cpp"			#undef  IAVC_SETNEXTSAMPLE		#else			// call GetNextSample()			mAutoVolCtrl.GetNextSample(left, right);		#endif		OutputSample ( left, right );	}	mpBufferPrevious = NULL;	EffectSimplePairedTwoTrack<IAVCSAMPLETYPE,AVCCOMPSAMPLETYPE>::End();}// WDR: class implementations//----------------------------------------------------------------------------// AvcCompressorDialog//----------------------------------------------------------------------------#define PREF_ADJWIN "/Effect/AVC/user1/adjwin"#define PREF_DELAY  "/Effect/AVC/user1/delay"#define PREF_CHANGE "/Effect/AVC/user1/change"#define PREF_MINPCT "/Effect/AVC/user1/minpct"#define PREF_ENABLE "/Effect/AVC/user1/%d/enable"#define PREF_HORIZ  "/Effect/AVC/user1/%d/horiz"#define PREV_VERT   "/Effect/AVC/user1/%d/vert"// WDR: event table for AvcCompressorDialogBEGIN_EVENT_TABLE(AvcCompressorDialog,wxDialog)   EVT_BUTTON( wxID_OK, AvcCompressorDialog::OnOK )   EVT_BUTTON( wxID_CANCEL, AvcCompressorDialog::OnCancel )   EVT_BUTTON( ID_RESTORE_DEFAULTS, AvcCompressorDialog::OnRestoreDefaults )   EVT_CHECKBOX(ID_FIRST_CURVE_CHECK+1, AvcCompressorDialog::OnCheckBox)   EVT_CHECKBOX(ID_FIRST_CURVE_CHECK+2, AvcCompressorDialog::OnCheckBox)   EVT_CHECKBOX(ID_FIRST_CURVE_CHECK+3, AvcCompressorDialog::OnCheckBox)   EVT_CHECKBOX(ID_FIRST_CURVE_CHECK+4, AvcCompressorDialog::OnCheckBox)   EVT_CHECKBOX(ID_FIRST_CURVE_CHECK+5, AvcCompressorDialog::OnCheckBox)END_EVENT_TABLE()AvcCompressorDialog::AvcCompressorDialog(wxWindow *parent, wxWindowID id,                           const wxString &title,                           const wxPoint &position, const wxSize& size,                           long style ) :		wxDialog( parent, id, title, position, size, style ),		mctlAdjWin ( 0 ),		mctlDelay ( 0 ),		mctlChangeWin ( 0 ),		mctlMinPct ( 0 ){	for ( int i = 0 ; i < NUM_CURVE_POINTS ; ++i ) {		mctlCheckBoxes[i] = 0;		mctlXAxis[i] = 0;		mctlYAxis[i] = 0;	}	MakeAvcCompressorDialog( this, TRUE );	// First make sure all value initialized, especially horiz and vert first & last values	wxCommandEvent event;	OnRestoreDefaults(event);	// Now read in from registry	ReadPrefs();}AvcCompressorDialog::~AvcCompressorDialog(){	// zero out pointers in case reference counts being used	mctlAdjWin = 0;	mctlDelay = 0;	mctlChangeWin = 0;	mctlMinPct = 0;	for ( int i = 0 ; i < NUM_CURVE_POINTS ; ++i ) {		mctlCheckBoxes[i] = 0;		mctlXAxis[i] = 0;		mctlYAxis[i] = 0;	}}// figure out Y value for each possible X valuevoid AvcCompressorDialog::GetTransformArray( unsigned short int nTransform[MULTIPLY_PCT_ARRAY_SIZE] ){	long iCurPoint = 0;		// index to mnXAxis and mnYAxis	long iPrevPoint= 0;		// index to mnXAxis and mnYAxis	long iMultiply = 1;		// iMultiply and iDivide used to calculate fractional slopes	long iDivide   = 1;	long iBias     = 0;	    // keeps values from decreasing	nTransform [ 0 ] = 0;	for ( long i = 0 ; i < MULTIPLY_PCT_ARRAY_SIZE - 1 ; ++i ) {		if ( i == mnXAxis [ iCurPoint ] && iCurPoint < NUM_CURVE_POINTS - 1 ) {			// time to move to next point			iPrevPoint = iCurPoint;			// find next checked point			while ( mctlCheckBoxes[++iCurPoint]->GetValue() == false)				;	// last box guaranteed to be checked			// Recalculate bias based on what would be calculated with old values and			//		what would be calculated with new values.			long iOld = i * iMultiply / iDivide + iBias;			iMultiply = mnYAxis [ iCurPoint ] - mnYAxis [ iPrevPoint ];			iDivide   = mnXAxis [ iCurPoint ] - mnXAxis [ iPrevPoint ];			iBias = iOld - ( i * iMultiply / iDivide );		}		nTransform [ i ] = (unsigned short int)         ( i * iMultiply / iDivide + iBias );	}	// set boundary case for loudest sound	nTransform [ MULTIPLY_PCT_ARRAY_SIZE - 1 ] = MULTIPLY_PCT_ARRAY_SIZE - 1;}bool AvcCompressorDialog::LongRangeCheck ( wxWindow *window,										   const long nValue,										   const long nMin,										   const long nMax ){	if ( nValue < nMin || nValue > nMax ) {		// value out of range        if ( !wxValidator::IsSilent() )            wxBell();		wxString strTemp;		strTemp.Printf ( _("Value must be from %d to %d."), nMin, nMax );		wxMessageBox(strTemp, _("Validation error"),					 wxOK | wxICON_EXCLAMATION, GetParent() ); 		if ( window )			window->SetFocus();		return false;	}	return true;}// WDR: handler implementations for AvcCompressorDialog

⌨️ 快捷键说明

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