/*
* EqualizerApplet.
*
* JavaZOOM : jlgui@javazoom.net
* http://www.javazoom.net
*
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jlgui.player.amp.equalizer.ui;
import java.applet.Applet;
import java.awt.AWTEvent;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javazoom.jlgui.player.amp.PlayerApplet;
import javazoom.jlgui.player.amp.skin.ActiveComponent;
import javazoom.jlgui.player.amp.skin.SkinLoader;
import javazoom.jlgui.player.amp.util.Config;
/**
* This class implements an equalizer UI.
*
* The equalizer consists of 32 band-pass filters.
* Each band of the equalizer can take on a fractional value between
* -1.0 and +1.0.
* At -1.0, the input signal is attenuated by 6dB, at +1.0 the signal is
* amplified by 6dB.
*/
public class EqualizerApplet extends Panel implements ActionListener
{
private Image imEqualizer;
private int WinWidth, WinHeight;
/*-- Slider Panel members --*/
private Image imSliders = null;
private boolean FirstSliderDrag = true;
private int YSliderDrag = 0;
private ActiveComponent[] acSlider = { null, null, null, null, null, null, null, null, null, null, null };
private Image[] sliderImage = { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null };
private int[][] sliderBarLocation = { { 21, 38 },
{78, 38 }, {96, 38 }, {114, 38 }, {132, 38 }, {150, 38 },
{168, 38 }, {186, 38 }, {204, 38 }, {222, 38 }, {240, 38 }};
private Image[] releasedSliderImage = { null };
private Image[] pressedSliderImage = { null };
private int minGain = 0;
private int maxGain = 100;
private int[] gainValue = { 50,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50 };
private int deltaSlider = 50;
private int[][] sliderLocation = { { 0, 0 },
{0, 0 }, {0, 0 }, {0, 0 }, {0, 0 }, {0, 0 },
{0, 0 }, {0, 0 }, {0, 0 }, {0, 0 }, {0, 0 }};
private int[] sliderBounds = { 0, 0 };
/*-- On/Off/Auto --*/
private ActiveComponent acOnOff, acAuto;
private Image[] releasedOAImage = { null, null };
private Image[] pressedOAImage = { null, null };
private int[] panelOALocation = { 15, 18, 39, 18 };
/*-- Presets --*/
private ActiveComponent acPresets;
private Image[] releasedPresetsImage = { null };
private Image[] pressedPresetsImage = { null };
private int[] panelPresetsLocation = { 217, 18 };
private Image offScreenImage;
private Graphics offScreenGraphics;
private int[] PRESET_NORMAL={50,50,50,50,50,50,50,50,50,50};
private int[] PRESET_CLASSICAL={50,50,50,50,50,50,70,70,70,76};
private int[] PRESET_CLUB={50,50,42,34,34,34,42,50,50,50};
private int[] PRESET_DANCE={26,34,46,50,50,66,70,70,50,50};
private int[] PRESET_FULLBASS={26,26,26,36,46,62,76,78,78,78};
private int[] PRESET_FULLBASSTREBLE={34,34,50,68,62,46,28,22,18,18};
private int[] PRESET_FULLTREBLE={78,78,78,62,42,24,8,8,8,8};
private int[] PRESET_LAPTOP={38,22,36,60,58,46,38,24,16,14};
private int[] PRESET_LIVE={66,50,40,36,34,34,40,42,42,42};
private int[] PRESET_PARTY={32,32,50,50,50,50,50,50,32,32};
private int[] PRESET_POP={56,38,32,30,38,54,56,56,54,54};
private int[] PRESET_REGGAE={48,48,50,66,48,34,34,48,48,48};
private int[] PRESET_ROCK={32,38,64,72,56,40,28,24,24,24};
private int[] PRESET_TECHNO={30,34,48,66,64,48,30,24,24,28};
private Config config = null;
private PlayerApplet player = null;
private Applet parent = null;
public static final int LINEARDIST = 1;
public static final int OVERDIST = 2;
private float[] bands = null;
private int[] eqgains = null;
private int eqdist = OVERDIST;
/**
* Constructor.
* @param parent
* @param player
* @param skl
* @param xPos
* @param yPos
* @param showit
*/
public EqualizerApplet(Applet parent, PlayerApplet player, SkinLoader skl, int xPos, int yPos, boolean showit)
{
super();
eqgains = new int[10];
setLayout(null);
this.parent = parent;
this.player = player;
// Config feature.
config = Config.getInstance();
imEqualizer = skl.getImage("eqmain.bmp");
WinWidth = 275;
WinHeight = 116;
offScreenImage = parent.createImage(WinWidth, WinHeight);
offScreenGraphics = offScreenImage.getGraphics();
offScreenGraphics.drawImage(imEqualizer, 0, 0, null);
imSliders = parent.createImage(208, 128);
Graphics g = imSliders.getGraphics();
g.drawImage(imEqualizer, 0, 0, 208, 128, 13, 164, 13 + 208, 164 + 128, null);
// Load last equalizer values.
int[] vals = config.getLastEqualizer();
if (vals != null)
{
for (int h=0;h<vals.length;h++)
{
gainValue[h] = vals[h];
}
}
setSliderPanel();
setOnOffAutoPanel();
setPresetsPanel();
// Popup menu on TitleBar
PopupMenu mainpopup = new PopupMenu("PresetsPopup");
String[] presets = {"Normal","Classical","Club","Dance","Full Bass",
"Full Bass & Treble","Full Treble","Laptop",
"Live","Party","Pop","Reggae","Rock","Techno"};
Font fnt = new Font("Dialog", Font.PLAIN, 11);
mainpopup.setFont(fnt);
for (int p=0;p<presets.length;p++)
{
MenuItem mi = new MenuItem(presets[p]);
mi.addActionListener(this);
mainpopup.add(mi);
}
acPresets.setPopup(mainpopup);
setSize(WinWidth, WinHeight);
setLocation(xPos, yPos);
//setBackground(Color.black);
show(showit); // changed to non-deprecated code (was show())
//pack();
}
/**
* Set sliders for equalizer.
*/
private void setSliderPanel()
{
releasedSliderImage[0] = parent.createImage(10, 11);
Graphics g = releasedSliderImage[0].getGraphics();
g.drawImage(imEqualizer, 0, 0, 10, 11, 0, 164, 0 + 10, 164 + 11, null);
pressedSliderImage[0] = parent.createImage(10, 11);
g = pressedSliderImage[0].getGraphics();
g.drawImage(imEqualizer, 0, 0, 10, 11, 0, 176, 0 + 10, 176 + 11, null);
for (int k = 0; k < sliderImage.length / 2; k++)
{
sliderImage[k] = parent.createImage(13, 63);
g = sliderImage[k].getGraphics();
g.drawImage(imSliders, 0, 0, 13, 63, k * 15, 0, k * 15 + 13, 0 + 63, null);
}
for (int k = 0; k < sliderImage.length / 2; k++)
{
sliderImage[k + (sliderImage.length / 2)] = parent.createImage(13, 63);
g = sliderImage[k + (sliderImage.length / 2)].getGraphics();
g.drawImage(imSliders, 0, 0, 13, 63, k * 15, 65, k * 15 + 13, 65 + 63, null);
}
// Setup sliders
for (int i = 0; i < acSlider.length; i++)
{
sliderLocation[i][0] = sliderBarLocation[i][0] + 1;
sliderLocation[i][1] = sliderBarLocation[i][1] + 1 + deltaSlider * gainValue[i] / maxGain;
sliderBounds[0] = sliderBarLocation[i][1] + 1;
sliderBounds[1] = sliderBarLocation[i][1] + 1 + deltaSlider;
acSlider[i] = new ActiveComponent(releasedSliderImage[0], pressedSliderImage[0], AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
acSlider[i].setLocation(sliderLocation[i][0], sliderLocation[i][1]);
add(acSlider[i]);
acSlider[i].setActionCommand("Slider");
acSlider[i].addActionListener(this);
offScreenGraphics.drawImage(sliderImage[(27) - ((int) Math.round(((double) gainValue[i] / (double) maxGain) * (sliderImage.length - 1)))], sliderBarLocation[i][0], sliderBarLocation[i][1], this);
}
}
/**
* Set On/Off and Auto checkbox.
*/
public void setOnOffAutoPanel()
{
// On/Off
int w = 24, h = 12;
releasedOAImage[0] = parent.createImage(w, h);
Graphics g = releasedOAImage[0].getGraphics();
g.drawImage(imEqualizer, 0, 0, w, h, 10, 119, 10 + w, 119 + h, null);
pressedOAImage[0] = parent.createImage(w, h);
g = pressedOAImage[0].getGraphics();
g.drawImage(imEqualizer, 0, 0, w, h, 69, 119, 69 + w, 119 + h, null);
acOnOff = new ActiveComponent(releasedOAImage[0], pressedOAImage[0], AWTEvent.MOUSE_EVENT_MASK, true, config.isEqualizerOn());
acOnOff.setLocation(panelOALocation[0], panelOALocation[1]);
add(acOnOff);
acOnOff.setActionCommand("OnOff");
acOnOff.addActionListener(this);
// Auto
w = 33;
h = 12;
releasedOAImage[1] = parent.createImage(w, h);
g = releasedOAImage[1].getGraphics();
g.drawImage(imEqualizer, 0, 0, w, h, 34, 119, 34 + w, 119 + h, null);
pressedOAImage[1] = parent.createImage(w, h);
g = pressedOAImage[1].getGraphics();
g.drawImage(imEqualizer, 0, 0, w, h, 93, 119, 93 + w, 119 + h, null);
acAuto = new ActiveComponent(releasedOAImage[1], pressedOAImage[1], AWTEvent.MOUSE_EVENT_MASK, true, config.isEqualizerAuto());
acAuto.setLocation(panelOALocation[2], panelOALocation[3]);
add(acAuto);
acAuto.setActionCommand("Auto");
acAuto.addActionListener(this);
}
/**
* Set presets button.
*/
public void setPresetsPanel()
{
int w = 43, h = 12;
releasedPresetsImage[0] = parent.createImage(w, h);
Graphics g = releasedPresetsImage[0].getGraphics();
g.drawImage(imEqualizer, 0, 0, w, h, 224, 164, 224 + w, 164 + h, null);
pressedPresetsImage[0] = parent.createImage(w, h);
g = pressedPresetsImage[0].getGraphics();
g.drawImage(imEqualizer, 0, 0, w, h, 224, 176, 224 + w, 176 + h, null);
acPresets = new ActiveComponent(releasedPresetsImage[0], pressedPresetsImage[0], AWTEvent.MOUSE_EVENT_MASK);
acPresets.setLocation(panelPresetsLocation[0], panelPresetsLocation[1]);
add(acPresets);
acPresets.setActionCommand("Presets");
acPresets.addActionListener(this);
}
public void paint(Graphics g)
{
if (offScreenImage != null)
g.drawImage(offScreenImage, 0, 0, this);
}
public void update(Graphics g)
{
paint(g);
}
/**
* Set bands array for equalizer.
* @param bands
*/
public void setBands(float[] bands)
{
this.bands = bands;
}
/**
* Apply equalizer function.
* @param gains
* @param min
* @param max
*/
public void updateBands(int[] gains, int min, int max)
{
if ((gains != null) && (bands != null))
{
int j=0;
float gvalj= (gains[j]*2.0f/(max-min)*1.0f) - 1.0f;
float gvalj1 = (gains[j+1]*2.0f/(max-min)*1.0f) - 1.0f;
// Linear distribution : 10 values => 32 values.
if (eqdist == LINEARDIST)
{
float a = (gvalj1 - gvalj)*1.0f;
float b = gvalj*1.0f - (gvalj1 - gvalj)*j;
// x=s*x'
float s = (gains.length-1)*1.0f/(bands.length-1)*1.0f;
for (int i=0;i<bands.length;i++)
{
float ind = s*i;
if (ind > (j+1))
{
j++;
gvalj= (gains[j]*2.0f/(max-min)*1.0f) - 1.0f;
gvalj1 = (gains[j+1]*2.0f/(max-min)*1.0f) - 1.0f;
a = (gvalj1 - gvalj)*1.0f;
b = gvalj*1.0f - (gvalj1 - gvalj)*j;
}
// a*x+b
bands[i] = a*i*1.0f*s + b;
//System.err.println("Lin : i="+i+" Bands["+i+"]="+bands[i]+" a="+a+" b="+b);
}
}
// Over distribution : 10 values => 10 first value of 32 values.
else if (eqdist == OVERDIST)
{
for (int i=0;i<gains.length;i++)
{
bands[i] = (gains[i]*2.0f/(max-min)*1.0f) - 1.0f;
//System.err.println("Over : i="+i+" Bands["+i+"]="+bands[i]);
}
}
}
}
public void actionPerformed(ActionEvent e)
{
String cmd = e.getActionCommand();
/*-------------------*/
/*-- ON/OFF --*/
/*-------------------*/
if (e.getActionCommand().equals("OnOff"))
{
if (acOnOff.getCheckboxState())
{
config.setEqualizerOn(true);
}
else
{
config.setEqualizerOn(false);
}
synchronizeEqualizer();
}
/*-------------------*/
/*-- Auto --*/
/*-------------------*/
else if (e.getActionCommand().equals("Auto"))
{
if (acAuto.getCheckboxState())
{
config.setEqualizerAuto(true);
}
else
{
config.setEqualizerAuto(false);
}
}
/*-------------------*/
/*-- Presets --*/
/*-------------------*/
else if (e.getActionCommand().equals("Presets"))
{
if ((acPresets.getMouseButton() & MouseEvent.BUTTON1_MASK) == MouseEvent.BUTTON1_MASK)
{
MouseEvent me = new MouseEvent(acPresets, e.getID(), 0, e.getModifiers(), acPresets.getMouseX(), acPresets.getMouseY(), 1, true);
acPresets.processMouseEvent(me);
}
}
else if (e.getActionCommand().equals("Normal"))
{
updateSliders(PRESET_NORMAL);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Classical"))
{
updateSliders(PRESET_CLASSICAL);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Club"))
{
updateSliders(PRESET_CLUB);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Dance"))
{
updateSliders(PRESET_DANCE);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Full Bass"))
{
updateSliders(PRESET_FULLBASS);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Full Bass & Treble"))
{
updateSliders(PRESET_FULLBASSTREBLE);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Full Treble"))
{
updateSliders(PRESET_FULLTREBLE);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Laptop"))
{
updateSliders(PRESET_LAPTOP);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Live"))
{
updateSliders(PRESET_LIVE);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Party"))
{
updateSliders(PRESET_PARTY);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Pop"))
{
updateSliders(PRESET_POP);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Reggae"))
{
updateSliders(PRESET_REGGAE);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Rock"))
{
updateSliders(PRESET_ROCK);
synchronizeEqualizer();
}
else if (e.getActionCommand().equals("Techno"))
{
updateSliders(PRESET_TECHNO);
synchronizeEqualizer();
}
/*------------------------------------*/
/*-- Interact on Sliders --*/
/*------------------------------------*/
else if (e.getActionCommand().equals("Slider"))
{
ActiveComponent src = (ActiveComponent) e.getSource();
int i = 0;
for (i = 0; i < acSlider.length; i++)
{
if (acSlider[i] == src) break;
}
if (acSlider[i].isMousePressed() == false)
{
FirstSliderDrag = true;
repaint();
}
else
{
int DeltaY = 0;
if (FirstSliderDrag == false)
{
DeltaY = acSlider[i].getMouseY() - YSliderDrag;
YSliderDrag = acSlider[i].getMouseY() - DeltaY;
if (sliderLocation[i][1] + DeltaY < sliderBounds[0]) sliderLocation[i][1] = sliderBounds[0];
else if (sliderLocation[i][1] + DeltaY > sliderBounds[1]) sliderLocation[i][1] = sliderBounds[1];
else sliderLocation[i][1] = sliderLocation[i][1] + DeltaY;
acSlider[i].setLocation(sliderLocation[i][0], sliderLocation[i][1]);
double a = (maxGain - minGain) / (sliderBounds[1] - sliderBounds[0]);
gainValue[i] = (int) (a * (sliderLocation[i][1] - sliderBounds[0]) + minGain);
offScreenGraphics.drawImage(sliderImage[(27) - ((int) Math.round(((double) gainValue[i] / (double) maxGain) * (sliderImage.length - 1)))], sliderBarLocation[i][0], sliderBarLocation[i][1], this);
//System.out.println("Gain:"+gainValue[i]);
}
else
{
FirstSliderDrag = false;
YSliderDrag = acSlider[i].getMouseY();
}
}
// Apply equalizer values.
synchronizeEqualizer();
}
}
/**
* Update sliders from gains array.
* @param gains
*/
public void updateSliders(int[] gains)
{
if (gains != null)
{
for (int i=0;i<gains.length;i++)
{
gainValue[i+1]=gains[i];
sliderLocation[i+1][1] = sliderBarLocation[i+1][1] + 1 + deltaSlider * gainValue[i+1] / maxGain;
acSlider[i+1].setLocation(sliderLocation[i+1][0], sliderLocation[i+1][1]);
offScreenGraphics.drawImage(sliderImage[(27) - ((int) Math.round(((double) gainValue[i+1] / (double) maxGain) * (sliderImage.length - 1)))], sliderBarLocation[i+1][0], sliderBarLocation[i+1][1], this);
}
repaint();
}
}
public void synchronizeEqualizer()
{
config.setLastEqualizer(gainValue);
if (config.isEqualizerOn())
{
for (int j=0;j<eqgains.length;j++)
{
eqgains[j] = -gainValue[j+1] + maxGain;
}
updateBands(eqgains, minGain, maxGain);
}
else
{
for (int j=0;j<eqgains.length;j++)
{
eqgains[j] = (maxGain-minGain)/2;
}
updateBands(eqgains, minGain, maxGain);
}
}
/**
* @return
*/
public int getEqdist()
{
return eqdist;
}
/**
* @param i
*/
public void setEqdist(int i)
{
eqdist = i;
}
/**
* Simulates "On/Off" selection.
*/
public void pressOnOff()
{
acOnOff.fireEvent();
}
/**
* Simulates "Auto" selection.
*/
public void pressAuto()
{
acAuto.fireEvent();
}
/**
* Force display of all components.
*/
public void displayAll()
{
acAuto.display();
acOnOff.display();
acPresets.display();
if (acSlider != null)
{
for (int i=0;i<acSlider.length;i++)
{
acSlider[i].display();
}
}
paintAll(getGraphics());
}
}