org.monome.pages.AbletonClipSkipperPage.java Source code

Java tutorial

Introduction

Here is the source code for org.monome.pages.AbletonClipSkipperPage.java

Source

/*
 *  AbletonClipSkipperPage.java
 * 
 *  Copyright (c) 2008, Tom Dinchak
 * 
 *  This file is part of Pages.
 *
 *  Pages 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.
 *
 *  Pages 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 Pages; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

package org.monome.pages;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.apache.commons.lang.StringEscapeUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * The Template page, a good starting point for creating your own pages.  
 * Usage information is available at:
 * 
 * http://code.google.com/p/monome-pages/wiki/ExternalApplicationPage
 * 
 * @author Tom Dinchak
 *
 */
public class AbletonClipSkipperPage implements Page, ActionListener {

    /**
     * The MonomeConfiguration this page belongs to
     */
    private MonomeConfiguration monome;

    private static final int NUM_CLIPS = 1000;
    private static final int NUM_TRACKS = 50;

    /**
     * This page's index (page number) 
     */
    private int index;

    /**
     * This page's GUI / configuration panel 
     */
    private JPanel panel;

    /**
     * The name of the selected MIDI output device 
     */
    private String midiDeviceName;

    private int[] trackJump = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };

    private float[] trackMovement = new float[16];

    private int[] jumpClip = new int[16];

    /**
     * The name of the page 
     */
    private String pageName = "Ableton Clip Skipper";
    private JLabel pageNameLBL;
    private JButton refreshButton = new JButton();

    private AbletonState abletonState;

    /**
     * @param monome The MonomeConfiguration this page belongs to
     * @param index The index of this page (the page number)
     */
    public AbletonClipSkipperPage(MonomeConfiguration monome, int index) {
        this.monome = monome;
        this.index = index;
        this.monome.configuration.initAbleton();
        this.abletonState = this.monome.configuration.abletonState;
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Add MIDI Output")) {
            String[] midiOutOptions = this.monome.getMidiOutOptions();
            String deviceName = (String) JOptionPane.showInputDialog(this.monome, "Choose a MIDI Output to add",
                    "Add MIDI Output", JOptionPane.PLAIN_MESSAGE, null, midiOutOptions, "");

            if (deviceName == null) {
                return;
            }
            this.addMidiOutDevice(deviceName);
        }

        if (e.getActionCommand().equals("Refresh from Ableton")) {
            this.refreshAbleton();
        }
    }

    public void refreshAbleton() {
        this.monome.configuration.getAbletonControl().refreshAbleton();
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#addMidiOutDevice(java.lang.String)
     */
    public void addMidiOutDevice(String deviceName) {
        return;
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#getName()
     */
    public String getName() {
        return pageName;
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#setName()
     */
    public void setName(String name) {
        this.pageName = name;
        this.pageNameLBL.setText("Page " + (this.index + 1) + ": " + pageName);
        this.monome.setJMenuBar(this.monome.createMenuBar());
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#getPanel()
     */
    public JPanel getPanel() {
        if (this.panel != null) {
            return this.panel;
        }

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.setPreferredSize(new java.awt.Dimension(464, 156));

        pageNameLBL = new JLabel("Page " + (this.index + 1) + ": Ableton Clip Skipper");
        panel.add(pageNameLBL);

        refreshButton.setText("Refresh from Ableton");
        refreshButton.addActionListener(this);
        panel.add(refreshButton);

        this.panel = panel;
        return panel;
    }

    public void updateClipState(int track, int clip, int state, float length) {
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#handlePress(int, int, int)
     */
    public void handlePress(int x, int y, int value) {
        AbletonTrack track = this.abletonState.getTrack(y);
        if (track != null) {
            for (int clipNum = 0; clipNum < track.getClips().size(); clipNum++) {
                AbletonClip clip = track.getClip(clipNum);
                if (clip.getState() == AbletonClip.STATE_PLAYING) {
                    int xPos = (int) ((float) (clip.getPosition() / clip.getLength()) * (float) this.monome.sizeX);
                    int xDiff = x - xPos;
                    float beatsPerButton = (float) (clip.getLength() / (float) this.monome.sizeX);
                    float movement = xDiff * beatsPerButton;
                    this.trackJump[y] = y;
                    this.trackMovement[y] = movement;
                    this.jumpClip[y] = clipNum;
                    ArrayList<Integer> rowArgs = new ArrayList<Integer>();
                    rowArgs.add(y);
                    rowArgs.add(0);
                    rowArgs.add(0);
                    this.monome.led_row(rowArgs, this.index);
                }
            }
        }
    }

    public void trackJump(int track, float amount) {
        this.monome.configuration.getAbletonControl().trackJump(track, amount);
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#handleReset()
     */
    public void handleReset() {
        for (int y = 0; y < this.monome.sizeY; y++) {
            ArrayList<Integer> rowArgs = new ArrayList<Integer>();
            rowArgs.add(y);
            rowArgs.add(0);
            rowArgs.add(0);
            this.monome.led_row(rowArgs, this.index);
            AbletonTrack track = this.abletonState.getTrack(y);
            if (track != null) {
                for (int clipNum = 0; clipNum < track.getClips().size(); clipNum++) {
                    AbletonClip clip = track.getClip(clipNum);
                    if (clip != null) {
                        clip.setPosition(0.0f);
                    }
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#handleTick()
     */
    public void handleTick() {
        for (int y = 0; y < this.monome.sizeY; y++) {
            AbletonTrack track = this.abletonState.getTrack(y);
            if (track != null) {
                for (int clipNum = 0; clipNum < track.getClips().size(); clipNum++) {
                    AbletonClip clip = track.getClip(clipNum);
                    if (clip != null) {
                        if (clip.getState() == AbletonClip.STATE_PLAYING) {
                            clip.setPosition(clip.getPosition() + (4.0f / 96.0f));
                        } else {
                            clip.setPosition(0.0f);
                        }
                        if (this.trackJump[y] != -1) {
                            clip.setPosition(clip.getPosition() + this.trackMovement[y]);
                            this.trackJump(this.trackJump[y], this.trackMovement[y]);
                            this.trackJump[y] = -1;
                        }
                        if (clip.getPosition() > clip.getLength()) {
                            clip.setPosition(clip.getPosition() - clip.getLength());
                        }
                    }
                }
            }
        }
        this.redrawMonome();
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#redrawMonome()
     */
    public void redrawMonome() {
        for (int y = 0; y < this.monome.sizeY; y++) {
            AbletonTrack track = this.abletonState.getTrack(y);
            if (track != null) {
                int foundPlayingClip = 0;
                for (int clipNum = 0; clipNum < track.getClips().size(); clipNum++) {
                    AbletonClip clip = track.getClip(clipNum);
                    if (clip != null) {
                        if (clip.getState() == AbletonClip.STATE_PLAYING) {
                            foundPlayingClip = 1;
                            int x = (int) ((float) (clip.getPosition() / clip.getLength())
                                    * (float) this.monome.sizeX);
                            for (int leds = 0; leds < this.monome.sizeX; leds++) {
                                if (leds == x) {
                                    this.monome.led(leds, y, 1, this.index);
                                } else {
                                    this.monome.led(leds, y, 0, this.index);
                                }
                            }
                        }
                    } else {
                        ArrayList<Integer> rowParams = new ArrayList<Integer>();
                        rowParams.add(y);
                        rowParams.add(0);
                        rowParams.add(0);
                        this.monome.led_row(rowParams, index);
                    }
                }
                if (foundPlayingClip == 0) {
                    for (int x = 0; x < this.monome.sizeX; x++) {
                        this.monome.led(x, y, 0, this.index);
                    }
                }
            } else {
                ArrayList<Integer> rowParams = new ArrayList<Integer>();
                rowParams.add(y);
                rowParams.add(0);
                rowParams.add(0);
                this.monome.led_row(rowParams, index);
            }
        }
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#send(javax.sound.midi.MidiMessage, long)
     */
    public void send(MidiMessage message, long timeStamp) {
        // TODO add code to handle midi input from midi clock source (can be any type of input)
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#toXml()
     */
    public String toXml() {
        String xml = "";
        xml += "      <name>Ableton Clip Skipper</name>\n";
        xml += "      <pageName>" + this.pageName + "</pageName>\n";
        xml += "      <selectedmidioutport>" + StringEscapeUtils.escapeXml(this.midiDeviceName)
                + "</selectedmidioutport>\n";
        return xml;
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#getCacheDisabled()
     */
    public boolean getCacheDisabled() {
        return false;
    }

    /* (non-Javadoc)
     * @see org.monome.pages.Page#destroyPage()
     */
    public void destroyPage() {
        return;
    }

    public void clearPanel() {
        this.panel = null;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public void handleADC(int adcNum, float value) {
        // TODO Auto-generated method stub

    }

    public void handleADC(float x, float y) {
        // TODO Auto-generated method stub

    }

    public boolean isTiltPage() {
        // TODO Auto-generated method stub
        return false;
    }

    public ADCOptions getAdcOptions() {
        // TODO Auto-generated method stub
        return null;
    }

    public void setAdcOptions(ADCOptions options) {
        // TODO Auto-generated method stub

    }

    public void configure(Element pageElement) {
        NodeList nameNL = pageElement.getElementsByTagName("pageName");
        Element el = (Element) nameNL.item(0);
        if (el != null) {
            NodeList nl = el.getChildNodes();
            String name = ((Node) nl.item(0)).getNodeValue();
            this.setName(name);
        }
    }
}