dolphin/Externals/MusicMod/Player/Src/PlaybackEq.cpp

224 lines
7.5 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Plainamp, Open source Winamp core
//
// Copyright © 2005 Sebastian Pipping <webmaster@hartwork.org>
//
// --> http://www.hartwork.org
//
// This source code is released under the GNU General Public License (GPL).
// See GPL.txt for details. Any non-GPL usage is strictly forbidden.
////////////////////////////////////////////////////////////////////////////////
#include "Playback.h"
#include "InputPlugin.h"
#include "Console.h"
#include "Config.h"
#include <vector>
using namespace std;
vector <char *> eq_vec;
// Note: CurPresetFixed will be renamed to CurPreset when
// custom presets are implemented. This hopefully avoids
// migration trouble.
int iCurPreset; // -1 means EQ off
ConfInt ciCurPreset( &iCurPreset, TEXT( "CurPresetFixed" ), CONF_MODE_INTERNAL, -1 );
bool bPreventDistortion; // Automatic preamp adjustment
ConfBool cbPreventDistortion( &bPreventDistortion, TEXT( "PreventDistortion" ), CONF_MODE_PUBLIC, true );
////////////////////////////////////////////////////////////////////////////////
// PRE valid index
////////////////////////////////////////////////////////////////////////////////
void Playback_Eq_Set( int iPresetIndex )
{
if( active_input_plugin && active_input_plugin->plugin )
{
if( iPresetIndex == -1 ) // == EQ disabled
{
char data[ 10 ] = { 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 };
active_input_plugin->plugin->EQSet( 0, data, 31 );
}
else
{
char data[ 10 ];
memcpy( data, eq_vec[ iPresetIndex ], sizeof( char ) * 10 );
if( bPreventDistortion )
{
// Search minimum (most amplifying band)
int iMin = 63;
int i;
for( i = 0; i < 10; i++ )
{
if( data[ i ] < iMin ) iMin = data[ i ];
}
if( iMin < 31 ) // Possible distortion
{
// Adjust preamp to prevent distortion
active_input_plugin->plugin->EQSet( 1, data, 31 + ( 31 - iMin ) );
}
else
{
if( iMin > 31 ) // Lower than necessary
{
// Push to zero level so we get
// more volume without distortion
const int iSub = iMin - 31;
for( i = 0; i < 10; i++ )
{
data[ i ] -= iSub;
}
}
active_input_plugin->plugin->EQSet( 1, data, 31 );
}
}
else
{
active_input_plugin->plugin->EQSet( 1, data, 31 );
}
}
}
}
/*
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::Set( bool bOn, char * pData, int iPreamp )
{
if( active_input_plugin && active_input_plugin->plugin )
{
char data[ 10 ];
memcpy( data, pData, sizeof( char ) * 10 );
active_input_plugin->plugin->EQSet( bOn ? 1 : 0, data, iPreamp );
}
return true;
}
*/
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
int Playback::Eq::GetCurIndex()
{
return iCurPreset;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::SetIndex( int iPresetIndex )
{
if( iPresetIndex >= ( int )eq_vec.size() ) return false;
Playback_Eq_Set( iPresetIndex );
iCurPreset = iPresetIndex;
return true;
}
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::Reapply()
{
Playback_Eq_Set( iCurPreset );
return true;
}
// Note: Most of these are the exact presets used in Winamp.
// I do not expect any legal trouble with this but
// in case I am wrong please let me know and I will
// remove them.
char eq_classical [ 10 ] = { 31, 31, 31, 31, 31, 31, 44, 44, 44, 48 };
char eq_club [ 10 ] = { 31, 31, 26, 22, 22, 22, 26, 31, 31, 31 };
char eq_dance [ 10 ] = { 16, 20, 28, 32, 32, 42, 44, 44, 32, 32 };
char eq_full_bass [ 10 ] = { 16, 16, 16, 22, 29, 39, 46, 49, 50, 50 };
char eq_full_bass_treble[ 10 ] = { 20, 22, 31, 44, 40, 29, 18, 14, 12, 12 };
char eq_full_treble [ 10 ] = { 48, 48, 48, 39, 27, 14, 6, 6, 6, 4 };
char eq_headphones [ 10 ] = { 24, 14, 23, 38, 36, 29, 24, 16, 11, 8 };
char eq_laptop [ 10 ] = { 24, 14, 23, 38, 36, 29, 24, 16, 11, 8 };
char eq_large_hall [ 10 ] = { 15, 15, 22, 22, 31, 40, 40, 40, 31, 31 };
char eq_live [ 10 ] = { 40, 31, 25, 23, 22, 22, 25, 27, 27, 28 };
char eq_more_bass [ 10 ] = { 22, 22, 22, 22, 22, 22, 26, 31, 31, 31 };
char eq_party [ 10 ] = { 20, 20, 31, 31, 31, 31, 31, 31, 20, 20 };
char eq_pop [ 10 ] = { 35, 24, 20, 19, 23, 34, 36, 36, 35, 35 };
char eq_reggae [ 10 ] = { 31, 31, 33, 42, 31, 21, 21, 31, 31, 31 };
char eq_rock [ 10 ] = { 19, 24, 41, 45, 38, 25, 17, 14, 14, 14 };
char eq_ska [ 10 ] = { 36, 40, 39, 33, 25, 22, 17, 16, 14, 16 };
char eq_soft [ 10 ] = { 24, 29, 34, 36, 34, 25, 18, 16, 14, 12 };
char eq_soft_rock [ 10 ] = { 25, 25, 28, 33, 39, 41, 38, 33, 27, 17 };
char eq_techno [ 10 ] = { 19, 22, 31, 41, 40, 31, 19, 16, 16, 17 };
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
bool Playback::Eq::ReadPresets( PresetCallback AddPreset )
{
if( AddPreset == NULL ) return false;
eq_vec.push_back( eq_classical ); AddPreset( TEXT( "Classical" ) );
eq_vec.push_back( eq_club ); AddPreset( TEXT( "Club" ) );
eq_vec.push_back( eq_dance ); AddPreset( TEXT( "Dance" ) );
eq_vec.push_back( eq_full_bass ); AddPreset( TEXT( "Full Bass" ) );
eq_vec.push_back( eq_full_bass_treble ); AddPreset( TEXT( "Full Bass & Treble" ) );
eq_vec.push_back( eq_full_treble ); AddPreset( TEXT( "Full Treble" ) );
eq_vec.push_back( eq_headphones ); AddPreset( TEXT( "Headphones" ) );
eq_vec.push_back( eq_laptop ); AddPreset( TEXT( "Laptop Speakers" ) );
eq_vec.push_back( eq_large_hall ); AddPreset( TEXT( "Large Hall" ) );
eq_vec.push_back( eq_live ); AddPreset( TEXT( "Live" ) );
eq_vec.push_back( eq_more_bass ); AddPreset( TEXT( "More Bass" ) );
eq_vec.push_back( eq_party ); AddPreset( TEXT( "Party" ) );
eq_vec.push_back( eq_pop ); AddPreset( TEXT( "Pop" ) );
eq_vec.push_back( eq_reggae ); AddPreset( TEXT( "Reggae" ) );
eq_vec.push_back( eq_rock ); AddPreset( TEXT( "Rock" ) );
eq_vec.push_back( eq_ska ); AddPreset( TEXT( "Ska" ) );
eq_vec.push_back( eq_soft ); AddPreset( TEXT( "Soft" ) );
eq_vec.push_back( eq_soft_rock ); AddPreset( TEXT( "Soft Rock" ) );
eq_vec.push_back( eq_techno ); AddPreset( TEXT( "Techno" ) );
// Fix invalid indices
if( iCurPreset < -1 )
{
iCurPreset = -1;
}
else
{
const int iLen = ( int )eq_vec.size();
if( iCurPreset >= iLen )
{
iCurPreset = iLen - 1;
}
}
// TODO load/save eqf files
// GPL eqf loading from koders.com
// equalizer.c / xmms2 A Gtk2 port of xmms.(xmms2)
// equalizer.c / Digital Disco System(dds)
return true;
}