aboutsummaryrefslogtreecommitdiffstats
path: root/Lua/src/menu/UMenuEqualizer.pas
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2009-03-21 19:16:07 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2009-03-21 19:16:07 +0000
commit5d69ab51fd28961fd43b7e7646768b5a6dcbcb25 (patch)
tree5323292fcb46269f7dbbafe5a15ee399ad74675e /Lua/src/menu/UMenuEqualizer.pas
parent220ae11b40e104d09e2c1ac08203c2a631294d99 (diff)
downloadusdx-5d69ab51fd28961fd43b7e7646768b5a6dcbcb25.tar.gz
usdx-5d69ab51fd28961fd43b7e7646768b5a6dcbcb25.tar.xz
usdx-5d69ab51fd28961fd43b7e7646768b5a6dcbcb25.zip
lua stuff moved to experimental folder
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@1642 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Lua/src/menu/UMenuEqualizer.pas')
-rw-r--r--Lua/src/menu/UMenuEqualizer.pas319
1 files changed, 319 insertions, 0 deletions
diff --git a/Lua/src/menu/UMenuEqualizer.pas b/Lua/src/menu/UMenuEqualizer.pas
new file mode 100644
index 00000000..6d77721c
--- /dev/null
+++ b/Lua/src/menu/UMenuEqualizer.pas
@@ -0,0 +1,319 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuEqualizer;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMusic,
+ UThemes;
+
+type
+ //----------------
+ //Tms_Equalizer
+ //Class displaying an equalizer (Songscreen)
+ //----------------
+ Tms_Equalizer = class(TObject)
+ private
+ FFTData: TFFTData; // moved here to avoid stack overflows
+ BandData: array of Byte;
+ RefreshTime: Cardinal;
+
+ Source: IAudioPlayback;
+
+ Procedure Analyse;
+ public
+ X: Integer;
+ Y: Integer;
+ Z: Real;
+
+ W: Integer;
+ H: Integer;
+ Space: Integer;
+
+ Visible: Boolean;
+ Alpha: real;
+ Color: TRGB;
+
+ Direction: Boolean;
+
+ BandLength: Integer;
+
+ Reflection: boolean;
+ Reflectionspacing: Real;
+
+
+ constructor Create(Source: IAudioPlayback; mySkin: TThemeEqualizer);
+
+ procedure Draw;
+
+ Procedure SetBands(Value: Byte);
+ Function GetBands: Byte;
+ Property Bands: Byte read GetBands write SetBands;
+ procedure SetSource(newSource: IAudioPlayback);
+ end;
+
+implementation
+uses math, SDL, gl, glext;
+
+
+constructor Tms_Equalizer.Create(Source: IAudioPlayback; mySkin: TThemeEqualizer);
+var I: Integer;
+begin
+ If (Source <> nil) then
+ begin
+ X := mySkin.X;
+ Y := mySkin.Y;
+ W := mySkin.W;
+ H := mySkin.H;
+ Z := mySkin.Z;
+
+ Space := mySkin.Space;
+
+ Visible := mySkin.Visible;
+ Alpha := mySkin.Alpha;
+ Color.R := mySkin.ColR;
+ Color.G := mySkin.ColG;
+ Color.B := mySkin.ColB;
+
+ Direction := mySkin.Direction;
+ Bands := mySkin.Bands;
+ BandLength := mySkin.Length;
+
+ Reflection := mySkin.Reflection;
+ Reflectionspacing := mySkin.Reflectionspacing;
+
+ Self.Source := Source;
+
+
+ //Check if Visible
+ If (Bands <= 0) OR
+ (BandLength <= 0) OR
+ (W <= 0) OR
+ (H <= 0) OR
+ (Alpha <= 0) then
+ Visible := False;
+
+ //ClearArray
+ For I := low(BandData) to high(BandData) do
+ BandData[I] := 3;
+ end
+ else
+ Visible := False;
+end;
+
+//--------
+// evaluate FFT-Data
+//--------
+Procedure Tms_Equalizer.Analyse;
+ var
+ I: Integer;
+ ChansPerBand: byte; // channels per band
+ MaxChannel: Integer;
+ Pos: Real;
+ CurBand: Integer;
+begin
+ Source.GetFFTData(FFTData);
+
+ Pos := 0;
+ // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz
+ ChansPerBand := ceil(92 / Bands); // How much channels are used for one Band
+ MaxChannel := ChansPerBand * Bands - 1;
+
+ // Change Lengths
+ for i := 0 to MaxChannel do
+ begin
+ // Gain higher freq. data so that the bars are visible
+ if i > 35 then
+ FFTData[i] := FFTData[i] * 8
+ else if i > 11 then
+ FFTData[i] := FFTData[i] * 4.5
+ else
+ FFTData[i] := FFTData[i] * 1.1;
+
+ // clamp data
+ if (FFTData[i] > 1) then
+ FFTData[i] := 1;
+
+ // Get max. pos
+ if (FFTData[i] * BandLength > Pos) then
+ Pos := FFTData[i] * BandLength;
+
+ // Check if this is the last channel in the band
+ if ((i+1) mod ChansPerBand = 0) then
+ begin
+ CurBand := i div ChansPerBand;
+
+ // Smooth delay if new equalizer is lower than the old one
+ if ((BandData[CurBand] > Pos) and (BandData[CurBand] > 1)) then
+ BandData[CurBand] := BandData[CurBand] - 1
+ else
+ BandData[CurBand] := Round(Pos);
+
+ Pos := 0;
+ end;
+ end;
+end;
+
+//--------
+// Draw SpectrumAnalyser, Call Analyse
+//--------
+procedure Tms_Equalizer.Draw;
+ var
+ CurTime: Cardinal;
+ PosX, PosY: Real;
+ I, J: Integer;
+ Diff: Real;
+
+ Function GetAlpha(Diff: Single): Single;
+ begin
+ If Direction then
+ Result := (Alpha * 0.6) *(0.5 - Diff/(BandLength * (H + Space)))
+ else
+ Result := (Alpha * 0.6) *(0.5 - Diff/(Bands * (H + Space)));
+ end;
+begin
+ If (Visible) AND not (AudioPlayback.Finished) then
+ begin
+ //Call Analyse if necessary
+ CurTime := SDL_GetTicks();
+ If (CurTime > RefreshTime) then
+ begin
+ Analyse;
+
+ RefreshTime := CurTime + 44;
+ end;
+
+ //Draw Equalizer Bands
+ // Setup OpenGL
+ glColorRGB(Color, Alpha);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ // Set position of the first equalizer bar
+ PosY := Y;
+ PosX := X;
+
+ // Draw bars for each band
+ for I := 0 to High(BandData) do
+ begin
+ // Reset to lower or left position depending on the drawing-direction
+ if Direction then // Vertical bars
+ // FIXME: Is Y the upper or lower coordinate?
+ PosY := Y //+ (H + Space) * BandLength
+ else // Horizontal bars
+ PosX := X;
+
+ // Draw the bar as a stack of blocks
+ for J := 1 to BandData[I] do
+ begin
+ // Draw block
+ glBegin(GL_QUADS);
+ glVertex3f(PosX, PosY, Z);
+ glVertex3f(PosX, PosY+H, Z);
+ glVertex3f(PosX+W, PosY+H, Z);
+ glVertex3f(PosX+W, PosY, Z);
+ glEnd;
+
+ If (Reflection) AND (J <= BandLength div 2) then
+ begin
+ Diff := (Y-PosY) + H;
+
+ //Draw Reflection
+ If Direction then
+ begin
+ glBegin(GL_QUADS);
+ glColorRGB(Color, GetAlpha(Diff));
+ glVertex3f(PosX, Diff + Y + ReflectionSpacing, Z);
+
+ //bottom v
+ glColorRGB(Color, GetAlpha(Diff + H));
+ glVertex3f(PosX, Diff + Y+H + ReflectionSpacing, Z);
+ glVertex3f(PosX+W, Diff + Y+H + ReflectionSpacing, Z);
+
+ glColorRGB(Color, GetAlpha(Diff));
+ glVertex3f(PosX+W, Diff + Y + ReflectionSpacing, Z);
+ glEnd;
+ end
+ else
+ begin
+ glBegin(GL_QUADS);
+ glColorRGB(Color, GetAlpha(Diff));
+ glVertex3f(PosX, Diff + Y + (H + Space)*Bands + ReflectionSpacing, Z);
+ glVertex3f(PosX, Diff + Y+H + (H + Space)*Bands + ReflectionSpacing, Z);
+ glVertex3f(PosX+W, Diff + Y+H + (H + Space)*Bands + ReflectionSpacing, Z);
+ glVertex3f(PosX+W, Diff + Y + (H + Space)*Bands + ReflectionSpacing, Z);
+ glColorRGB(Color, GetAlpha(Diff + H));
+ glEnd;
+ end;
+
+ glColorRGB(Color, Alpha);
+ end;
+
+
+ // Calc position of the bar's next block
+ if Direction then // Vertical bars
+ PosY := PosY - H - Space
+ else // Horizontal bars
+ PosX := PosX + W + Space;
+ end;
+
+ // Calc position of the next bar
+ if Direction then // Vertical bars
+ PosX := PosX + W + Space
+ else // Horizontal bars
+ PosY := PosY + H + Space;
+ end;
+
+
+ end;
+end;
+
+Procedure Tms_Equalizer.SetBands(Value: Byte);
+begin
+ SetLength(BandData, Value);
+end;
+
+Function Tms_Equalizer.GetBands: Byte;
+begin
+ Result := Length(BandData);
+end;
+
+Procedure Tms_Equalizer.SetSource(newSource: IAudioPlayback);
+begin
+ If (newSource <> nil) then
+ Source := newSource;
+end;
+
+
+
+end. \ No newline at end of file