/* * 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()); } }