mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-30 07:39:42 +02:00
remove other traces of iAVC now that AVCeffect is gone
This commit is contained in:
parent
59bf545179
commit
b48e6883c6
@ -155,10 +155,6 @@ GPL-compatible license. Specifically:
|
||||
Provides decoding/encoding of additional formats. Optional separate
|
||||
download.
|
||||
|
||||
iAVC: LGPL
|
||||
Part of the code to the AVC Compressor effect.
|
||||
Included with Audacity.
|
||||
|
||||
libid3tag: GPL
|
||||
Reads/writes ID3 tags in MP3 files. Optional
|
||||
separate download as part of libmad.
|
||||
@ -1960,4 +1956,4 @@ New libraries in Audacity 1.1:
|
||||
* libmad for fast MP3 importing
|
||||
* libid3tag for editing MP3 file information
|
||||
* libsndfile to read and write more audio file formats
|
||||
* PortAudio for cross-platform audio playing and recording
|
||||
* PortAudio for cross-platform audio playing and recording
|
||||
|
@ -20,10 +20,6 @@ The customised file saving dialogs for wxwidgets to provide the options
|
||||
button for format preferences. This is written and maintained by us so doesn't
|
||||
have an upstream at the moment.
|
||||
|
||||
iAVC
|
||||
----
|
||||
disused?
|
||||
|
||||
id3lib
|
||||
------
|
||||
disused?
|
||||
|
@ -1,30 +0,0 @@
|
||||
No library needs to be built for iAVC.
|
||||
|
||||
The file src/effects/AvcCompressor.cpp includes the iAVC files.
|
||||
While it is somewhat unorthodox to include a .cpp file, it
|
||||
does save building a library.
|
||||
|
||||
Keeping the iAVC files in a directory of its own is appropriate
|
||||
and makes it easy to remember that iAVC is under LGPL license
|
||||
and not simply part of Audacity.
|
||||
|
||||
Vince Busam
|
||||
|
||||
-------------
|
||||
|
||||
New files list:
|
||||
|
||||
lib-src/iAVC/iAVC-Audacity.txt (this file)
|
||||
lib-src/iAVC/iAVC.h
|
||||
lib-src/iAVC/iAVC.cpp
|
||||
lib-src/iAVC/iAVCsamples.h
|
||||
|
||||
src/effects/AvcCompressor.cpp
|
||||
src/effects/AvcCompressor.h
|
||||
src/effects/SimplePairedTwoTrack.cpp
|
||||
src/effects/SimplePairedTwoTrack.h
|
||||
|
||||
Updated files list:
|
||||
|
||||
src/effects/LoadEffects.cpp (one line to load AvcCompressor)
|
||||
win/audacity.dsp (add above new files to project)
|
@ -1,643 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// iAVC -- integer Automatic Volume Control (on samples given it)
|
||||
//
|
||||
// Copyright (C) 2002 Vincent A. Busam
|
||||
// 15754 Adams Ridge
|
||||
// Los Gatos, CA 95033
|
||||
// email: vince@busam.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// If you change the algorithm or find other sets of values that improve the
|
||||
// output results, please send me a copy so that I can incorporate them into
|
||||
// iAVC. Of course, you are not required to send me any updates under the
|
||||
// LGPL license, but please consider doing so under the spirit of open source
|
||||
// and in appreciation of being able to take advantage of my efforts expended
|
||||
// in developing iAVC.
|
||||
|
||||
// This code implements a "poor man's" dynamic range compression algorithm
|
||||
// that was build on hueristics. It's purpose is to perform dynamic range
|
||||
// compression in real time using only integer arithmetic. Processing time
|
||||
// is more important than memory. It acts like an automatic volume control,
|
||||
// frequently adjusting the volume (gain) based on an average of the current
|
||||
// sound samples
|
||||
|
||||
#if !defined(IAVC_INLINE) || ( !defined(IAVC_SETNEXTSAMPLE) && !defined(IAVC_GETNEXTSAMPLE) && !defined(IAVC_ADJUSTMULTIPLIER) )
|
||||
|
||||
#ifdef _WINDOWS
|
||||
//#include "stdafx.h" // don't use precompiled headers on this file
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
// You really should consider using C++.
|
||||
// Granted it is not needed or even useful in all situations, but real
|
||||
// object oriented design and code (not faux OO code like in MFC)
|
||||
// has lots of benefits.
|
||||
#endif
|
||||
|
||||
#include "iAVC.h"
|
||||
|
||||
#if (defined ( _WINDOWS ) | defined ( _DEBUG ))
|
||||
#define c_WithDebug 1 // should be = 1
|
||||
#else
|
||||
#define c_WithDebug 0
|
||||
#endif
|
||||
|
||||
#ifdef IDEBUGLOG
|
||||
#include "LogFlags.h"
|
||||
#include "../Logger/IDebugLog.h"
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#ifdef _WINDOWS
|
||||
#define _MFC_OVERRIDES_NEW
|
||||
#include <crtdbg.h> // user _RPTF0 to get file name and line in output
|
||||
#define log0(fn,lf,ulid,fmt) _RPT0(_CRT_WARN,fmt);
|
||||
#define log1(fn,lf,ulid,fmt,p1) _RPT1(_CRT_WARN,fmt,p1);
|
||||
#define log2(fn,lf,ulid,fmt,p1,p2) _RPT2(_CRT_WARN,fmt,p1,p2);
|
||||
#define log3(fn,lf,ulid,fmt,p1,p2,p3) _RPT3(_CRT_WARN,fmt,p1,p2,p3);
|
||||
#define log4(fn,lf,ulid,fmt,p1,p2,p3,p4) _RPT4(_CRT_WARN,fmt,p1,p2,p3,p4);
|
||||
#define log5(fn,lf,ulid,fmt,p1,p2,p3,p4,p5) _RPT5(_CRT_WARN,fmt,p1,p2,p3,p4,p5);
|
||||
#elif
|
||||
#define log0(fn,lf,ulid,fmt) fprintf(stderr,fmt);
|
||||
#define log1(fn,lf,ulid,fmt,p1) fprintf(stderr,fmt,p1);
|
||||
#define log2(fn,lf,ulid,fmt,p1,p2) fprintf(stderr,fmt,p1,p2);
|
||||
#define log3(fn,lf,ulid,fmt,p1,p2,p3) fprintf(stderr,fmt,p1,p2,p3);
|
||||
#define log4(fn,lf,ulid,fmt,p1,p2,p3,p4) fprintf(stderr,fmt,p1,p2,p3,p4);
|
||||
#define log5(fn,lf,ulid,fmt,p1,p2,p3,p4,p5) fprintf(stderr,fmt,p1,p2,p3,p4,p5);
|
||||
#endif // _WINDOWS
|
||||
#else
|
||||
#define log0(fn,lf,ulid,fmt) ;
|
||||
#define log1(fn,lf,ulid,fmt,p1) ;
|
||||
#define log2(fn,lf,ulid,fmt,p1,p2) ;
|
||||
#define log3(fn,lf,ulid,fmt,p1,p2,p3) ;
|
||||
#define log4(fn,lf,ulid,fmt,p1,p2,p3,p4) ;
|
||||
#define log5(fn,lf,ulid,fmt,p1,p2,p3,p4,p5) ;
|
||||
#endif // _DEBUG
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// iAVC constructor
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AutoVolCtrl::AutoVolCtrl()
|
||||
{
|
||||
m_pSampleList = NULL;
|
||||
m_nSampleWindowSize = DEFAULT_SAMPLE_WINDOW_SIZE;
|
||||
m_nSamplesInAvg = DEFAULT_ADJUSTER_WINDOW_SIZE;
|
||||
m_nLookAheadWindowSize = DEFAULT_LOOKAHEAD_WINDOW_SIZE;
|
||||
m_nMinSamplesBeforeSwitch = DEFAULT_MINIMUM_SAMPLES_BEFORE_SWITCH;
|
||||
m_nNumTracks = DEFAULT_NUMBER_OF_TRACKS;
|
||||
m_nMaxChangePct = DEFAULT_MAX_PCT_CHANGE_AT_ONCE;
|
||||
m_nMaxSampleValue = DEFAULT_MAX_SAMPLE_VALUE;
|
||||
|
||||
SetSampleWindowSize ( m_nSampleWindowSize,
|
||||
m_nSamplesInAvg,
|
||||
m_nLookAheadWindowSize );
|
||||
Reset();
|
||||
|
||||
// set multipliers to a nil transform
|
||||
for ( int i = 0 ; i < MULTIPLY_PCT_ARRAY_SIZE ; ++i )
|
||||
m_nMultiplyPct [ i ] = IAVCMULTIPLYPCT ( APPLY_MULTIPLY_FACTOR ( 1 ) ); // default to no transform
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// iAVC destructor
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AutoVolCtrl::~AutoVolCtrl()
|
||||
{
|
||||
// Dump diagnostic information
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Sample Window Size %d\n", m_nSampleWindowSize );
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Adjuster Window Size %d\n", m_nSamplesInAvg );
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Min Samples to Switch %d\n", m_nMinSamplesBeforeSwitch );
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Pct Change threshold %d\n", m_nMaxChangePct );
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Number of Samples = %d\n", m_nTotalSamples );
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Multiplier changes = %d\n", m_nNumMultiplerChanges );
|
||||
log1(CN_iAVC,LL_DEBUG,0, "Number of clips = %d\n", m_nClips );
|
||||
|
||||
if ( m_pSampleList != NULL )
|
||||
delete []m_pSampleList;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reset
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AutoVolCtrl::Reset()
|
||||
{
|
||||
ZeroSampleWindow();
|
||||
SetMinSamplesBeforeSwitch ( m_nMinSamplesBeforeSwitch );
|
||||
SetMaxPctChangeAtOnce ( m_nMaxChangePct ); // e.g. 10%
|
||||
SetNumberTracks ( m_nNumTracks );
|
||||
m_nMaxSampleValue = DEFAULT_MAX_SAMPLE_VALUE; //TODO: make a method so caller can set
|
||||
|
||||
// set our internal data
|
||||
m_nSampleAvgSum = 0;
|
||||
m_nSamplesInSum = 0;
|
||||
m_nCurrentMultiplier = APPLY_MULTIPLY_FACTOR ( 1 );
|
||||
m_nTotalSamples = 0;
|
||||
m_nNumMultiplerChanges = 0;
|
||||
m_nClips = 0;
|
||||
m_nLookaheadSum = 0;
|
||||
m_nSamplesInLookahead = 0;
|
||||
m_nNumSamplesBeforeNextSwitch = 0; // allows switch on first GetSample
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SetSampleWindowSize
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool AutoVolCtrl::SetSampleWindowSize ( unsigned long nSampleWindowSize,
|
||||
unsigned long nAdjusterWindowSize,
|
||||
unsigned long nLookAheadWindowSize )
|
||||
{
|
||||
if ( nSampleWindowSize > MAX_SAMPLE_WINDOW_SIZE )
|
||||
return false; // sums may overflow and we use int for indicies
|
||||
|
||||
if ( nSampleWindowSize < nAdjusterWindowSize + nLookAheadWindowSize )
|
||||
return false;
|
||||
|
||||
m_nSamplesInAvg = nAdjusterWindowSize;
|
||||
m_nLookAheadWindowSize = nLookAheadWindowSize;
|
||||
|
||||
if ( m_nSampleWindowSize != nSampleWindowSize || m_pSampleList == NULL )
|
||||
{ // window size has changed
|
||||
m_nSampleWindowSize = nSampleWindowSize;
|
||||
if ( m_pSampleList )
|
||||
delete m_pSampleList;
|
||||
m_pSampleList = new Sample [ m_nSampleWindowSize ];
|
||||
}
|
||||
|
||||
// initialize a circular list of samples
|
||||
for ( unsigned long j = 0 ; j < m_nSampleWindowSize ; ++j )
|
||||
{
|
||||
m_pSampleList [ j ].m_pNext = &(m_pSampleList[j + 1]);
|
||||
m_pSampleList [ j ].m_nLeft = 0;
|
||||
m_pSampleList [ j ].m_nRight = 0;
|
||||
m_pSampleList [ j ].m_nSampleValid = 0; // false
|
||||
m_pSampleList [ j ].m_nSampleAbsAvg = 0;
|
||||
// set average partner
|
||||
m_pSampleList [ j ].m_pAvgPartner = ( j < m_nSamplesInAvg ) ?
|
||||
&(m_pSampleList [ m_nSampleWindowSize - m_nSamplesInAvg + j]) :
|
||||
&(m_pSampleList [ j - m_nSamplesInAvg ]) ;
|
||||
// set lookahead partner
|
||||
m_pSampleList [ j ].m_pLookaheadPartner = ( j < m_nLookAheadWindowSize ) ?
|
||||
&(m_pSampleList [ m_nSampleWindowSize - m_nLookAheadWindowSize + j]) :
|
||||
&(m_pSampleList [ j - m_nLookAheadWindowSize ]) ;
|
||||
}
|
||||
m_pSampleList [ m_nSampleWindowSize - 1 ].m_pNext = &(m_pSampleList[0]); // last points to first
|
||||
|
||||
ZeroSampleWindow();
|
||||
|
||||
if ( c_WithDebug )
|
||||
{
|
||||
//for ( j = 0 ; j < m_nSampleWindowSize ; ++j )
|
||||
//{
|
||||
// unsigned long nNext = ( m_pSampleList [ j ].m_pNext - m_pSampleList );
|
||||
// unsigned long nAvgp = ( m_pSampleList [ j ].m_pAvgPartner - m_pSampleList );
|
||||
// unsigned long nLkap = ( m_pSampleList [ j ].m_pLookaheadPartner - m_pSampleList );
|
||||
// log4(CN_iAVC,LL_DEBUG,0, "this=%d, next=%d, AvgPartner=%d, LookAheadPartner = %d",
|
||||
// j, nNext, nAvgp, nLkap );
|
||||
//}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SetMinSamplesBeforeSwitch
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool AutoVolCtrl::SetMinSamplesBeforeSwitch ( unsigned long nMinSamplesBeforeSwitch )
|
||||
{
|
||||
if ( m_nSampleWindowSize < nMinSamplesBeforeSwitch ||
|
||||
nMinSamplesBeforeSwitch < MIN_MINIMUM_SAMPLES_BEFORE_SWITCH )
|
||||
return false;
|
||||
|
||||
m_nMinSamplesBeforeSwitch = nMinSamplesBeforeSwitch;
|
||||
m_nNumSamplesBeforeNextSwitch = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SetMaxPctChangeAtOnce
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AutoVolCtrl::SetMaxPctChangeAtOnce ( IAVCMULTIPLYPCT nPctChange )
|
||||
{
|
||||
m_nMaxChangePct = nPctChange;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SetMultipliers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AutoVolCtrl::SetMultipliers ( unsigned short int nValueWanted [ MULTIPLY_PCT_ARRAY_SIZE ] )
|
||||
{
|
||||
for ( int i = 1 ; i < MULTIPLY_PCT_ARRAY_SIZE ; ++i )
|
||||
{
|
||||
m_nMultiplyPct [ i ] = APPLY_MULTIPLY_FACTOR ( nValueWanted [ i ] ) / IAVCMULTIPLYPCT ( i );
|
||||
if ( ( i % 1000 ) == 0 )
|
||||
log3(CN_iAVC,LL_DEBUG,0, "SetMultipliers at sample %d, =%d (0x%X)\n",
|
||||
i,
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nMultiplyPct [ i ]),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nMultiplyPct [ i ]) );
|
||||
}
|
||||
m_nMultiplyPct [ 0 ] = m_nMultiplyPct [ 1 ];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SetNumberTracks
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool AutoVolCtrl::SetNumberTracks ( unsigned int nNumTracks )
|
||||
{
|
||||
if ( nNumTracks > MAX_NUMBER_OF_TRACKS )
|
||||
return false;
|
||||
m_nNumTracks = nNumTracks;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ZeroSampleWindow
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AutoVolCtrl::ZeroSampleWindow()
|
||||
{
|
||||
// initialize a circular list of samples
|
||||
for ( unsigned long j = 0 ; j < m_nSampleWindowSize ; ++j )
|
||||
{
|
||||
m_pSampleList [ j ].m_nLeft = 0;
|
||||
m_pSampleList [ j ].m_nRight = 0;
|
||||
m_pSampleList [ j ].m_nSampleValid = 0; // false
|
||||
m_pSampleList [ j ].m_nSampleAbsAvg = 0;
|
||||
}
|
||||
|
||||
// set subscripts for where next data goes or comes from
|
||||
m_pNextSet = &m_pSampleList [ 0 ];
|
||||
m_pNextGet = &m_pSampleList [ 0 ];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SetNextSample
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool AutoVolCtrl::SetNextSample ( IAVCSAMPLETYPE left, IAVCSAMPLETYPE right )
|
||||
{
|
||||
|
||||
#endif // !defined...
|
||||
#if defined(IAVC_SETNEXTSAMPLE)
|
||||
|
||||
// take out of our sum the sample m_nSamplesInAvg before the sample just before the lookahead window
|
||||
Sample* pAddToSum = m_pNextSet->m_pLookaheadPartner; // node just before lookahead window
|
||||
Sample* pRemoveFromSum = pAddToSum->m_pAvgPartner; // node to remove from sample sum
|
||||
|
||||
//if ( m_nTotalSamples <= 2200 )
|
||||
//{ // TEMP
|
||||
// log8(CN_iAVC,LL_DEBUG,0,
|
||||
// "# = %d, sum = %d,"
|
||||
// ", nextSet=%d, AddToAvg=%d (%d), RemoveFromAvg=%d (%d), newAbsAvg=%d",
|
||||
// m_nSamplesInSum,
|
||||
// long(m_nSampleAvgSum),
|
||||
// m_pNextSet - m_pSampleList,
|
||||
// pAddToSum - m_pSampleList, long(pAddToSum->m_nSampleAbsAvg),
|
||||
// pRemoveFromSum - m_pSampleList, long(pRemoveFromSum->m_nSampleAbsAvg),
|
||||
// long( absVal ( left ) + absVal ( right ) ) / m_nNumTracks );
|
||||
//}
|
||||
|
||||
// take this sample out of the sample sum (if valid)
|
||||
m_nSampleAvgSum -= pRemoveFromSum->m_nSampleAbsAvg;
|
||||
m_nSamplesInSum -= pRemoveFromSum->m_nSampleValid;
|
||||
|
||||
// form average value for this cell
|
||||
m_pNextSet->m_nSampleAbsAvg = ( absVal ( left ) + absVal ( right ) ) / m_nNumTracks;
|
||||
if ( m_pNextSet->m_nSampleAbsAvg > DEFAULT_MAX_SAMPLE_VALUE ) // 9/1/02 Safety code needed for Audacity
|
||||
m_pNextSet->m_nSampleAbsAvg = DEFAULT_MAX_SAMPLE_VALUE;
|
||||
// put in new sample
|
||||
m_pNextSet->m_nLeft = left;
|
||||
m_pNextSet->m_nRight = right;
|
||||
m_pNextSet->m_nSampleValid = 1; // true, node will now always have a valid sample in it
|
||||
|
||||
// add a node's samples into the sample sum (if valid)
|
||||
m_nSampleAvgSum += pAddToSum->m_nSampleAbsAvg;
|
||||
m_nSamplesInSum += pAddToSum->m_nSampleValid;
|
||||
|
||||
|
||||
//NOTUSED - not using lookahead
|
||||
//if ( m_nLookAheadWindowSize > 0 )
|
||||
//{ // Figure out lookahead average for our lookahead partner
|
||||
// Sample* pLookaheadPartner = pAddToSum; // take this nodes samples out of lookahead sum
|
||||
// // take this sample out of the sum (if valid)
|
||||
// m_nLookaheadSum -= pLookaheadPartner->m_nSampleAbsAvg;
|
||||
// m_nSamplesInLookahead -= pLookaheadPartner->m_nSampleValid;
|
||||
//
|
||||
// // add into the lookahead sum the new values
|
||||
// ++m_nSamplesInLookahead;
|
||||
// m_nLookaheadSum += m_pNextSet->m_nSampleAbsAvg;
|
||||
//}
|
||||
|
||||
m_pNextSet = m_pNextSet->m_pNext;
|
||||
|
||||
#endif // defined(IAVC_SETNEXTSAMPLE)
|
||||
#if !defined(IAVC_INLINE) || ( !defined(IAVC_SETNEXTSAMPLE) && !defined(IAVC_GETNEXTSAMPLE) && !defined(IAVC_ADJUSTMULTIPLIER) )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetNextSample
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool AutoVolCtrl::GetNextSample ( IAVCSAMPLETYPE & left, IAVCSAMPLETYPE & right )
|
||||
{
|
||||
|
||||
#endif // !defined...
|
||||
#if defined(IAVC_GETNEXTSAMPLE)
|
||||
|
||||
// Note: If Puts circle around before we get the samples, then we'll lose one
|
||||
// whole round of samples.
|
||||
|
||||
int nClip; // not used unless c_WithDebug is true
|
||||
|
||||
#if defined(IAVC_INLINE)
|
||||
#undef IAVC_GETNEXTSAMPLE
|
||||
#define IAVC_ADJUSTMULTIPLIER
|
||||
//#pragma message("inlining AdjustMultiplier 1st time")
|
||||
#include "iAVC.cpp"
|
||||
#define IAVC_GETNEXTSAMPLE
|
||||
#undef IAVC_ADJUSTMULTIPLIER
|
||||
#else
|
||||
if ( m_pNextGet == m_pNextSet )
|
||||
{
|
||||
return false; // no sample to give
|
||||
}
|
||||
|
||||
AdjustMultiplier();
|
||||
#endif
|
||||
|
||||
if ( c_WithDebug )
|
||||
{
|
||||
++m_nTotalSamples;
|
||||
|
||||
if ( ( m_nTotalSamples % 10000 ) <= 1 )
|
||||
{
|
||||
log4(CN_iAVC,LL_DEBUG,0,
|
||||
"Sample %d, Number of samples in sum = %d, sample sum = %d, sample avg = %d\n",
|
||||
m_nTotalSamples,
|
||||
m_nSamplesInSum,
|
||||
long ( AVG_TO_MULTIPLIER_SUBSCRIPT(m_nSampleAvgSum) ),
|
||||
long ( AVG_TO_MULTIPLIER_SUBSCRIPT(m_nSampleAvgSum/m_nSamplesInSum) ) );
|
||||
}
|
||||
|
||||
nClip = 0;
|
||||
|
||||
if ( IF_CLIP ( left ) || IF_CLIP ( right ) || m_nTotalSamples == 55666 )
|
||||
{
|
||||
log2(CN_iAVC,LL_ERROR,0,"ERROR: Sample out of range, left=%d, right=%d\n",
|
||||
AVG_TO_MULTIPLIER_SUBSCRIPT( m_pNextGet->m_nLeft ),
|
||||
AVG_TO_MULTIPLIER_SUBSCRIPT( m_pNextGet->m_nRight ) );
|
||||
}
|
||||
}
|
||||
|
||||
IAVCSUMTYPE nLeft;
|
||||
IAVCSUMTYPE nRight;
|
||||
nLeft = UNDO_MULTIPLY_FACTOR ( m_nCurrentMultiplier * m_pNextGet->m_nLeft );
|
||||
nRight = UNDO_MULTIPLY_FACTOR ( m_nCurrentMultiplier * m_pNextGet->m_nRight );
|
||||
|
||||
if ( IF_CLIP ( nLeft ) || IF_CLIP ( nRight ) )
|
||||
{ // We had a clip, see if we can adjust multiplier down.
|
||||
|
||||
// What do we do? If this is a momentary pop, like a pop on a record, we should
|
||||
// do nothing. But most audio today is probably from CDs and therefore
|
||||
// probably clean. So let's be bold and ASSUME that we're just moving into
|
||||
// a loud section from a softer section (which can be why we have a high
|
||||
// multiplier for this sample). In this case, let's just change the multiplier
|
||||
// now and not wait for the end of the next change window. To figure out the
|
||||
// new multiplier, we'll just use this sample.
|
||||
|
||||
long nCurSampleAvgSubscript = AVG_TO_MULTIPLIER_SUBSCRIPT(m_pNextGet->m_nSampleAbsAvg);
|
||||
if ( nCurSampleAvgSubscript < 0 ) // Safety code, should not be needed
|
||||
nCurSampleAvgSubscript = 0;
|
||||
else if ( nCurSampleAvgSubscript >= MULTIPLY_PCT_ARRAY_SIZE )
|
||||
nCurSampleAvgSubscript = MULTIPLY_PCT_ARRAY_SIZE - 1;
|
||||
m_nCurrentMultiplier = m_nMultiplyPct [ nCurSampleAvgSubscript ]; // always positive
|
||||
m_nNumSamplesBeforeNextSwitch = m_nMinSamplesBeforeSwitch;
|
||||
|
||||
if ( c_WithDebug )
|
||||
{
|
||||
nClip = 1;
|
||||
}
|
||||
|
||||
// // This path will take extra time, but shouldn't occur very often.
|
||||
// m_nNumSamplesBeforeNextSwitch = 0; // for multiplier adjustment
|
||||
// ++m_nNumSamplesBeforeNextSwitch; // don't do this twice for a sample, already invoked AdjustMultiplier
|
||||
//
|
||||
//#if defined(IAVC_INLINE)
|
||||
//#undef IAVC_GETNEXTSAMPLE
|
||||
//#define IAVC_ADJUSTMULTIPLIER
|
||||
////#pragma message("inlining AdjustMultiplier 2nd time")
|
||||
//#include "DynRangeComp.cpp"
|
||||
//#define IAVC_GETNEXTSAMPLE
|
||||
//#undef IAVC_ADJUSTMULTIPLIER
|
||||
//#else
|
||||
// AdjustMultiplier();
|
||||
//#endif
|
||||
|
||||
nLeft = UNDO_MULTIPLY_FACTOR ( m_nCurrentMultiplier * m_pNextGet->m_nLeft );
|
||||
nRight = UNDO_MULTIPLY_FACTOR ( m_nCurrentMultiplier * m_pNextGet->m_nRight );
|
||||
|
||||
if ( IF_CLIP ( nLeft ) || IF_CLIP ( nRight ) )
|
||||
{
|
||||
nLeft = m_pNextGet->m_nLeft; // don't clip, use original values instead
|
||||
nRight = m_pNextGet->m_nRight; // don't clip, use original values instead
|
||||
}
|
||||
}
|
||||
left = nLeft;
|
||||
right = nRight;
|
||||
|
||||
if ( c_WithDebug )
|
||||
{
|
||||
if ( nClip != 0 )
|
||||
{
|
||||
m_nClips += nClip;
|
||||
if ( ( m_nClips % 1 ) == 0 )
|
||||
{ // m_nTotalSamples may be off if buffered (i.e. more put samples than get samples done)
|
||||
log4(CN_iAVC,LL_DEBUG,0, "Sample %d clipped, orig left=%d, right=%d, multiplier=0x%X\n",
|
||||
m_nTotalSamples,
|
||||
AVG_TO_MULTIPLIER_SUBSCRIPT(m_pNextGet->m_nLeft),
|
||||
AVG_TO_MULTIPLIER_SUBSCRIPT(m_pNextGet->m_nRight),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( m_nTotalSamples % 5000 ) == 0 )
|
||||
{
|
||||
log3(CN_iAVC,LL_DEBUG,0, "Sample %d, multiplier=%d (0x%X),...\n",
|
||||
m_nTotalSamples,
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier) );
|
||||
log4(CN_iAVC,LL_DEBUG,0, " , Transformed %d->%d %d->%d\n",
|
||||
long(AVG_TO_MULTIPLIER_SUBSCRIPT(m_pNextGet->m_nLeft)),
|
||||
long(AVG_TO_MULTIPLIER_SUBSCRIPT(left)),
|
||||
long(AVG_TO_MULTIPLIER_SUBSCRIPT(m_pNextGet->m_nRight)),
|
||||
long(AVG_TO_MULTIPLIER_SUBSCRIPT(right)) );
|
||||
}
|
||||
}
|
||||
|
||||
m_pNextGet = m_pNextGet->m_pNext;
|
||||
|
||||
#endif // defined(IAVC_GETNEXTSAMPLE)
|
||||
#if !defined(IAVC_INLINE) || ( !defined(IAVC_SETNEXTSAMPLE) && !defined(IAVC_GETNEXTSAMPLE) && !defined(IAVC_ADJUSTMULTIPLIER) )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AdjustMultiplier
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AutoVolCtrl::AdjustMultiplier()
|
||||
{
|
||||
// TEMPORARY DEBUG CODE
|
||||
if ( c_WithDebug && m_nTotalSamples >= 466930L && m_nTotalSamples <= 466973L )
|
||||
{
|
||||
log3(CN_iAVC,LL_DEBUG,0, "DEBUG at sample %d, mul now=0x%X (%d)\n",
|
||||
m_nTotalSamples,
|
||||
long(m_nCurrentMultiplier),
|
||||
long(m_nCurrentMultiplier) );
|
||||
long nLookaheadAvg; // needs to be long since used as a subscript
|
||||
if ( m_nSamplesInLookahead > 0 )
|
||||
nLookaheadAvg= long ( m_nLookaheadSum/m_nSamplesInLookahead );
|
||||
else
|
||||
nLookaheadAvg = 0;
|
||||
log4(CN_iAVC,LL_DEBUG,0, " sample max=%d, sample win avg=%d, lookahead avg=%d, avg multiplier=0x%X\n",
|
||||
long(maxVal(absVal(m_pNextGet->m_nLeft),absVal(m_pNextGet->m_nRight))),
|
||||
long(m_nSampleAvgSum / m_nSamplesInSum),
|
||||
nLookaheadAvg,
|
||||
long(m_nMultiplyPct [ nLookaheadAvg ]) );
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined...
|
||||
#if defined(IAVC_ADJUSTMULTIPLIER)
|
||||
//#pragma message("inlining AdjustMultiplier")
|
||||
|
||||
--m_nNumSamplesBeforeNextSwitch;
|
||||
if ( m_nNumSamplesBeforeNextSwitch <= 0 )
|
||||
{ // long time since last change, see if it is time to change the multiplier
|
||||
long nCurSampleAvgSubscript = ( m_nSamplesInSum <= 0 ) ? 0 :
|
||||
( AVG_TO_MULTIPLIER_SUBSCRIPT(m_nSampleAvgSum) / m_nSamplesInSum );
|
||||
if ( nCurSampleAvgSubscript < 0 ) // Safety code, should not be needed
|
||||
nCurSampleAvgSubscript = 0;
|
||||
else if ( nCurSampleAvgSubscript >= MULTIPLY_PCT_ARRAY_SIZE )
|
||||
nCurSampleAvgSubscript = MULTIPLY_PCT_ARRAY_SIZE - 1;
|
||||
IAVCMULTIPLYPCT nNewMultiplier = m_nMultiplyPct [ nCurSampleAvgSubscript ]; // always positive
|
||||
IAVCMULTIPLYPCT nMultiplierDiff = nNewMultiplier - m_nCurrentMultiplier; // positive or negative
|
||||
// if new multiplier is 1, force change to get to 1 (nChangeThreshold always positive)
|
||||
IAVCMULTIPLYPCT nChangeThreshold = ( nMultiplierDiff != 0 &&
|
||||
nNewMultiplier == APPLY_MULTIPLY_FACTOR ( 1 ) ) ?
|
||||
nMultiplierDiff :
|
||||
IAVCMULTIPLYPCT ( m_nCurrentMultiplier * m_nMaxChangePct / 100 ); // % of current multiplier
|
||||
//NOTUSED - not using lookahead
|
||||
//unsigned long nLookaheadAvg;
|
||||
//if ( m_nSamplesInLookahead > 0 )
|
||||
// nLookaheadAvg = m_nLookaheadSum/m_nSamplesInLookahead;
|
||||
//else
|
||||
// nLookaheadAvg = 0;
|
||||
//long nLookaheadMultiplier = m_nMultiplyPct [ nLookaheadAvg ];
|
||||
|
||||
if ( nMultiplierDiff >= nChangeThreshold )
|
||||
{ // adjust multiplier up
|
||||
log4(CN_iAVC,LL_DEBUG,0, "Multiplier UP old=%d, new=%d, diff=%d, threshold=%d\n",
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(nNewMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(nMultiplierDiff),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(nChangeThreshold) );
|
||||
m_nCurrentMultiplier = nNewMultiplier; // or m_nCurrentMultiplier += nChangeThreshold;
|
||||
m_nNumSamplesBeforeNextSwitch = m_nMinSamplesBeforeSwitch;
|
||||
if ( c_WithDebug )
|
||||
{
|
||||
++m_nNumMultiplerChanges;
|
||||
log4(CN_iAVC,LL_DEBUG,0, "Multiplier UP at sample %d, current avg=%d, now=%d (0x%X)\n",
|
||||
m_nTotalSamples,
|
||||
nCurSampleAvgSubscript,
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier) );
|
||||
//NOTUSED - not using lookahead
|
||||
//log2(CN_iAVC,LL_DEBUG,0, " lookahead: avg=%d, avg multiplier=0x%X\n",
|
||||
// long(nLookaheadAvg),
|
||||
// long(nLookaheadMultiplier) );
|
||||
}
|
||||
}
|
||||
else if ( nMultiplierDiff <= - nChangeThreshold )
|
||||
{ // adjust multiplier down
|
||||
log4(CN_iAVC,LL_DEBUG,0, "Multiplier DOWN old=%d, new=%d, diff=%d, threshold=%d\n",
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(nNewMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(nMultiplierDiff),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(nChangeThreshold) );
|
||||
m_nCurrentMultiplier = nNewMultiplier; // or m_nCurrentMultiplier -= nChangeThreshold;
|
||||
m_nNumSamplesBeforeNextSwitch = m_nMinSamplesBeforeSwitch;
|
||||
if ( c_WithDebug )
|
||||
{
|
||||
++m_nNumMultiplerChanges;
|
||||
log4(CN_iAVC,LL_DEBUG,0, "Multiplier DOWN at sample %d, current avg=%d, now=%d (0x%X)\n",
|
||||
m_nTotalSamples,
|
||||
nCurSampleAvgSubscript,
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier),
|
||||
MULTIPLY_FACTOR_TO_INT_X256(m_nCurrentMultiplier) );
|
||||
//NOTUSED - not using lookahead
|
||||
//log2(CN_iAVC,LL_DEBUG,0, " lookahead: avg=%d, avg multiplier=0x%X\n",
|
||||
// long(nLookaheadAvg),
|
||||
// long(nLookaheadMultiplier) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(IAVC_ADJUSTMULTIPLIER)
|
||||
#if !defined(IAVC_INLINE) || ( !defined(IAVC_SETNEXTSAMPLE) && !defined(IAVC_GETNEXTSAMPLE) && !defined(IAVC_ADJUSTMULTIPLIER) )
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // !defined...
|
||||
|
@ -1,250 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// iAVC -- integer Automatic Volume Control (on samples given it)
|
||||
//
|
||||
// Copyright (C) 2002 Vincent A. Busam
|
||||
// 15754 Adams Ridge
|
||||
// Los Gatos, CA 95033
|
||||
// email: vince@busam.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// If you change the algorithm or find other sets of values that improve the
|
||||
// output results, please send me a copy so that I can incorporate them into
|
||||
// iAVC. Of course, you are not required to send me any updates under the
|
||||
// LGPL license, but please consider doing so under the spirit of open source
|
||||
// and in appreciation of being able to take advantage of my efforts expended
|
||||
// in developing iAVC.
|
||||
|
||||
// This code implements a "poor man's" dynamic range compression algorithm
|
||||
// that was build on hueristics. It's purpose is to perform dynamic range
|
||||
// compression in real time using only integer arithmetic. Processing time
|
||||
// is more important than memory.
|
||||
|
||||
// There are 3 window sizes that can be set:
|
||||
// Sample Window Size: Total number of samples kept in a circular buffer.
|
||||
// The caller can "delay" retrieving samples this
|
||||
// long, although there is probably no reason to
|
||||
// make this bigger than the Adjuster Window size
|
||||
// plus the Lookahead Window size.
|
||||
// Adjuster Window Size: Total number of samples in the moving average
|
||||
// that is used to determine the amplification
|
||||
// multiplication factor.
|
||||
// Lookahead Window Size: A small window that is this many samples ahead
|
||||
// of the Adjuster Window. The
|
||||
// moving average of this window is used to
|
||||
// delay changing the multiplication factor for
|
||||
// this many samples. Helps avoid distorted
|
||||
// transitions from loud to soft. This is only
|
||||
// useful if the caller delays retrieving samples
|
||||
// by at least this many samples. (The lookahead
|
||||
// window is currently NOT being used.)
|
||||
|
||||
// |- oldest sample newest sample -|
|
||||
// | |
|
||||
// <----------------------- Sample Window --------------------------------->
|
||||
// <-Lookahead Window->
|
||||
// <------------ Adjuster Window -------------->
|
||||
//
|
||||
// ^
|
||||
// last sample put by PutNextSample -|
|
||||
//
|
||||
// ^
|
||||
// |- last sample got by GetNextSample
|
||||
//
|
||||
// <-- callers put/get delay ->
|
||||
|
||||
// The algorithms are safe for files with the number of samples <= 2,147,483,647
|
||||
// since 32 bit signed integer storage is used in some places.
|
||||
|
||||
|
||||
// The define symbol "IAVC_INLINE" is used to make the attributes (data) outside
|
||||
// the class definition so the SetNextSample and PutNextSample methods can be
|
||||
// inline for faster processing in realtime environments. (I don't trust
|
||||
// all C++ compilers to honor the inline directive so I'm forcing inline through
|
||||
// the use of define symbols.) See DRCinlineSample.cpp for how to use define
|
||||
// symbols for inline code.
|
||||
|
||||
// The define symbol "IAVC_FLOAT" is used to perform calculations in floating point
|
||||
// instead of integer. Floating point samples are expected to be in the range
|
||||
// or -1.0 to +1.0. Note that the multiplier array size remains
|
||||
// MULTIPLY_PCT_ARRAY_SIZE.
|
||||
|
||||
#ifndef _IAVC_H_
|
||||
#define _IAVC_H_
|
||||
|
||||
#ifndef IAVC_INLINE
|
||||
// prepare other defines for code inclusion, since not inline
|
||||
#define IAVC_SETNEXTSAMPLE
|
||||
#define IAVC_GETNEXTSAMPLE
|
||||
#define IAVC_ADJUSTMULTIPLIER
|
||||
#else
|
||||
#undef IAVC_SETNEXTSAMPLE
|
||||
#undef IAVC_GETNEXTSAMPLE
|
||||
#undef IAVC_ADJUSTMULTIPLIER
|
||||
#endif
|
||||
|
||||
#define MAX_INTEGER_SAMPLE_VALUE ( 32767 ) // for 16 bit samples
|
||||
#define MULTIPLY_PCT_ARRAY_SIZE ( MAX_INTEGER_SAMPLE_VALUE + 2 )
|
||||
|
||||
#define DEFAULT_MINIMUM_SAMPLES_BEFORE_SWITCH 1100
|
||||
#define MIN_MINIMUM_SAMPLES_BEFORE_SWITCH 1
|
||||
|
||||
#define DEFAULT_ADJUSTER_WINDOW_SIZE 2200
|
||||
#define DEFAULT_LOOKAHEAD_WINDOW_SIZE 0
|
||||
|
||||
#define DEFAULT_SAMPLE_WINDOW_SIZE ( DEFAULT_ADJUSTER_WINDOW_SIZE + DEFAULT_LOOKAHEAD_WINDOW_SIZE )
|
||||
#define MAX_SAMPLE_WINDOW_SIZE 32767
|
||||
|
||||
|
||||
#define DEFAULT_MAX_PCT_CHANGE_AT_ONCE 25 // 25%, not used if == 0
|
||||
|
||||
#define DEFAULT_NUMBER_OF_TRACKS 2
|
||||
#define MAX_NUMBER_OF_TRACKS 2
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef AfxMessageBox
|
||||
#define AfxMessageBox( pText ) { fprintf(stderr,"MESSAGE: %s\n",pText); };
|
||||
#endif
|
||||
|
||||
#ifndef maxVal
|
||||
#define maxVal(a,b) ( (a<b)?b:a )
|
||||
#endif
|
||||
|
||||
#ifndef absVal
|
||||
#define absVal(a) ( (a<0)?-a:a )
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef IAVC_FLOAT
|
||||
//#pragma message("iAVC using floating point samples")
|
||||
typedef float IAVCSAMPLETYPE;
|
||||
typedef float IAVCSUMTYPE;
|
||||
typedef float IAVCMULTIPLYPCT;
|
||||
#define APPLY_MULTIPLY_FACTOR(x) (x)
|
||||
#define UNDO_MULTIPLY_FACTOR(x) (x)
|
||||
#define AVG_TO_MULTIPLIER_SUBSCRIPT(x) long(x*MAX_INTEGER_SAMPLE_VALUE)
|
||||
#define MULTIPLY_FACTOR_TO_INT_X256(x) (int(x*256))
|
||||
#define DEFAULT_MAX_SAMPLE_VALUE 1 // values range from -1 to 1 for float
|
||||
#define DEFAULT_MIN_SAMPLE_VALUE -1 // values range from -1 to 1 for float
|
||||
#define IF_CLIP(x) ( absVal(x) > m_nMaxSampleValue )
|
||||
#else
|
||||
//#pragma message("iAVC using short int samples")
|
||||
typedef short int IAVCSAMPLETYPE;
|
||||
typedef long IAVCSUMTYPE;
|
||||
typedef long IAVCMULTIPLYPCT;
|
||||
#define APPLY_MULTIPLY_FACTOR(x) (long(x)<<8)
|
||||
#define UNDO_MULTIPLY_FACTOR(x) (long(x)>>8)
|
||||
#define AVG_TO_MULTIPLIER_SUBSCRIPT(x) (x)
|
||||
#define MULTIPLY_FACTOR_TO_INT_X256(x) (x)
|
||||
#define DEFAULT_MAX_SAMPLE_VALUE 32767 // for 16 bit samples, -32767 to 32767
|
||||
#define DEFAULT_MIN_SAMPLE_VALUE -32768 // for 16 bit samples, -32767 to 32767
|
||||
#define IF_CLIP(x) ( x != IAVCSAMPLETYPE ( x ) )
|
||||
#endif
|
||||
|
||||
struct Sample;
|
||||
|
||||
class AutoVolCtrl
|
||||
{
|
||||
public:
|
||||
AutoVolCtrl(); // standard constructor
|
||||
|
||||
virtual ~AutoVolCtrl(); // destructor
|
||||
|
||||
void Reset(); // reset to default values (can call between tracks, all settings saved)
|
||||
|
||||
// Initialization methods (Set Sample Window Size BEFORE setting Min Samples Before Switch)
|
||||
// Min Samples Before Switch must be < Sample Window Size
|
||||
// window size <= MAX_SAMPLE_WINDOW_SIZE
|
||||
bool SetSampleWindowSize ( unsigned long nSampleWindowSize,
|
||||
unsigned long nAdjusterWindowSize,
|
||||
unsigned long nLookAheadWindowSize );
|
||||
bool SetMinSamplesBeforeSwitch ( unsigned long nMinSamplesBeforeSwitch );
|
||||
void SetMaxPctChangeAtOnce ( IAVCMULTIPLYPCT nPctChange ); // in %, e.g. 10 for 10%
|
||||
void SetMultipliers ( unsigned short int nValueWanted [ MULTIPLY_PCT_ARRAY_SIZE ] );
|
||||
// e.g. if a sample with value 10000 is to be changed to be 20000, then
|
||||
// nValueWanted [ 10000 ] = 20000;
|
||||
// a nil transform is when every array element's value is its subscript
|
||||
//
|
||||
bool SetNumberTracks ( unsigned int nNumTracks ); // currently only 1 or 2 tracks supported
|
||||
|
||||
// Processing samples. In version 1 you MUST do a SetNextSample followed by a GetNextSample
|
||||
// If only one track the right sample must = 0.
|
||||
bool SetNextSample ( IAVCSAMPLETYPE left, IAVCSAMPLETYPE right ); // return true if AOK
|
||||
bool GetNextSample ( IAVCSAMPLETYPE & left, IAVCSAMPLETYPE & right ); // return true if AOK
|
||||
|
||||
protected:
|
||||
|
||||
void AdjustMultiplier();
|
||||
void ZeroSampleWindow();
|
||||
|
||||
#ifdef IAVC_INLINE
|
||||
|
||||
}; // end class definition here if not C++ (make data definitions below outside of class
|
||||
#pragma message("iAVC using inline methods")
|
||||
|
||||
#endif
|
||||
|
||||
struct Sample
|
||||
{
|
||||
Sample* m_pNext; // one entry points to the next, last entry to first entry
|
||||
Sample* m_pAvgPartner; // node "m_nSamplesInAvg" (i.e. adjuster size) before this node
|
||||
Sample* m_pLookaheadPartner; // node "m_nLookAheadWindowSize" before this node
|
||||
|
||||
IAVCSAMPLETYPE m_nLeft;
|
||||
IAVCSAMPLETYPE m_nRight;
|
||||
long m_nSampleValid; // =1 if node contains a sample value, =0 if no value
|
||||
IAVCSUMTYPE m_nSampleAbsAvg; // ( abs(left) + abs(right) ) / num_tracks, zero if not valid
|
||||
};
|
||||
|
||||
// Following are parameters whose values are provided by caller
|
||||
unsigned long m_nSampleWindowSize; // size of window of samples to keep
|
||||
unsigned long m_nSamplesInAvg; // <= m_nSampleWindowSize
|
||||
unsigned long m_nLookAheadWindowSize; // <= m_nMinSamplesBeforeSwitch & <= m_nSampleWindowSize
|
||||
unsigned long m_nMinSamplesBeforeSwitch; // minimum number of samples between multiplier changes
|
||||
IAVCMULTIPLYPCT m_nMaxChangePct; // maximum % change in multiplier at a time
|
||||
IAVCMULTIPLYPCT m_nMultiplyPct [ MULTIPLY_PCT_ARRAY_SIZE ]; // desired multiplier % for each sample value
|
||||
unsigned long m_nNumTracks; // = 2 for stereo, = 1 for mono
|
||||
IAVCSUMTYPE m_nMaxSampleValue; // e.g. 32767 for 16 bit
|
||||
|
||||
// Following are internal attributes
|
||||
IAVCSUMTYPE m_nSampleAvgSum; // sum of sound samples in current sample window
|
||||
unsigned long m_nSamplesInSum; // number of samples in m_nSampleAvgSum ( <= m_nSamplesInAvg )
|
||||
IAVCMULTIPLYPCT m_nCurrentMultiplier; // current % multiplier for sample
|
||||
Sample* m_pNextSet; // next node for SetNextSample
|
||||
Sample* m_pNextGet; // next node for GetNextSample
|
||||
IAVCSUMTYPE m_nLookaheadSum; // sum of lookahead samples
|
||||
unsigned int m_nSamplesInLookahead; // number of samples in m_nLookaheadSum
|
||||
signed long m_nNumSamplesBeforeNextSwitch; // number of samples before next switch
|
||||
|
||||
Sample * m_pSampleList; // array of samples
|
||||
|
||||
// Following are internal attributes for diagnostics
|
||||
long m_nTotalSamples;
|
||||
long m_nNumMultiplerChanges;
|
||||
long m_nClips;
|
||||
|
||||
#ifndef IAVC_INLINE
|
||||
|
||||
};
|
||||
|
||||
#endif // end class definition here if C++
|
||||
|
||||
|
||||
#endif // _IAVC_H_
|
@ -1,82 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// iAVC -- integer Automatic Volume Control -- Sample transformations for use with iAVC
|
||||
//
|
||||
// Copyright (C) 2002 Vincent A. Busam
|
||||
// 15754 Adams Ridge
|
||||
// Los Gatos, CA 95033
|
||||
// email: vince@busam.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// nil transform. Useful for testing.
|
||||
|
||||
static int iHoriz_1K_1K[] = { 0, 1000, 13000, 32768, 99999 }; // leave first and last two pairs
|
||||
static int iVert_1K_1K [] = { 0, 1000, 13000, 32768, 99999 }; // of values alone
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// Heavy amplification in low volumes, linear when sound is louder.
|
||||
// Doesn't turn linear until quite loud, which contributes to more clipping.
|
||||
|
||||
// -100 db -> -100 db expand 2:1 below -60 db 0 -> 0
|
||||
// -60 db -> -20 db compress 4.33:1 below -8 db 1,000 -> 3,500
|
||||
// -8 db -> -8 db flat 1:1 above -8 db 13,000 -> 13,000
|
||||
// 0 db -> 0 db
|
||||
static int iHoriz_1K_3HK[] = { 0, 1000, 13000, 32768, 99999 }; // leave first and last two pairs
|
||||
static int iVert_1K_3HK [] = { 0, 3500, 13000, 32768, 99999 }; // of values alone
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// Another version with heavy amplication in low volumes.
|
||||
// based on x^0.75 from 0 to 5,000 then flat
|
||||
// More points make for a smoother curve but more multiplier changes.
|
||||
|
||||
static int iHoriz_E75_5K[] = {
|
||||
0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950,1000,1050,1100,1150,1200,1250,1300,1350,1400,1450,1500,1550,1600,1650,1700,1750,1800,1850,1900,1950,2000,2050,2100,2150,2200,2250,2300,2350,2400,2450,2500,2550,2600,2650,2700,2750,2800,2850,2900,2950,3000,3050,3100,3150,3200,3250,3300,3350,3400,3450,3500,3550,3600,3650,3700,3750,3800,3850,3900,3950,4000,4050,4100,4150,4200,4250,4300,4350,4400,4450,4500,4550,4600,4650,4700,4750,4800,4850,4900,4950,5000
|
||||
,32768, 99999 };
|
||||
static int iVert_E75_5K [] = {
|
||||
0,1581,1880,2081,2236,2364,2475,2572,2659,2739,2812,2880,2943,3002,3058,3112,3162,3211,3257,3301,3344,3385,3424,3463,3500,3536,3570,3604,3637,3669,3700,3731,3761,3790,3818,3846,3873,3900,3926,3951,3976,4001,4025,4049,4072,4095,4118,4140,4162,4183,4204,4225,4246,4266,4286,4306,4325,4344,4363,4382,4401,4419,4437,4455,4472,4490,4507,4524,4540,4557,4573,4590,4606,4622,4637,4653,4668,4684,4699,4714,4729,4743,4758,4772,4787,4801,4815,4829,4843,4856,4870,4883,4897,4910,4923,4936,4949,4962,4975,4987,5000
|
||||
,32768, 99999 };
|
||||
//multipliers
|
||||
// 1,31.6,18.8,13.9,11.2, 9.5, 8.2 ,7.3, 6.6, 6.1, 5.6, 5.2, 4.9, 4.6, 4.4, 4.1, 4.0, 3.8, 3.6, 3.5, 3.3,3.2,3.1,3.0,2.9,2.8,2.7,2.7,2.6,2.5,2.5,2.4,2.4,2.3,2.2,2.2,2.2,2.1,2.1,2.0,2.0,2.0,1.9,1.9,1.9,1.8,1.8,1.8,1.7,1.7,1.7,1.7,1.6,1.6,1.6,1.6,1.5,1.5,1.5,1.5,1.5,1.4,1.4,1.4,1.4,1.4,1.4,1.4,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.2,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.0,1.0,1.0,1.0,1.0,1.0,1.0
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// Another version with heavy amplication in low volumes.
|
||||
// based on x^0.75 from 0 to 3,500 then flat
|
||||
// More points make for a smoother curve but more multiplier changes.
|
||||
|
||||
static int iHoriz_75_3500[] = {
|
||||
0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950,1000,1050,1100,1150,1200,1250,1300,1350,1400,1450,1500,1550,1600,1650,1700,1750,1800,1850,1900,1950,2000,2050,2100,2150,2200,2250,2300,2350,2400,2450,2500,2550,2600,2650,2700,2750,2800,2850,2900,2950,3000,3050,3100,3150,3200,3250,3300,3350,3400,3450,3500
|
||||
,32768, 99999 };
|
||||
static int iVert_75_3500 [] = {
|
||||
0,1210,1439,1592,1711,1809,1894,1968,2035,2096,2152,2204,2252,2298,2341,2381,2420,2457,2492,2526,2559,2590,2621,2650,2678,2706,2732,2758,2783,2808,2832,2855,2878,2900,2922,2943,2964,2984,3004,3024,3043,3062,3080,3099,3116,3134,3151,3168,3185,3201,3218,3234,3249,3265,3280,3295,3310,3325,3339,3354,3368,3382,3395,3409,3422,3436,3449,3462,3475,3487,3500
|
||||
,32768, 99999 };
|
||||
//multipliers
|
||||
// 1,24.2,14.4,10.6, 8.6, 7.2, 6.3, 5.6, 5.1, 4.7, 4.3, 4.0, 3.8, 3.5, 3.3, 3.2, 3.0, 2.9, 2.8, 2.7, 2.6, 2.5, 2.4, 2.3, 2.2, 2.2, 2.1, 2.0, 2.0, 1.9, 1.9, 1.8, 1.8, 1.8, 1.7, 1.7, 1.6, 1.6, 1.6, 1.6, 1.5, 1.5, 1.5, 1.4, 1.4, 1.4, 1.4, 1.3, 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// Another version with heavy amplication in low volumes.
|
||||
// based on x^0.75 from 0 to 3,500 then flat
|
||||
// Fewer point to reduce number of multiplier changes.
|
||||
|
||||
static int iHoriz_AE75_3HK[] = { 0, 150, 300, 450, 650, 2500, 32768, 99999 }; // leave first and last two pairs
|
||||
static int iVert_AE75_3HK [] = { 0, 1592, 1894, 2096, 2298, 3218, 32768, 99999 }; // of values alone
|
||||
|
||||
//static int iHoriz_AE75_3HK[] = { 0, 300, 600, 1000, 2500, 3500, 32768, 99999 }; // leave first and last two pairs
|
||||
//static int iVert_AE75_3HK [] = { 0, 1900, 2250, 2500, 3100, 3500, 32768, 99999 }; // of values alone
|
@ -120,7 +120,7 @@ function cleanfulltree {
|
||||
printf "Done\n"
|
||||
|
||||
printf "removing unused libraries from SVN tree ..."
|
||||
myrmrvf $1 lib-src/iAVC lib-src/id3lib ;
|
||||
myrmrvf $1 lib-src/id3lib ;
|
||||
myrmrvf $1 lib-src/portburn lib-src/rtaudio;
|
||||
myrmrvf $1 lib-src/taglib;
|
||||
printf "Done\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user