Merge branch 'master' of git@github.com:SammyIAm/Moppy.git

This commit is contained in:
Sam Archer 2011-12-16 23:56:26 -08:00
commit 942f0b1656
7 changed files with 623 additions and 188 deletions

View File

@ -4,7 +4,7 @@ boolean firstRun = true; // Used for one-run-only stuffs;
//First pin being used for floppies, and the last pin. Used for looping over all pins.
const byte FIRST_PIN = 2;
const byte PIN_MAX = 9;
const byte PIN_MAX = 17;
#define RESOLUTION 40 //Microsecond resolution for notes
@ -21,28 +21,28 @@ are used for control, so only even numbers need a value here. 3.5" Floppies hav
half a position (use 158 and 98).
*/
byte MAX_POSITION[] = {
0,0,158,0,158,0,158,0,158,0};
0,0,158,0,158,0,158,0,158,0,158,0,158,0,158,0,158,0};
//Array to track the current position of each floppy head. (Only even indexes (i.e. 2,4,6...) are used)
byte currentPosition[] = {
0,0,0,0,0,0,0,0,0,0};
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/*Array to keep track of state of each pin. Even indexes track the control-pins for toggle purposes. Odd indexes
track direction-pins. LOW = forward, HIGH=reverse
*/
int currentState[] = {
0,0,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW
0,0,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW
};
//Current period assigned to each pin. 0 = off. Each period is of the length specified by the RESOLUTION
//variable above. i.e. A period of 10 is (RESOLUTION x 10) microseconds long.
unsigned int currentPeriod[] = {
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
//Current tick
unsigned int currentTick[] = {
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
@ -57,7 +57,15 @@ void setup(){
pinMode(6, OUTPUT); // Step control 3
pinMode(7, OUTPUT); // Direction 3
pinMode(8, OUTPUT); // Step control 4
pinMode(9, OUTPUT); // Direction 5
pinMode(9, OUTPUT); // Direction 4
pinMode(10, OUTPUT); // Step control 5
pinMode(11, OUTPUT); // Direction 5
pinMode(12, OUTPUT); // Step control 6
pinMode(13, OUTPUT); // Direction 6
pinMode(14, OUTPUT); // Step control 7
pinMode(15, OUTPUT); // Direction 7
pinMode(16, OUTPUT); // Step control 8
pinMode(17, OUTPUT); // Direction 8
Timer1.initialize(RESOLUTION); // Set up a timer at the defined resolution
Timer1.attachInterrupt(tick); // Attach the tick function
@ -127,6 +135,34 @@ void tick()
currentTick[8]=0;
}
}
if (currentPeriod[10]>0){
currentTick[10]++;
if (currentTick[10] >= currentPeriod[10]){
togglePin(10,11);
currentTick[10]=0;
}
}
if (currentPeriod[12]>0){
currentTick[12]++;
if (currentTick[12] >= currentPeriod[12]){
togglePin(12,13);
currentTick[12]=0;
}
}
if (currentPeriod[14]>0){
currentTick[14]++;
if (currentTick[14] >= currentPeriod[14]){
togglePin(14,15);
currentTick[14]=0;
}
}
if (currentPeriod[16]>0){
currentTick[16]++;
if (currentTick[16] >= currentPeriod[16]){
togglePin(16,17);
currentTick[16]=0;
}
}
}
@ -178,14 +214,33 @@ void reset(byte pin)
}
currentPosition[pin] = 0; // We're reset.
digitalWrite(pin+1,LOW);
currentPosition[pin+1] = LOW; // Ready to go forward.
currentPosition[pin+1] = 0; // Ready to go forward.
}
//Resets all the pins
void resetAll(){
// Old one-at-a-time reset
//for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
// reset(p);
//}
// New all-at-once reset
for (byte s=0;s<80;s++){ // For max drive's position
for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
digitalWrite(p+1,HIGH); // Go in reverse
digitalWrite(p,HIGH);
digitalWrite(p,LOW);
}
delay(5);
}
for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
reset(p);
}
currentPosition[p] = 0; // We're reset.
digitalWrite(p+1,LOW);
currentState[p+1] = 0; // Ready to go forward.
}
}

View File

@ -3,6 +3,10 @@
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="3"/>
<Property name="title" type="java.lang.String" value="MoppyDesk"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[480, 410]"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
@ -28,26 +32,14 @@
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="comSelectionMenu" min="-2" pref="79" max="-2" attributes="0"/>
<Component id="jTabbedPane1" alignment="0" max="32767" attributes="0"/>
<Component id="statusLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jSeparator1" alignment="1" pref="380" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="sequenceNameLabel" min="-2" max="-2" attributes="0"/>
<Component id="jSlider1" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="bpmLabel" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="30" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" attributes="0">
<Component id="startButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="stopButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="loadButton" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jSeparator1" alignment="1" pref="461" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="comSelectionMenu" min="-2" pref="79" max="-2" attributes="0"/>
</Group>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -56,26 +48,14 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="comSelectionMenu" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="107" max="32767" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="sequenceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="loadButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comSelectionMenu" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Component id="bpmLabel" min="-2" max="-2" attributes="0"/>
<Component id="jTabbedPane1" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="startButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="stopButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jSlider1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" pref="8" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="statusLabel" min="-2" max="-2" attributes="0"/>
@ -85,25 +65,6 @@
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="startButton">
<Properties>
<Property name="text" type="java.lang.String" value="Start"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="startButton" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="startButtonClicked"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="stopButton">
<Properties>
<Property name="text" type="java.lang.String" value="Stop/Reset"/>
<Property name="name" type="java.lang.String" value="stopButton" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="stopResetClicked"/>
</Events>
</Component>
<Component class="javax.swing.JComboBox" name="comSelectionMenu">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
@ -126,46 +87,276 @@
<Property name="name" type="java.lang.String" value="jSeparator1" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="loadButton">
<Container class="javax.swing.JTabbedPane" name="jTabbedPane1">
<Properties>
<Property name="text" type="java.lang.String" value="Load Sequence"/>
<Property name="name" type="java.lang.String" value="loadButton" noResource="true"/>
<Property name="name" type="java.lang.String" value="bridgePanel" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="loadSequence"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="sequenceNameLabel">
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Bridge" noResource="true"/>
</AccessibilityProperties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1">
<Properties>
<Property name="name" type="java.lang.String" value="sequencerPanel" noResource="true"/>
</Properties>
<Events>
<EventHandler event="componentHidden" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="seqTabHidden"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Sequencer">
<Property name="tabTitle" type="java.lang.String" value="Sequencer"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="sequencerControlsPanel" pref="436" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="jSeparator2" alignment="1" pref="456" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="connectSeqButton" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="373" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="connectSeqButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="jSeparator2" min="-2" pref="10" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="sequencerControlsPanel" min="-2" pref="187" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="sequencerControlsPanel">
<Properties>
<Property name="name" type="java.lang.String" value="sequencerControlsPanel" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[200, 200]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="sequenceNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="220" max="32767" attributes="0"/>
<Component id="loadButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="jSlider1" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="66" max="32767" attributes="0"/>
<Component id="startButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="stopButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="136" max="-2" attributes="0"/>
<Component id="bpmLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="sequenceNameLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="loadButton" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="100" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="stopButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="startButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jSlider1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="bpmLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="54" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="Current Sequence:"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="jLabel1" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="sequenceNameLabel">
<Properties>
<Property name="text" type="java.lang.String" value="&lt;None loaded&gt;"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="sequenceNameLabel" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="startButton">
<Properties>
<Property name="text" type="java.lang.String" value="Start"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="startButton" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="startButtonClicked"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="stopButton">
<Properties>
<Property name="text" type="java.lang.String" value="Stop/Reset"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="stopButton" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="stopResetClicked"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="loadButton">
<Properties>
<Property name="text" type="java.lang.String" value="Load Sequence"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="loadButton" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="loadSequence"/>
</Events>
</Component>
<Component class="javax.swing.JSlider" name="jSlider1">
<Properties>
<Property name="majorTickSpacing" type="int" value="10"/>
<Property name="maximum" type="int" value="210"/>
<Property name="minimum" type="int" value="20"/>
<Property name="paintTicks" type="boolean" value="true"/>
<Property name="value" type="int" value="120"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="jSlider1" noResource="true"/>
</Properties>
<Events>
<EventHandler event="mouseDragged" listener="java.awt.event.MouseMotionListener" parameters="java.awt.event.MouseEvent" handler="tempoSliderChanged"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="bpmLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="jSlider1.getValue() + &quot; bpm&quot;" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="bpmLabel" noResource="true"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="jSlider1.getValue() + &quot; bpm&quot;" type="code"/>
</Property>
</AccessibilityProperties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JSeparator" name="jSeparator2">
<Properties>
<Property name="name" type="java.lang.String" value="jSeparator2" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="connectSeqButton">
<Properties>
<Property name="text" type="java.lang.String" value="Connect"/>
<Property name="toolTipText" type="java.lang.String" value="Attempts to open selected COM port."/>
<Property name="name" type="java.lang.String" value="connectSequencerButton" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectSequencerPressed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jPanel2">
<Properties>
<Property name="name" type="java.lang.String" value="jPanel2" noResource="true"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Bridge">
<Property name="tabTitle" type="java.lang.String" value="Bridge"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="333" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="229" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" value="Coming soon... (sorry!)"/>
<Property name="name" type="java.lang.String" value="jLabel2" noResource="true"/>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" value="&lt;None loaded&gt;"/>
<Property name="name" type="java.lang.String" value="sequenceNameLabel" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="Current Sequence:"/>
<Property name="name" type="java.lang.String" value="jLabel1" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JSlider" name="jSlider1">
<Properties>
<Property name="majorTickSpacing" type="int" value="10"/>
<Property name="maximum" type="int" value="210"/>
<Property name="minimum" type="int" value="20"/>
<Property name="paintTicks" type="boolean" value="true"/>
<Property name="value" type="int" value="120"/>
<Property name="name" type="java.lang.String" value="jSlider1" noResource="true"/>
</Properties>
<Events>
<EventHandler event="mouseDragged" listener="java.awt.event.MouseMotionListener" parameters="java.awt.event.MouseEvent" handler="tempoSliderChanged"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="bpmLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="jSlider1.getValue() + &quot; bpm&quot;" type="code"/>
</Property>
<Property name="name" type="java.lang.String" value="bpmLabel" noResource="true"/>
<Property name="text" type="java.lang.String" value="Arduino Port:"/>
<Property name="name" type="java.lang.String" value="jLabel3" noResource="true"/>
</Properties>
</Component>
</SubComponents>

View File

@ -11,6 +11,7 @@
package moppydesk;
import gnu.io.CommPortIdentifier;
import java.awt.Component;
import java.io.File;
import java.util.Enumeration;
import java.util.logging.Level;
@ -25,11 +26,10 @@ import javax.swing.JSlider;
*
* @author Sam
*/
public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusConsumer{
public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusConsumer {
static String PREF_COM_PORT = "comPort";
static String PREF_LOADED_SEQ = "loadedSequencePath";
MoppyUI app;
Preferences prefs = Preferences.userNodeForPackage(MoppyUI.class);
final JFileChooser sequenceChooser = new JFileChooser();
@ -42,12 +42,11 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
updateComSelectionMenu();
initializeSequencer((String) comSelectionMenu.getSelectedItem());
String previouslyLoadedFile = prefs.get(PREF_LOADED_SEQ, null);
if (previouslyLoadedFile != null){
loadSequenceFile(new File(previouslyLoadedFile));
}
statusLabel.setText("Ready");
// initializeSequencer((String) comSelectionMenu.getSelectedItem());
//
//
}
private void updateComSelectionMenu() {
@ -75,6 +74,25 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
JOptionPane.showMessageDialog(rootPane, ex);
}
statusLabel.setText("Sequencer connected to " + comPort);
String previouslyLoadedFile = prefs.get(PREF_LOADED_SEQ, null);
if (previouslyLoadedFile != null) {
loadSequenceFile(new File(previouslyLoadedFile));
}
setSequenceControlsEnabled(true);
connectSeqButton.setText("Disconnect");
}
private void shutdownSequencer() {
statusLabel.setText("Closing sequencer...");
if (app.ms != null) {
app.ms.closeSequencer();
app.ms = null;
}
setSequenceControlsEnabled(false);
connectSeqButton.setText("Connect");
statusLabel.setText("Sequencer closed");
}
/** This method is called from within the constructor to
@ -86,41 +104,34 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
startButton = new javax.swing.JButton();
stopButton = new javax.swing.JButton();
comSelectionMenu = new javax.swing.JComboBox();
statusLabel = new javax.swing.JLabel();
jSeparator1 = new javax.swing.JSeparator();
loadButton = new javax.swing.JButton();
sequenceNameLabel = new javax.swing.JLabel();
jTabbedPane1 = new javax.swing.JTabbedPane();
jPanel1 = new javax.swing.JPanel();
sequencerControlsPanel = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
sequenceNameLabel = new javax.swing.JLabel();
startButton = new javax.swing.JButton();
stopButton = new javax.swing.JButton();
loadButton = new javax.swing.JButton();
jSlider1 = new javax.swing.JSlider();
bpmLabel = new javax.swing.JLabel();
jSeparator2 = new javax.swing.JSeparator();
connectSeqButton = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("MoppyDesk");
setMinimumSize(new java.awt.Dimension(480, 410));
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
MoppyMainWindow.this.windowClosing(evt);
}
});
startButton.setText("Start");
startButton.setEnabled(false);
startButton.setName("startButton"); // NOI18N
startButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startButtonClicked(evt);
}
});
stopButton.setText("Stop/Reset");
stopButton.setName("stopButton"); // NOI18N
stopButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
stopResetClicked(evt);
}
});
comSelectionMenu.setName("comSelectionMenu"); // NOI18N
comSelectionMenu.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -133,7 +144,46 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
jSeparator1.setName("jSeparator1"); // NOI18N
jTabbedPane1.setName("bridgePanel"); // NOI18N
jPanel1.setName("sequencerPanel"); // NOI18N
jPanel1.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentHidden(java.awt.event.ComponentEvent evt) {
seqTabHidden(evt);
}
});
sequencerControlsPanel.setName("sequencerControlsPanel"); // NOI18N
sequencerControlsPanel.setPreferredSize(new java.awt.Dimension(200, 200));
jLabel1.setText("Current Sequence:");
jLabel1.setEnabled(false);
jLabel1.setName("jLabel1"); // NOI18N
sequenceNameLabel.setText("<None loaded>");
sequenceNameLabel.setEnabled(false);
sequenceNameLabel.setName("sequenceNameLabel"); // NOI18N
startButton.setText("Start");
startButton.setEnabled(false);
startButton.setName("startButton"); // NOI18N
startButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startButtonClicked(evt);
}
});
stopButton.setText("Stop/Reset");
stopButton.setEnabled(false);
stopButton.setName("stopButton"); // NOI18N
stopButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
stopResetClicked(evt);
}
});
loadButton.setText("Load Sequence");
loadButton.setEnabled(false);
loadButton.setName("loadButton"); // NOI18N
loadButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -141,17 +191,12 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
}
});
sequenceNameLabel.setText("<None loaded>");
sequenceNameLabel.setName("sequenceNameLabel"); // NOI18N
jLabel1.setText("Current Sequence:");
jLabel1.setName("jLabel1"); // NOI18N
jSlider1.setMajorTickSpacing(10);
jSlider1.setMaximum(210);
jSlider1.setMinimum(20);
jSlider1.setPaintTicks(true);
jSlider1.setValue(120);
jSlider1.setEnabled(false);
jSlider1.setName("jSlider1"); // NOI18N
jSlider1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
@ -160,8 +205,127 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
});
bpmLabel.setText(jSlider1.getValue() + " bpm");
bpmLabel.setEnabled(false);
bpmLabel.setName("bpmLabel"); // NOI18N
javax.swing.GroupLayout sequencerControlsPanelLayout = new javax.swing.GroupLayout(sequencerControlsPanel);
sequencerControlsPanel.setLayout(sequencerControlsPanelLayout);
sequencerControlsPanelLayout.setHorizontalGroup(
sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(sequenceNameLabel)
.addComponent(jLabel1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 220, Short.MAX_VALUE)
.addComponent(loadButton))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, sequencerControlsPanelLayout.createSequentialGroup()
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 66, Short.MAX_VALUE)
.addComponent(startButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(stopButton))))
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addGap(136, 136, 136)
.addComponent(bpmLabel)))
.addContainerGap())
);
sequencerControlsPanelLayout.setVerticalGroup(
sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(sequencerControlsPanelLayout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sequenceNameLabel))
.addComponent(loadButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 100, Short.MAX_VALUE)
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(sequencerControlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(stopButton)
.addComponent(startButton))
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, sequencerControlsPanelLayout.createSequentialGroup()
.addComponent(bpmLabel)
.addGap(54, 54, 54))))
);
bpmLabel.getAccessibleContext().setAccessibleName(jSlider1.getValue() + " bpm");
jSeparator2.setName("jSeparator2"); // NOI18N
connectSeqButton.setText("Connect");
connectSeqButton.setToolTipText("Attempts to open selected COM port.");
connectSeqButton.setName("connectSequencerButton"); // NOI18N
connectSeqButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectSequencerPressed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(sequencerControlsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 436, Short.MAX_VALUE)
.addContainerGap())
.addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(connectSeqButton)
.addContainerGap(373, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(connectSeqButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sequencerControlsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
jTabbedPane1.addTab("Sequencer", jPanel1);
jPanel2.setName("jPanel2"); // NOI18N
jLabel2.setText("Coming soon... (sorry!)");
jLabel2.setName("jLabel2"); // NOI18N
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel2)
.addContainerGap(333, Short.MAX_VALUE))
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel2)
.addContainerGap(229, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Bridge", jPanel2);
jLabel3.setText("Arduino Port:");
jLabel3.setName("jLabel3"); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
@ -169,50 +333,33 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(comSelectionMenu, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jTabbedPane1)
.addComponent(statusLabel)
.addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(sequenceNameLabel)
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bpmLabel, javax.swing.GroupLayout.Alignment.TRAILING))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(startButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(stopButton))
.addComponent(loadButton)))
.addComponent(jLabel1))
.addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 461, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comSelectionMenu, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(comSelectionMenu, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 107, Short.MAX_VALUE)
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(sequenceNameLabel)
.addComponent(loadButton))
.addComponent(comSelectionMenu, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel3))
.addGap(18, 18, 18)
.addComponent(bpmLabel)
.addComponent(jTabbedPane1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(startButton)
.addComponent(stopButton))
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(11, 11, 11)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 8, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(statusLabel)
.addContainerGap())
);
jTabbedPane1.getAccessibleContext().setAccessibleName("Bridge"); // NOI18N
pack();
}// </editor-fold>//GEN-END:initComponents
@ -230,8 +377,8 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
private void loadSequence(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadSequence
String previouslyLoaded = prefs.get(PREF_LOADED_SEQ, null);
if (previouslyLoaded != null){
sequenceChooser.setCurrentDirectory(new File(previouslyLoaded));
if (previouslyLoaded != null) {
sequenceChooser.setCurrentDirectory(new File(previouslyLoaded));
}
int returnVal = sequenceChooser.showOpenDialog(this);
@ -242,21 +389,21 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
}
}//GEN-LAST:event_loadSequence
private void loadSequenceFile(File sequenceFile){
private void loadSequenceFile(File sequenceFile) {
try {
statusLabel.setText("Loading file...");
app.ms.loadFile(sequenceFile.getPath());
sequenceNameLabel.setText(sequenceFile.getName());
prefs.put(PREF_LOADED_SEQ, sequenceFile.getPath());
statusLabel.setText("Loaded " + sequenceFile.getName());
startButton.setEnabled(true);
} catch (Exception ex) {
Logger.getLogger(MoppyMainWindow.class.getName()).log(Level.SEVERE, null, ex);
statusLabel.setText("File loading error!");
JOptionPane.showMessageDialog(rootPane, ex);
}
statusLabel.setText("Loading file...");
app.ms.loadFile(sequenceFile.getPath());
sequenceNameLabel.setText(sequenceFile.getName());
prefs.put(PREF_LOADED_SEQ, sequenceFile.getPath());
statusLabel.setText("Loaded " + sequenceFile.getName());
startButton.setEnabled(true);
} catch (Exception ex) {
Logger.getLogger(MoppyMainWindow.class.getName()).log(Level.SEVERE, null, ex);
statusLabel.setText("File loading error!");
JOptionPane.showMessageDialog(rootPane, ex);
}
}
private void tempoSliderChanged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tempoSliderChanged
JSlider s = (JSlider) evt.getSource();
app.ms.setTempo(s.getValue());
@ -267,15 +414,35 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
JComboBox cb = (JComboBox) evt.getSource();
if (comboBoxReady) {
String comPort = (String) cb.getSelectedItem();
initializeSequencer(comPort);
shutdownSequencer();
prefs.put(PREF_COM_PORT, comPort);
}
}//GEN-LAST:event_comPortSelected
private void windowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_windowClosing
app.ms.closeSequencer();
if (app.ms != null){
app.ms.closeSequencer();
}
}//GEN-LAST:event_windowClosing
private void connectSequencerPressed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectSequencerPressed
if (connectSeqButton.getText().equals("Connect")) {
initializeSequencer((String) comSelectionMenu.getSelectedItem());
} else {
shutdownSequencer();
}
}//GEN-LAST:event_connectSequencerPressed
private void seqTabHidden(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_seqTabHidden
shutdownSequencer();
}//GEN-LAST:event_seqTabHidden
private void setSequenceControlsEnabled(boolean enabled) {
for (Component c : sequencerControlsPanel.getComponents()) {
c.setEnabled(enabled);
}
}
public void tempoChanged(int newTempo) {
jSlider1.setValue(newTempo);
bpmLabel.setText(newTempo + " bpm");
@ -283,14 +450,21 @@ public class MoppyMainWindow extends javax.swing.JFrame implements MoppyStatusCo
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel bpmLabel;
private javax.swing.JComboBox comSelectionMenu;
private javax.swing.JButton connectSeqButton;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JSeparator jSeparator2;
private javax.swing.JSlider jSlider1;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JButton loadButton;
private javax.swing.JLabel sequenceNameLabel;
private javax.swing.JPanel sequencerControlsPanel;
private javax.swing.JButton startButton;
private javax.swing.JLabel statusLabel;
private javax.swing.JButton stopButton;
// End of variables declaration//GEN-END:variables
}

View File

@ -47,7 +47,7 @@ public class MoppySequencer implements MetaEventListener{
Sequence sequence = MidiSystem.getSequence(new File(filePath));
sequencer.setSequence(sequence);
System.out.println("Loaded sequence with "+sequence.getTracks().length+" tracks.");
System.out.println("Loaded sequence with "+(sequence.getTracks().length-1)+" MIDI channels.");
}
public void startSequencer(){
@ -55,7 +55,9 @@ public class MoppySequencer implements MetaEventListener{
}
public void stopSequencer(){
sequencer.stop();
if (sequencer.isOpen()){
sequencer.stop();
}
mb.resetDrives();
}

View File

@ -16,7 +16,8 @@ public class MoppyUI extends SingleFrameApplication{
@Override
protected void startup() {
show(new MoppyMainWindow(this));
MoppyMainWindow mainWindow = new MoppyMainWindow(this);
show(mainWindow);
}
/**

View File

@ -21,18 +21,30 @@ I built Moppy using an Arduino UNO, though it should work just fine on most Ardu
Some pinout information can be found here: http://pinouts.ru/Storage/InternalDisk_pinout.shtml
Make sure you short the correct drive-select pin, or the drive won't respond to any input. Also, it's VERY IMPORTANT that your Arduino is grounded with the drives, or the drives will not register the pulses correctly.
Make sure you ground the correct drive-select pin, or the drive won't respond to any input. You can tell when you have the right drive selected, because the light on the front of the drive will come on. Also, it's VERY IMPORTANT that your Arduino is grounded with the drives, or the drives will not register the pulses correctly.
--CONFIGURAITON / USE--
Right now, there is no configuration for MoppyDesk (the Moppy Desktop application for controlling) and any variables need to be changed in the code itself. This will be improved in the future.
- Open up the code in NetBeans (or your favorite IDE) and run it. Alternatively, you can build the MoppyDesk.jar file and run that.
- Select the COM port that the Arduino is hooked up to from the "Arduino Port" drop-down. You will need to have this configured before you launch MoppyDesk.
- Click the "Connect" button to create a new Sequencer connected to the specified COM port.
- Click the "Load Sequence" button and select a suitable MIDI file (see below).
- Click "Start" to start playback (if all goes well).
- The Stop/Reset button will stop playback and reset the drives. Pressing "Start" again will resume from where the sequencer left off. You will need to reload the MIDI to start from the beginning.
Edit the code to select the appropriate COM port, and point to the correct MIDI file. Don't forget to edit the tempo in the code as well.
MIDI files should have one MIDI track for each controller pin on the Arduino. Track 1 will be sent to pin2, track 2 to pin4, &c.
--MIDI FILE INFORMATION / GUIDELINES--
Run the java code, cross your fingers, and enjoy!
- MIDI files should have one MIDI channel for each controller pin on the Arduino. Channel 1 will be sent to pin2, channel 2 to pin4, &c.
- Each drive can only play a single note at a time.
- The software will only attempt to play notes between C1 and B4. Floppy drives don't seem to respond well to notes outside of this range (especially higher).
- Generally shorter notes tend to sound better, as longer notes are marred by the read-heads changing directions repeatedly.
Cross your fingers, and enjoy!
--HELP/CONTRIBUTIONS--