src/main/java/com/soniccandle/Main.java
public class Main {

    private static GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    private static int screenWidth = gd.getDisplayMode().getWidth();
    private static int screenHeight = gd.getDisplayMode().getHeight();

    // set default video property constants
    public static final int DEFAULT_VIDEO_FRAME_RATE = 30;
    public static final int WIDTH = screenWidth;
    public static final int HEIGHT = screenHeight;

    // set variables for changing video properties
    private static int mainVideoFrameRate = DEFAULT_VIDEO_FRAME_RATE;
    private static int mainVideoWidth = WIDTH;
    private static int mainVideoHeight = HEIGHT;

    // set video properties methods
    public static void setDefaultVideoFrameRate(int mainVideoFrameRateNew) {
        mainVideoFrameRate = mainVideoFrameRateNew;
    }

    public static void setVideoWidth(int mainVideoWidthNew) {
        mainVideoWidth = mainVideoWidthNew;
    }

    public static void setVideoHeight(int mainVideoHeightNew) {
        mainVideoHeight = mainVideoHeightNew;
    }

    // get Video Properties Methods
    public static int getDefaultVideoFrameRate() {
        return (mainVideoFrameRate);
    }

    public static int getVideoWidth() {
        return (mainVideoWidth);
    }

    public static int getVideoHeight() {
        return (mainVideoHeight);
    }

    public static void main(String[] args) throws Exception {
        javax.swing.SwingUtilities.invokeLater(() -> {

            MainModel m = new MainModel();
            MainView v = new MainView();
            MainController c = new MainController();
            v.m = m;
            v.c = c;
            c.m = m;
            c.v = v;
            v.createAndShowGUI();
        });
    }
}
src/main/java/com/soniccandle/model/VideoOutputter.java
public abstract class VideoOutputter {

    public File audioFile;
    public File outputTo;
    public int frameRate;
    public int width;
    public int height;

    public VideoOutputter(File audioFile, File outputTo) {
        this.audioFile = audioFile;
        this.outputTo = outputTo;
    }

    public abstract void start() throws Exception;

    public abstract void addFrame(BufferedImage frame) throws Exception;

    public abstract void finish();

}
src/main/java/com/soniccandle/util/InputFilter.java
public class InputFilter extends FileFilter {

    // Accept all directories and all wav files.
    public boolean accept(File f) {
        if (f.isDirectory()) {
            return true;
        }

        String extension = Utils.getExtension(f);
        if (extension != null) {
            if (extension.equals(Utils.wav) | extension.equals(Utils.mp3)) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    public static boolean supportedType(File f) {
        if (f.isDirectory()) {
            return true;
        }

        String extension = Utils.getExtension(f);
        if (extension != null) {
            if (extension.equals(Utils.wav) | extension.equals(Utils.mp3)) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    // The description of this filter
    public String getDescription() {
        return "Audio Files (wav,mp3)";
    }
}
src/main/java/com/soniccandle/model/FastSimpleRenderer.java
public class FastSimpleRenderer extends SpectrumRenderer {

    public BufferedImage backgroundImage;
    public String barStyle;
    public Color barColor;

    public FastSimpleRenderer(File audioFile, int frameRate, int width, int height, File outputTo) throws IOException, WavFileException {
        super(audioFile, frameRate, width, height, outputTo);
    }

    @Override
    public BufferedImage renderVFrame(long vFrameNum) throws IOException, WavFileException {
        int framesRead;
        double[] buffer = new double[framesPerVFrame * numChannels];
        framesRead = wavFile.readFrames(buffer, framesPerVFrame);
        // not multiplied by number of channels; that's correct.
        if (framesRead == 0) {
            throw new RuntimeException("no frames were read for vFrameNum " + vFrameNum);
        }

        DoubleFFT_1D fft = new DoubleFFT_1D(framesPerVFrame);
        double[] fftResult;
        if (numChannels == 2) {
            StereoData stereo = Utils.splitChannels(buffer);
            fftResult = Utils.doubleAddZeros(stereo.left);
        } else if (numChannels == 1) {
            fftResult = Utils.doubleAddZeros(buffer);
        } else {
            throw new RuntimeException("only supporting 1 or 2 channels");
        }
        fft.complexForward(fftResult);
        System.out.println("array fftResult has this many entries: " + fftResult.length);

        int i = 0;
        int[] bars = new int[barCount];
        int pointsPerBar = Math.round(((framesPerVFrame * 2) / barCount) / 16);
        // divide by 2 because size of fft result is N/2. Rest of array is mirror of first half.
        // Divide by 4 because most of the frequencies we want are actually towards the far left, so this scales us over.

        System.out.println("total fftResult points: " + fftResult.length + "; pointsPerBar: " + pointsPerBar);

        while (i < barCount) {
            bars[i] = 0;
            // find the absolute-value peek in this region.
            int j = pointsPerBar * i;
            while (j < (pointsPerBar * (i + 1))) {
                double real = fftResult[j];
                double imaginary = fftResult[j + 1];
                double freqencyMagnatude = Math.sqrt((real * real) + (imaginary * imaginary));
                // frequency magnatude =sqrt (real * real + imag * imag)
                // http://stackoverflow.com/questions/6740545/need-help-understanding-fft-output
                freqencyMagnatude = freqencyMagnatude * 1.2; // scale up.
                if (Math.abs(fftResult[j]) > bars[i]) {
                    bars[i] = (int) Math.round(freqencyMagnatude);
                }
                j = j + 2; // real and imaginary part
            }
            i++;
        }

        // draw a spectrum
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = img.createGraphics();
        g.drawImage(backgroundImage, 0, 0, width, height, 0, 0, width, height, null);
        g.setColor(barColor);

        i = 0;
        int x;
        int half = height / 2;
        // int barWidth = 18;
        // Attempt to scale bars horizontally
        int barWidth = (width / barCount);
        int fftSize = (barCount * barWidth);
        int whiteSpace = width - fftSize;
        int offset = whiteSpace / 2;

        BarDrawer barDrawer = null;
        if (barStyle.equals(MainController.BAR_STYLE_THICK_BROCK)) {
            barDrawer = new ThickBlockBarDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_OUTLINE_BLOCK)) {
            barDrawer = new OutlinBlockBarDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_THIN)) {
            barDrawer = new ThinBarDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_ROUND_BLOCK)) {
            barDrawer = new RoundBlockBarDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_ROUND_OUTLINE)) {
            barDrawer = new RoundOutlineBarDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_DEPTH_BLOCK)) {
            barDrawer = new PopUpBlockDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_DEPTH_BLOCK2)) {
            barDrawer = new EtchedBlockDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_OVAL_FILLED)) {
            barDrawer = new OvalFilledDrawer(g, half, barWidth);
        } else if (barStyle.equals(MainController.BAR_STYLE_OVAL_OUTLINE)) {
            barDrawer = new OvalOutlineDrawer(g, half, barWidth);
        }

        while (i < barCount) {
            // x = 60+(i*barWidth);
            // Manage inset from left
            x = (barWidth / 2) + offset + (i * barWidth);
            // barwidth/2 keeps bars from clipping on left, offset centers the fft as best it can (you using integers made a perfect scale really hard)
            if (i == 1 && bars[i] == 0) {
                barDrawer.drawBar(((int) ((bars[0] + bars[2]) / 2.0)), x);
            } else {
                barDrawer.drawBar(bars[i], x);
            }
            i++;
        }
        return img;
    }
}
src/main/java/com/soniccandle/view/MainView.java
public class MainView {

    // color constants
    public static final Color BGCOLOR = new Color(70, 70, 70);
    public static final Color PANELCOLOR = new Color(45, 45, 45);
    public static final Color SCPROGRESS = new Color(40, 100, 130);
    public static final Color SCDARK = new Color(5, 5, 5);
    public static final Color SCWHITE = new Color(255, 255, 255);
    public static final Color SCGREY = new Color(91, 91, 91);
    public static final Color SCGREY_LT = SCGREY.brighter();
    public static final Color SC_GREY_BACK = new Color(64, 64, 64);

    public static final String BG_OTHER_IMAGE = "Other Image";
    public static final String BG_BUILT_IN_IMAGE = "Built-in Image";
    public static final String BG_FLAT_COLOR = "Flat Color";
    public static final String OUTPUT_SEQUENCE_TITLE = "Image Sequence (png) (select a folder for output)";

    public MainModel m;
    public MainController c;

    private ColorBox colorBox;

    public void createAndShowGUI() {
        // use Nimbus
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    customizeNimbus();
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
            System.out.println("Nimbus look and feel not found (MainView.java)");
            e.printStackTrace();
        }

        // Get screen size
        int screenWidth = Main.WIDTH;
        int screenHeight = Main.HEIGHT;

        // Create and set up the window.
        JFrame frame = new JFrame("Sonic Candle");
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Icon code
        Image icon;
        InputStream input = getClass().getResourceAsStream("/sonic-candle-icon.png");
        try {
            icon = ImageIO.read(input);
            frame.setIconImage(icon);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("Could not locate icon file!");
        }

        m.pane = frame.getContentPane();
        m.pane.setLayout(new GridBagLayout());
        m.pane.setBackground(BGCOLOR);

        GridBagConstraints topC = new GridBagConstraints();
        topC.fill = GridBagConstraints.HORIZONTAL;
        JLabel label;

        // Header (Image)
        JLabel headerLabel = getHeaderLabel();
        headerLabel.setPreferredSize(new Dimension(930, 54));
        topC.gridwidth = 2;
        topC.weightx = 1;
        topC.gridx = 0;
        topC.gridy = 0;
        m.pane.add(headerLabel, topC);

        topC.insets = new Insets(5, 5, 5, 5);

        // Video Properties panel
        JPanel vpPanel = new JPanel();
        vpPanel.setLayout(new GridBagLayout());
        vpPanel.setBorder(newTitledLabel("Video Properties"));
        vpPanel.setPreferredSize(new Dimension(460, 115));
        GridBagConstraints vpC = new GridBagConstraints();
        vpC.insets = new Insets(5, 5, 5, 5);
        vpC.fill = GridBagConstraints.BOTH;

        JLabel fps = newSCLabel("Frame Rate (Minimum 1):");
        vpC.gridwidth = 1;
        vpC.gridx = 0;
        vpC.gridy = 0;
        vpPanel.add(fps, vpC);

        m.videoSetFrameRate = newSCTextField(
                Integer.toString(Main.DEFAULT_VIDEO_FRAME_RATE), 120, 1, 10);
        m.videoSetFrameRate.setColumns(3);
        vpC.gridwidth = 1;
        vpC.gridx = 1;
        vpC.gridy = 0;
        vpPanel.add(m.videoSetFrameRate, vpC);

        JLabel frameWidth = newSCLabel("Video Width (Minimum 400):");
        vpC.gridwidth = 1;
        vpC.gridx = 0;
        vpC.gridy = 1;
        vpPanel.add(frameWidth, vpC);

        m.videoSetWidth = newSCTextField(Integer.toString(Main.WIDTH), 10000,
                400, 100);
        m.videoSetWidth.setColumns(3);
        vpPanel.add(m.videoSetWidth);
        vpC.gridwidth = 1;
        vpC.gridx = 1;
        vpC.gridy = 1;
        vpPanel.add(m.videoSetWidth, vpC);

        JLabel frameHeight = newSCLabel("Video Height (Minimum 300):");
        vpC.gridwidth = 1;
        vpC.gridx = 0;
        vpC.gridy = 2;
        vpPanel.add(frameHeight, vpC);

        m.videoSetHeight = newSCTextField(Integer.toString(Main.HEIGHT), 5000,
                300, 100);
        m.videoSetHeight.setColumns(3);
        vpPanel.add(m.videoSetHeight);
        vpC.gridwidth = 1;
        vpC.gridx = 1;
        vpC.gridy = 2;
        vpPanel.add(m.videoSetHeight, vpC);
        topC.gridwidth = 1;
        topC.weightx = 1;
        topC.gridx = 0;
        topC.gridy = 1;
        m.pane.add(vpPanel, topC);

        // IO panel
        JPanel inOutPanel = new JPanel();
        inOutPanel.setLayout(new GridBagLayout());
        inOutPanel.setBorder(newTitledLabel("Input and Output Files"));
        inOutPanel.setPreferredSize(new Dimension(460, 150));
        GridBagConstraints inOutC = new GridBagConstraints();
        inOutC.insets = new Insets(5, 5, 5, 5);
        inOutC.fill = GridBagConstraints.BOTH;

        m.setAudioButton = newSCButton("Set Input");
        m.setAudioButton.setActionCommand(MainController.SET_INPUT_WAV);
        m.setAudioButton.addActionListener(c);
        inOutC.weightx = 0.2;
        inOutC.gridx = 0;
        inOutC.gridy = 0;
        inOutPanel.add(m.setAudioButton, inOutC);

        m.audioFileNameLabel = newSCLabel("  (no file chosen)");
        m.audioFileNameLabel.setOpaque(true);
        inOutC.gridwidth = 1;
        inOutC.weightx = 0.8;
        inOutC.gridx = 1;
        inOutC.gridy = 0;
        inOutPanel.add(m.audioFileNameLabel, inOutC);

        label = new JLabel("  Output Format:");
        inOutC.weightx = 0.2;
        inOutC.gridx = 0;
        inOutC.gridy = 1;
        inOutPanel.add(label, inOutC);

        String[] outputMethods = {OUTPUT_SEQUENCE_TITLE};
        m.outputMethod = newSCComboBoxString(outputMethods);
        inOutC.weightx = 0.2;
        inOutC.gridwidth = 1;
        inOutC.gridx = 1;
        inOutC.gridy = 1;
        inOutPanel.add(m.outputMethod, inOutC);

        m.setOutputButton = newSCButton("Set Output");
        m.setOutputButton.setActionCommand(MainController.SET_OUTPUT_MP4);
        m.setOutputButton.addActionListener(c);
        m.setOutputButton.setEnabled(false);
        inOutC.weightx = 0.2;
        inOutC.gridx = 0;
        inOutC.gridy = 2;
        inOutPanel.add(m.setOutputButton, inOutC);

        m.outputToNameLabel = newSCLabel("  (no file or folder chosen)");
        m.outputToNameLabel.setOpaque(true);
        inOutC.weightx = 0.8;
        inOutC.gridx = 1;
        inOutC.gridy = 2;
        inOutPanel.add(m.outputToNameLabel, inOutC);

        topC.weightx = 1;
        topC.gridx = 0;
        topC.gridy = 2;
        m.pane.add(inOutPanel, topC);

        // Background Panel
        JPanel bgPanel = new JPanel();
        bgPanel.setLayout(new GridBagLayout());
        bgPanel.setBorder(newTitledLabel("Background Options"));
        bgPanel.setPreferredSize(new Dimension(460, 115));
        GridBagConstraints bgC = new GridBagConstraints();
        bgC.insets = new Insets(5, 5, 5, 5);
        bgC.fill = GridBagConstraints.BOTH;

        m.bgTypeGroup = new ButtonGroup();
        m.flatColorRb = newSCRadioButton(BG_FLAT_COLOR);
        m.flatColorRb.setActionCommand(BG_FLAT_COLOR);
        m.flatColorRb.addActionListener(c);
        m.flatColorRb.setSelected(true);
        m.bgTypeGroup.add(m.flatColorRb);
        bgC.gridx = 0;
        bgC.gridy = 0;
        bgPanel.add(m.flatColorRb, bgC);

        m.builtInImageRb = newSCRadioButton(BG_BUILT_IN_IMAGE);
        m.builtInImageRb.setActionCommand(BG_BUILT_IN_IMAGE);
        m.builtInImageRb.addActionListener(c);
        m.bgTypeGroup.add(m.builtInImageRb);
        bgC.gridx = 1;
        bgC.gridy = 0;
        bgPanel.add(m.builtInImageRb, bgC);

        m.otherImageRb = newSCRadioButton(BG_OTHER_IMAGE);
        m.otherImageRb.setActionCommand(BG_OTHER_IMAGE);
        m.otherImageRb.addActionListener(c);
        m.bgTypeGroup.add(m.otherImageRb);
        bgC.gridx = 2;
        bgC.gridy = 0;
        bgPanel.add(m.otherImageRb, bgC);

        m.bgColorPanel = new JPanel();
        label = newSCLabel("RGB values (0-255 for each color): ");
        m.bgColorPanel.add(label);

        m.bgColorRed = newSCTextField("" + BGCOLOR.getRed(), 255, 0, 5);
        m.bgColorRed.addKeyListener(new ColorFieldEar(m.bgColorRed));
        m.bgColorRed.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.bgColorRed.setColumns(3);
        m.bgColorPanel.add(m.bgColorRed);

        m.bgColorGreen = newSCTextField("" + BGCOLOR.getGreen(), 255, 0, 5);
        m.bgColorGreen.addKeyListener(new ColorFieldEar(m.bgColorGreen));
        m.bgColorGreen.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.bgColorGreen.setColumns(3);
        m.bgColorPanel.add(m.bgColorGreen);

        m.bgColorBlue = newSCTextField("" + BGCOLOR.getBlue(), 255, 0, 5);
        m.bgColorBlue.addKeyListener(new ColorFieldEar(m.bgColorBlue));
        m.bgColorBlue.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.bgColorBlue.setColumns(3);
        m.bgColorPanel.add(m.bgColorBlue);

        m.bgColorButton = new JButton("Color");

        m.bgColorButton.addActionListener(new BGColorPickerEar());

        m.bgColorPanel.add(m.bgColorButton);

        bgC.gridwidth = 3;
        bgC.gridx = 0;
        bgC.gridy = 1;
        bgPanel.add(m.bgColorPanel, bgC);

        m.bgBuiltInPanel = new JPanel();
        m.bgBuiltInPanel.setVisible(false);
        label = newSCLabel("Built-in Image(1920x1080): ");
        m.bgBuiltInPanel.add(label);

        String[] builtInImages = {"blue.png", "deep.png", "golden.png",
                "maroon.png", "red.png", "sea.png", "silver.png", "violet.png"};
        m.bgBuiltIn = newSCComboBoxString(builtInImages);
        m.bgBuiltInPanel.add(m.bgBuiltIn);

        bgC.gridwidth = 3;
        bgC.gridx = 0;
        bgC.gridy = 2;
        bgPanel.add(m.bgBuiltInPanel, bgC);

        m.bgOtherImagePanel = new JPanel();
        m.bgOtherImagePanel.setVisible(false);
        label = newSCLabel("Background Image, png or jpg");
        m.bgOtherImagePanel.add(label);

        m.setBgOtherImageButton = newSCButton("Set Image");
        m.setBgOtherImageButton
                .setActionCommand(MainController.SET_BG_OTHER_IMAGE);
        m.setBgOtherImageButton.addActionListener(c);
        m.bgOtherImagePanel.add(m.setBgOtherImageButton);

        m.bgImageNamelabel = new JLabel("  (no file chosen)  ");
        m.bgImageNamelabel.setOpaque(true);
        m.bgOtherImagePanel.add(m.bgImageNamelabel);

        bgC.gridwidth = 3;
        bgC.gridx = 0;
        bgC.gridy = 3;
        bgPanel.add(m.bgOtherImagePanel, bgC);

        topC.weightx = 1;
        topC.gridx = 1;
        topC.gridy = 1;
        m.pane.add(bgPanel, topC);

        // Bars panel - search makeBarsPanel
        JPanel barsPanel = makeBarsPanel();
        topC.weightx = 1;
        topC.gridx = 1;
        topC.gridy = 2;
        m.pane.add(barsPanel, topC);

        // Render panel
        JPanel renderPanel = new JPanel();
        renderPanel.setLayout(new GridBagLayout());
        renderPanel.setBorder(newTitledLabel("Render"));
        GridBagConstraints renderC = new GridBagConstraints();
        renderC.insets = new Insets(5, 5, 5, 5);
        renderC.fill = GridBagConstraints.BOTH;

        m.renderButton = newSCButton("Render");
        m.renderButton.setEnabled(false);
        m.renderButton.setActionCommand(MainController.RENDER);
        m.renderButton.addActionListener(c);
        renderC.gridwidth = 3;
        renderC.weightx = 1;
        renderC.gridx = 0;
        renderC.gridy = 0;
        renderPanel.add(m.renderButton, renderC);

        label = newSCLabel("Preview at Frame: ");
        renderC.gridwidth = 1;
        renderC.weightx = 0;
        renderC.gridx = 3;
        renderC.gridy = 0;
        renderPanel.add(label, renderC);

        m.previewFrame = newSCTextField("1", 100, 1, 1);
        m.previewFrame.setColumns(4);
        renderC.gridx = 4;
        renderC.gridy = 0;
        renderPanel.add(m.previewFrame, renderC);

        m.previewButton = newSCButton(" Preview ");
        m.previewButton.setActionCommand(MainController.PREVIEW);
        m.previewButton.addActionListener(c);
        renderC.gridx = 5;
        renderC.gridy = 0;
        renderPanel.add(m.previewButton, renderC);

        m.progressBar = new JProgressBar(SwingConstants.HORIZONTAL, 0, 100);
        m.progressBar.setValue(0);
        m.progressBar.setEnabled(false);
        m.progressBar.setMinimumSize(new Dimension(30, 30));
        renderC.weightx = 1;
        renderC.gridwidth = 6;
        renderC.gridx = 0;
        renderC.gridy = 1;
        renderPanel.add(m.progressBar, renderC);

        topC.gridwidth = 2;
        topC.weightx = 1;
        topC.gridx = 0;
        topC.gridy = 3;
        m.pane.add(renderPanel, topC);

        m.fcBG = new JFileChooser();
        m.fcBG.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        m.fcBG.setFileFilter(new ImageFilter());
        m.fcIn = new JFileChooser();
        m.fcIn.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        m.fcIn.setFileFilter(new InputFilter());
        m.fcOut = new JFileChooser();
        // TODO Make the file filters for output the object that decides what format to output
        m.fcOut.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        m.fcOut.setFileFilter(new OutputFilter());

        // Display the window.
        frame.pack();
        // Center frame on screen
        frame.setLocation((screenWidth / 2) - (frame.getWidth() / 2), (screenHeight / 2) - (frame.getHeight() / 2));
        frame.setVisible(true);
    }

    private JLabel getHeaderLabel() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        BufferedImage header;
        try {
            header = ImageIO.read(loader.getResourceAsStream("longheader.png"));
        } catch (Exception e) {
            throw new RuntimeException("header image not found");
        }
        JLabel headerLabel = new JLabel(new ImageIcon(header));
        return headerLabel;
    }

    private JPanel makeBarsPanel() {
        JPanel barsPanel = new JPanel();
        barsPanel.setLayout(new GridBagLayout());
        barsPanel
                .setBorder(newTitledLabel("Bar Customization (More options coming soon!)"));
        barsPanel.setPreferredSize(new Dimension(460, 150));
        GridBagConstraints barsC = new GridBagConstraints();
        barsC.insets = new Insets(5, 5, 5, 5);
        barsC.fill = GridBagConstraints.BOTH;

        JLabel label = newSCLabel("Bar Style:");
        barsC.gridwidth = 1;
        barsC.gridx = 0;
        barsC.gridy = 0;
        barsPanel.add(label, barsC);

        label = newSCLabel("Bar Color (RGBA 0-255) ");
        barsC.gridwidth = 1;
        barsC.gridx = 0;
        barsC.gridy = 1;
        barsPanel.add(label, barsC);

        JPanel panel = new JPanel();

        m.barColorRed = newSCTextField("" + SCGREY.getRed(), 255, 0, 5);
        m.barColorRed.addKeyListener(new ColorFieldEar(m.barColorRed));
        m.barColorRed.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.barColorRed.setColumns(3);
        panel.add(m.barColorRed);

        m.barColorGreen = newSCTextField("" + SCGREY.getGreen(), 255, 0, 5);
        m.barColorGreen.addKeyListener(new ColorFieldEar(m.barColorGreen));
        m.barColorGreen.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.barColorGreen.setColumns(3);
        panel.add(m.barColorGreen);

        m.barColorBlue = newSCTextField("" + SCGREY.getBlue(), 255, 0, 5);
        m.barColorBlue.addKeyListener(new ColorFieldEar(m.barColorBlue));
        m.barColorBlue.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.barColorBlue.setColumns(3);
        panel.add(m.barColorBlue);

        m.barAlpha = newSCTextField("" + SCGREY.getAlpha(), 255, 0, 5);
        m.barAlpha.addKeyListener(new ColorFieldEar(m.barAlpha));
        m.barAlpha.addMouseWheelListener(new ColorFieldMouseWheelEar());
        m.barAlpha.setColumns(3);
        panel.add(m.barAlpha);

        barsC.gridx = 1;
        barsC.gridy = 1;
        barsPanel.add(panel, barsC);

        label = newSCLabel("Color Picker: ");
        barsC.gridwidth = 1;
        barsC.gridx = 0;
        barsC.gridy = 2;
        barsPanel.add(label, barsC);

        JPanel panelColorPicker = new JPanel();

        m.barColorButton = new JButton("Color Picker");
        m.barColorButton.addActionListener(new BarColorPickerEar());

        panelColorPicker.add(m.barColorButton);

        colorBox = new ColorBox(m);

        panelColorPicker.add(colorBox);

        barsC.gridwidth = 1;
        barsC.gridx = 1;
        barsC.gridy = 2;
        barsPanel.add(panelColorPicker, barsC);

        String[] barStyles = {MainController.BAR_STYLE_THICK_BROCK,
                MainController.BAR_STYLE_OUTLINE_BLOCK,
                MainController.BAR_STYLE_THIN,
                MainController.BAR_STYLE_ROUND_BLOCK,
                MainController.BAR_STYLE_ROUND_OUTLINE,
                MainController.BAR_STYLE_DEPTH_BLOCK,
                MainController.BAR_STYLE_DEPTH_BLOCK2,
                MainController.BAR_STYLE_OVAL_FILLED,
                MainController.BAR_STYLE_OVAL_OUTLINE};
        m.barStyle = newSCComboBoxString(barStyles);
        barsC.gridx = 1;
        barsC.gridy = 0;
        barsPanel.add(m.barStyle, barsC);

        return barsPanel;
    }

    private TitledBorder newTitledLabel(String title) {

        javax.swing.border.Border normalBorder = (BorderFactory
                .createSoftBevelBorder(2));
        Font myFont = Utils.scFont(14, Font.BOLD);
        TitledBorder SCBorder = (BorderFactory.createTitledBorder(normalBorder,
                title, TitledBorder.LEFT, TitledBorder.ABOVE_TOP, myFont,
                Color.WHITE));

        return (SCBorder);
    }

    private JLabel newSCLabel(String text) {
        JLabel newSCLabel = new JLabel(text);
        return newSCLabel;

    }

    private JTextField newSCTextField(String text, int max, int min, int step) {
        JTextField newSCTextField = new JTextField(text);
        newSCTextField.addKeyListener(new TextFieldKeyEar(newSCTextField, max,
                min, step));
        newSCTextField.addMouseWheelListener(new TextFieldMouseWheelEar(
                newSCTextField, max, min, step));
        newSCTextField.setMinimumSize(new Dimension(46, 24));
        return (newSCTextField);
    }

    private JRadioButton newSCRadioButton(String text) {
        JRadioButton newSCRadioButton = new JRadioButton(text);
        return newSCRadioButton;
    }

    private JComboBox<String> newSCComboBoxString(String[] outputMethods) {
        JComboBox<String> newSCComboBox = new JComboBox<String>(outputMethods);
        return newSCComboBox;
    }

    private JButton newSCButton(String text) {
        JButton newSCButton = new JButton(text);
        return newSCButton;
    }

    private void customizeNimbus() {
        // General Changes
        // UIManager.put("defaultFont", Utils.scFont());
        UIManager.put("control", PANELCOLOR);
        UIManager.put("text", SCWHITE);
        UIManager.put("nimbusLightBackground", BGCOLOR);
        UIManager.put("nimbusFocus", SCGREY_LT);
        UIManager.put("nimbusBase", SCDARK);
        UIManager.put("nimbusOrange", SCPROGRESS);
        UIManager.put("nimbusBorder", SCDARK);
        UIManager.put("background", SC_GREY_BACK);
        UIManager.put("nimbusSelection", SCGREY);
        UIManager.put("textHighlight", SCGREY);
        UIManager.put("nimbusSelectionBackground", SCDARK);

    }

    // Action listeners (ears... hehe)

    private class BarColorPickerEar implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            Color color = new Color(Integer.parseInt(m.barColorRed.getText()),
                    Integer.parseInt(m.barColorGreen.getText()),
                    Integer.parseInt(m.barColorBlue.getText()),
                    Integer.parseInt(m.barAlpha.getText()));
            Color newColor = null;
            try {
                newColor = JColorChooser.showDialog(null, "Color Picker", color);
            } catch (Exception e1) {
                System.out.println("User didn't select a color");
                return;
            }
            if (newColor == null) {
                return;
            }
            m.barColorRed.setText("" + newColor.getRed());
            m.barColorBlue.setText("" + newColor.getBlue());
            m.barColorGreen.setText("" + newColor.getGreen());
            m.barAlpha.setText("" + newColor.getAlpha());

            colorBox.updateBox();
        }
    }

    private class BGColorPickerEar implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            Color color = new Color(Integer.parseInt(m.bgColorRed.getText()),
                    Integer.parseInt(m.bgColorGreen.getText()),
                    Integer.parseInt(m.bgColorBlue.getText()));
            Color newColor = null;
            try {
                newColor = JColorChooser.showDialog(null, "Color Picker", color);
            } catch (Exception e1) {
                System.out.println("User didn't select a color");
                return;
            }
            if (newColor == null) {
                return;
            }
            m.bgColorRed.setText("" + newColor.getRed());
            m.bgColorBlue.setText("" + newColor.getBlue());
            m.bgColorGreen.setText("" + newColor.getGreen());

            colorBox.updateBox();
        }
    }

    // MouseListeners

    private class TextFieldMouseWheelEar implements MouseWheelListener {

        private JTextField field;
        private int max;
        private int min;
        private int step;

        public TextFieldMouseWheelEar(JTextField field, int max, int min,
                                      int step) {
            this.field = field;
            this.max = max;
            this.min = min;
            this.step = step;
        }

        public void mouseWheelMoved(MouseWheelEvent e) {
            if (e.getWheelRotation() < 0) {
                int value = Integer.parseInt(field.getText());

                value += step;

                if (value <= max) {
                    field.setText("" + value);
                }
            } else if (e.getWheelRotation() > 0) {
                int value = Integer.parseInt(field.getText());

                value -= step;

                if (value >= min) {
                    field.setText("" + value);
                }
            }
        }

    }

    private class ColorFieldMouseWheelEar implements MouseWheelListener {

        public void mouseWheelMoved(MouseWheelEvent e) {
            colorBox.updateBox();
        }
    }

    // KeyListeners

    private class TextFieldKeyEar implements KeyListener {
        private JTextField field;
        private int max;
        private int min;
        private int step;

        public TextFieldKeyEar(JTextField field, int max, int min, int step) {
            this.field = field;
            this.max = max;
            this.min = min;
            this.step = step;
        }

        public void keyTyped(KeyEvent e) {
        }

        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_UP) {
                int value = Integer.parseInt(field.getText());

                value += step;

                if (value <= max) {
                    field.setText("" + value);
                }
            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                int value = Integer.parseInt(field.getText());

                value -= step;

                if (value >= min) {
                    field.setText("" + value);
                }
            }
        }

        public void keyReleased(KeyEvent e) {
        }

    }

    private class ColorFieldEar implements KeyListener {
        JTextField field;

        public ColorFieldEar(JTextField field) {
            this.field = field;
        }

        public void keyTyped(KeyEvent e) {

            if (!field.getText().equals("")) {

                int value;

                try {
                    value = Integer.parseInt(field.getText());
                } catch (Exception e1) {
                    value = 0;
                }

                if (value > 255) {
                    field.setText("" + 255);
                } else if (value < 0) {
                    field.setText("" + 0);
                }
            }
            colorBox.updateBox();
        }

        public void keyPressed(KeyEvent e) {
            colorBox.updateBox();
        }

        public void keyReleased(KeyEvent e) {
        }

    }
}
src/main/java/com/soniccandle/model/MainModel.java
public class MainModel {
    public JFileChooser fcBG;
    public JFileChooser fcIn;
    public JFileChooser fcOut;
    public Container pane;
    public JButton setAudioButton;
    public JLabel audioFileNameLabel;
    public File audioFile;
    public File outputTo;
    public JButton setOutputButton;
    public JLabel outputToNameLabel;
    public JButton renderButton;
    public JProgressBar progressBar;
    public JComboBox<String> outputMethod;
    public JTextField bgColorRed;
    public JTextField bgColorGreen;
    public JTextField bgColorBlue;
    public JPanel bgColorPanel;
    public JPanel bgBuiltInPanel;
    public JPanel bgOtherImagePanel;
    public File backgroundImageFile;
    public JLabel bgImageNamelabel;
    public JButton setBgOtherImageButton;
    public ButtonGroup bgTypeGroup;
    public JComboBox<String> bgBuiltIn;
    public JRadioButton flatColorRb;
    public JRadioButton builtInImageRb;
    public JRadioButton otherImageRb;
    public JComboBox<String> barStyle;
    public JTextField barColorRed;
    public JTextField barColorGreen;
    public JTextField barColorBlue;
    public JTextField videoSetFrameRate;
    public JTextField videoSetWidth;
    public JTextField videoSetHeight;
    public JTextField barAlpha;
    public JPanel videoProperties;
    public JTextField previewFrame;
    public JButton previewButton;
    public JButton detailsButton;
    public JButton bgColorButton;
    public JButton barColorButton;
}
src/main/java/com/soniccandle/util/Utils.java
public class Utils {
    // Audio file types
    public final static String wav = "wav";
    public final static String mp3 = "mp3";
    // Video file types
    public final static String mp4 = "mp4";
    // Image file types
    public final static String png = "png";
    public final static String jpg = "jpg";

    // Get file extension
    public static String getExtension(File f) {
        String ext = null;
        String s = f.getName();
        int i = s.lastIndexOf('.');

        if (i > 0 && i < s.length() - 1) {
            ext = s.substring(i + 1).toLowerCase();
        }
        return ext;
    }

    public static double[] doubleAddZeros(double[] input) {
        double[] output = new double[input.length * 2];
        int i = 0;
        int j = 0;
        while (i < input.length) {
            output[j] = input[i];
            j++;
            output[j] = 0; // complex component.
            j++;
            i++;
        }
        return output;
    }

    public static StereoData splitChannels(double[] input) {
        StereoData stereo = new StereoData();
        int halfLength = input.length / 2;
        stereo.left = new double[halfLength];
        stereo.right = new double[halfLength];
        int leftI = 0;
        int rightI = 0;
        int i = 0;
        boolean isOdd = false;
        while (i < input.length) {
            if (isOdd) {
                stereo.left[leftI] = input[i];
                leftI++;
            } else {
                stereo.right[rightI] = input[i];
                rightI++;
            }
            isOdd = !isOdd;
            i++;
        }
        return stereo;
    }

    public static void printMinMax(double[] buffer) throws IOException,
            WavFileException {
        double min = Double.MAX_VALUE;
        double max = Double.MIN_VALUE;
        int i = 0;
        while (i < buffer.length) {
            if (buffer[i] > max)
                max = buffer[i];
            if (buffer[i] < min)
                min = buffer[i];
            i++;
        }
        System.out.printf("Min: %f, Max: %f\n", min, max);
    }

    public static Font scFont(int size, int style) {
        InputStream in = Main.class
                .getResourceAsStream("/SourceSansPro-Regular.ttf");
        Font myFont = null;
        try {
            myFont = Font.createFont(Font.TRUETYPE_FONT, in).deriveFont(
                    style, size);
        } catch (FontFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (myFont == null) {
            myFont = new Font("Plain", style, 12);
        }
        return myFont;
    }
}
src/main/java/com/soniccandle/util/ImageFilter.java
public class ImageFilter extends FileFilter {

    // Accept all directories and all image files.
    public boolean accept(File f) {
        if (f.isDirectory()) {
            return true;
        }

        String extension = Utils.getExtension(f);
        if (extension != null) {
            if (extension.equals(Utils.png) || extension.equals(Utils.jpg)) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    public static boolean supportedType(File f) {
        if (f.isDirectory()) {
            return true;
        }

        String extension = Utils.getExtension(f);
        if (extension != null) {
            if (extension.equals(Utils.png) || extension.equals(Utils.jpg)) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    // The description of this filter
    public String getDescription() {
        return "Image Files (.png or .jpg)";
    }
}
src/main/java/com/soniccandle/model/RenderSettings.java
public class RenderSettings {
    public File audioFile;
    public File outputTo;
    public VideoOutputter outputter;
    public int videoFrameRate;
    public int width;
    public int height;
    public BufferedImage backgroundImage;

    public FastSimpleRenderer bakeSimpleRenderer(MainModel m) throws IOException, WavFileException {
        FastSimpleRenderer renderer = new FastSimpleRenderer(audioFile, videoFrameRate, width, height, outputTo);
        renderer.backgroundImage = backgroundImage;
        renderer.barStyle = (String) m.barStyle.getSelectedItem();
        renderer.barColor = new Color(
                Integer.parseInt(m.barColorRed.getText()),
                Integer.parseInt(m.barColorGreen.getText()),
                Integer.parseInt(m.barColorBlue.getText()),
                Integer.parseInt(m.barAlpha.getText()));
        renderer.outputter = outputter;
        return renderer;
    }

}
src/main/java/com/soniccandle/model/ImageSeqVideoOutputter.java
public class ImageSeqVideoOutputter extends VideoOutputter {

    public long frameNumber = 0;

    public ImageSeqVideoOutputter(File wavFile, File outputTo) {
        super(wavFile, outputTo);
    }

    @Override
    public void start() {
        frameNumber = 0;
    }

    @Override
    public void addFrame(BufferedImage frame) throws Exception {
        File outputfile = new File(outputTo, "frame_" + frameNumber + ".png");
        ImageIO.write(frame, "png", outputfile);
        frameNumber++;
    }

    @Override
    public void finish() {
    }

}


Question: package com.soniccandle.controller;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;//http://docs.oracle.com/javase/tutorial/2d/advanced/quality.html -- set in the specific bar drawing class
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javazoom.jl.converter.Converter;
import javazoom.jl.decoder.JavaLayerException;
import com.soniccandle.Main;
import com.soniccandle.model.FastSimpleRenderer;
import com.soniccandle.model.ImageSeqVideoOutputter;
import com.soniccandle.model.MainModel;
import com.soniccandle.model.RenderSettings;
import com.soniccandle.model.VideoOutputter;
import com.soniccandle.util.ImageFilter;
import com.soniccandle.util.InputFilter;
import com.soniccandle.util.Utils;
import com.soniccandle.view.MainView;





public class MainController implements ActionListener {

    public static final String SET_INPUT_WAV = "SET_INPUT_WAV";
    public static final String SET_OUTPUT_MP4 = "SET_OUTPUT_MP4";
    public static final String SET_BG_OTHER_IMAGE = "SET_BG_OTHER_IMAGE";
    public static final String RENDER = "RENDER";
    public static final String CANCEL_RENDER = "CANCEL_RENDER";
    public static final String BAR_STYLE_THICK_BROCK = "01 Thick Block";
    public static final String BAR_STYLE_OUTLINE_BLOCK = "02 Outline Block";
    public static final String BAR_STYLE_THIN = "03 Thin";
    public static final String BAR_STYLE_ROUND_BLOCK = "04 Round Filled";
    public static final String BAR_STYLE_ROUND_OUTLINE = "05 Round Outline";
    public static final String BAR_STYLE_DEPTH_BLOCK = "06 Pop Up Block";
    public static final String BAR_STYLE_DEPTH_BLOCK2 = "07 Etched Block";
    public static final String BAR_STYLE_OVAL_FILLED = "08 Oval Filled";
    public static final String BAR_STYLE_OVAL_OUTLINE = "09 Oval Outline";
    public static final String PREVIEW = "PREVIEW";
    public static final String DETAILS = "DETAILS";

    public static String audioType;

    File generatedWav;

    public MainModel m;
    public MainView v;
    private RenderSwingWorker renderSwingWorker;

    public void actionPerformed(ActionEvent e) {

        // set frame rate
        if (Integer.parseInt(m.videoSetFrameRate.getText()) > 0)// set minimum
        // to 1
        {
Answer:             Main.setDefaultVideoFrameRate(Integer.parseInt(m.videoSetFrameRate