1 /***************************************************************************
2 Graphical spline display for equalizer
4 (c) 2004 Mark Kretschmann <markey@web.de>
5 (c) 2005 Markus Brueffer <markus@brueffer.de>
6 Based on code from XMMS
7 (c) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
8 ***************************************************************************/
10 /***************************************************************************
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
17 ***************************************************************************/
18 #include "equalizergraph.h"
20 #include "amarokconfig.h"
27 EqualizerGraph::EqualizerGraph( QWidget
* parent
)
28 : QWidget( parent
, 0, Qt::WNoAutoErase
)
29 , m_backgroundPixmap( new QPixmap() )
33 EqualizerGraph::~EqualizerGraph()
35 delete m_backgroundPixmap
;
39 /////////////////////////////////////////////////////////////////////////////////////
41 /////////////////////////////////////////////////////////////////////////////////////
44 EqualizerGraph::resizeEvent( QResizeEvent
* )
50 EqualizerGraph::sizeHint() const
52 return QSize( 100, 60 );
56 EqualizerGraph::paintEvent( QPaintEvent
* )
59 p
.drawPixmap( 0, 0, *m_backgroundPixmap
);
62 int middleLineY
= (int) ( ( height() - 1 ) / 2.0 + AmarokConfig::equalizerPreamp() * ( height() - 1 ) / 200.0 );
63 QPen
pen( colorGroup().dark(), 0, Qt::DotLine
);
65 p
.drawLine( 8, middleLineY
, width() - 1, middleLineY
);
67 QColor
color( colorGroup().highlight() );
69 color
.getHsv( &h
, &s
, &v
);
71 int i
, y
, ymin
, ymax
, py
= 0;
72 float x
[NUM_BANDS
], yf
[NUM_BANDS
];
73 float gains
[NUM_BANDS
] = { 0, 0, 0, 0, 0, 0, 0, 0, 0};
75 // Don't calculate 0 and NUM_BANDS-1 for accuracy reasons
76 for ( i
= 1; i
< NUM_BANDS
-1 ; i
++)
77 x
[i
] = ( width() - 8 ) * i
/ ( NUM_BANDS
-1 ) + 8;
79 x
[ NUM_BANDS
- 1 ] = width() - 1;
81 if ( AmarokConfig::equalizerEnabled() )
82 for ( i
= 0; i
< NUM_BANDS
; i
++ )
83 gains
[i
] = ( height() - 1 ) * AmarokConfig::equalizerGains()[i
] / 200.0;
85 init_spline( x
, gains
, NUM_BANDS
, yf
);
87 for ( i
= 8; i
< width(); i
++ ) {
88 y
= (int) ( ( height() - 1 ) / 2 - eval_spline( x
, gains
, yf
, NUM_BANDS
, i
) );
93 if ( y
> height() - 1 )
108 for ( y
= ymin
; y
<= ymax
; y
++ ) {
109 // Absolute carthesian coordinate
110 s
= y
- ( height() - 1 ) / 2;
113 // Normalise to a base of 256
114 // short for: s / ( ( height() / 2.0 ) * 255;
115 s
= (int) ( s
* 510.0 / height() );
117 color
.setHsv( h
, 255 - s
, v
);
126 /////////////////////////////////////////////////////////////////////////////////////
128 /////////////////////////////////////////////////////////////////////////////////////
131 EqualizerGraph::drawBackground()
133 m_backgroundPixmap
->resize( size() );
135 m_backgroundPixmap
->fill( colorGroup().background().dark( 105 ) );
136 QPainter
p( m_backgroundPixmap
);
138 // Erase background for scale
139 p
.fillRect( 0, 0, 7, height() -1, colorGroup().background());
142 p
.setPen( colorGroup().shadow() );
143 p
.drawLine( 7, 0, 7, height() - 1 );
144 p
.drawLine( 0, 0, 7, 0 );
145 p
.drawLine( 0, height() / 2 - 1, 7, height() / 2 - 1 );
146 p
.drawLine( 0, height() - 1, 7, height() - 1 );
151 EqualizerGraph::init_spline( float* x
, float* y
, int n
, float* y2
)
154 float p
, qn
, sig
, un
;
155 QVector
<float> u(n
* sizeof(float));
157 y2
[ 0 ] = u
[ 0 ] = 0.0;
159 for ( i
= 1; i
< n
- 1; i
++ ) {
160 sig
= ( (float)x
[i
] - x
[i
-1] ) / ( (float)x
[i
+1] - x
[i
-1] );
161 p
= sig
* y2
[i
-1] + 2.0;
162 y2
[i
] = ( sig
- 1.0 ) / p
;
163 u
[i
] = ( ( (float)y
[i
+1] - y
[i
] ) / ( x
[i
+1] - x
[i
] ) ) - ( ( (float)y
[i
] - y
[i
-1] ) / ( x
[i
] - x
[i
-1] ) );
164 u
[i
] = ( 6.0 * u
[i
] / ( x
[i
+1] - x
[i
-1] ) - sig
* u
[i
-1] ) / p
;
168 y2
[n
-1] = ( un
- qn
* u
[n
-2] ) / ( qn
* y2
[n
-2] + 1.0 );
169 for ( k
= n
- 2; k
>= 0; k
-- )
170 y2
[k
] = y2
[k
] * y2
[k
+1] + u
[k
];
175 EqualizerGraph::eval_spline( float xa
[], float ya
[], float y2a
[], int n
, float x
)
182 while ( khi
- klo
> 1 ) {
183 k
= ( khi
+ klo
) >> 1;
189 h
= xa
[khi
] - xa
[klo
];
190 a
= ( xa
[khi
] - x
) / h
;
191 b
= ( x
- xa
[klo
] ) / h
;
192 return ( a
* ya
[klo
] + b
* ya
[khi
] + ( ( a
*a
*a
- a
) * y2a
[klo
] + ( b
*b
*b
- b
) * y2a
[khi
] ) * ( h
*h
) / 6.0 );