Saving a List of MIDI files
Hey all,
This seems to be a bit over my head. What I have here is code from AJ (aka, MrSolidSnake745) adapted from Sammy1Am's moppy software (https://github.com/SammyIAm/Moppy). AJ made code that would play MIDIs in a playlist going in the order that the user loaded them. The problem is, once the playlist is done, in order to play that same playlist again, a user would have to reload each song all over again. I have a playlist of 30 songs xP. Here's what he did:
package moppydesk;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.*;
/**
*
* @author AJ
*/
public class MoppySequencerMultiple implements MetaEventListener{
MoppyBridge mb;
MoppyPlayer mp;
Sequencer sequencer;
ArrayList<MoppyStatusConsumer> listeners = new ArrayList<MoppyStatusConsumer>(1);
//Added to enable playlists and repeating
List<File> playlist = new ArrayList<File>();
Boolean playlistFlag = false;
Boolean resetFlag = false;
Boolean repeatFlag = false;
....
public void meta(MetaMessage meta) {
if (meta.getType() == 81){
int uSecondsPerQN = 0;
uSecondsPerQN |= meta.getData()[0] & 0xFF;
uSecondsPerQN <<= 8;
uSecondsPerQN |= meta.getData()[1] & 0xFF;
uSecondsPerQN <<= 8;
uSecondsPerQN |= meta.getData()[2] & 0xFF;
LastBPM = 60000000/uSecondsPerQN;
for (Sequencer c : Sequencers){c.setTempoInBPM(LastBPM);}
for (MoppyStatusConsumer c : listeners){
c.tempoChanged(LastBPM);
}
System.out.println("Tempo changed to: " + LastBPM);
}
else if (meta.getType() == 47) { //If condition to catch end of MIDI file event
LastBPM = 0;
if (playlistFlag && !(playlist.isEmpty())) {
playlist.remove(0);
try {
if(resetFlag && !(playlist.isEmpty())){Thread.sleep(2000);resetDri ves();} //Pause for 2 seconds and reset the drives at the end of a song
Thread.sleep(3000);loadFile(playlist.get(0).getPat h());startSequencers(); //3 second pause to allow everything to catch up then load and start next MIDI
}
catch (Exception ex) {Logger.getLogger(MoppyMainWindow.class.getName()) .log(Level.SEVERE, null, ex);}
if(playlist.isEmpty()){playlistFlag=false;} //Disable playlist functionality once playlist is empty
}
else if (repeatFlag){
for (Sequencer c : Sequencers){c.setTickPosition(0);}
for (Sequencer c : Sequencers){c.start();}
}
}
}
__________________________________________________ _______________________________________________
Is it possible to turn a list into a file that contains that list of midis?
I know this code probably isn't enough to understand what's going on. If you're interested in helping, and you would like all the code, send me a message, please. Thanks!
Otherwise, other info about java.util.list and saving arrays would be helpful.
Re: Saving a List of MIDI files
Quote:
Is it possible to turn a list into a file
Yes if the items in the list can be represented by Strings, then you could write those Strings to a file.
Re: Saving a List of MIDI files
Quote:
Originally Posted by
Norm
Yes if the items in the list can be represented by Strings, then you could write those Strings to a file.
I think that helps! The code uses this method to load midis:
public void loadFile(String filePath) throws InvalidMidiDataException, IOException, MidiUnavailableException {
Sequence sequence = MidiSystem.getSequence(new File(filePath));
for (Sequencer c : Sequencers){
c.stop();
c.setSequence(sequence);
}
System.out.println("Loaded sequence with "+(sequence.getTracks().length-1)+" MIDI channels.");
}
__________________________________________________ ________________________________________
Where filePath is a string of the filePath. Is it possible to save an array of filePath Strings, and then be able to load all of them in at once?
Re: Saving a List of MIDI files
Hold on, I just found the method listFiles in java.io.file.list
listFiles
public File[] listFiles()
Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname.
If this abstract pathname does not denote a directory, then this method returns null. Otherwise an array of File objects is returned, one for each file or directory in the directory. Pathnames denoting the directory itself and the directory's parent directory are not included in the result. Each resulting abstract pathname is constructed from this abstract pathname using the File(File, String) constructor. Therefore if this pathname is absolute then each resulting pathname is absolute; if this pathname is relative then each resulting pathname will be relative to the same directory.
There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.
Returns:
An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.
__________________________________________________ _________________________________________
I'm not too clear on the definition of a directory, but, does this mean that I would select a folder of MIDIs to load, and it would load them all for me at once? Because that would be awesome.
Re: Saving a List of MIDI files
If you had a file with paths to the files, you could use the loadFile() method with the paths that were read from the file.
The listFiles() method returns an array of File objects for the selected directory in the File object. No data is loaded, that is up to the program to do.
Re: Saving a List of MIDI files
Okay, so there are two ways of going about this then. I could create a file with paths to other midi files, which I could then load, or I could use the listFiles() method to obtain the array of midi files, and then possibly use a for loop using Array.lenght() as the loop condition to load each file in the array.
Going with the second option, how do I use the listFiles() method? It has no arguments, so how do I tell it which folder to get the midi files from?
Thanks so much for all your help!
Re: Saving a List of MIDI files
Quote:
how do I tell it which folder
Set the File object to be the folder with the files: = new File(<folder with the files>);
Re: Saving a List of MIDI files
Okay, this is strange. I can't instantiate a File object. Can't this work?
File a = new File(<b>); \\ b is a String representing the folder with the files
_________
then once I instantiate that file I would do this:
a.listFiles()
for(i=0; i<=a.Length(); i++)
{
Sequence sequence = MidiSystem.getSequence(new File(a[i]));
}
for (Sequencer c : Sequencers){
c.stop();
c.setSequence(sequence);
}
System.out.println("Loaded sequence with "+(sequence.getTracks().length-1)+" MIDI channels.");
}
________________________
.... Right?
Re: Saving a List of MIDI files
Quote:
I can't instantiate a File object.
Do you get an error? Please post the full text of the error message.
Why do you say "I can't instantiate a File object"? What happens when the code is executed? What is returned by the call to new File(..)?
the listFiles() method returns an array. Your posted code does nothing with what the method returns. You need to receive the array in a variable.
Re: Saving a List of MIDI files
I don't know how useful this will be. A lot of these errors are unrelated. I tried to highlight the related ones.
Jul 30, 2012 3:52:34 PM org.jdesktop.application.LocalStorage getId
WARNING: unspecified resource Application.id using MoppyUI
Jul 30, 2012 3:52:34 PM org.jdesktop.application.LocalStorage getId
WARNING: unspecified resource Application.vendorId using UnknownApplicationVendor
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/jdesktop/swingworker/SwingWorker
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknow n Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknow n Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.jdesktop.application.Application.waitForReady( Application.java:283)
at org.jdesktop.application.Application$1.run(Applica tion.java:172)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPri vilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.jdesktop.swingworker.SwingWorker
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 40 more
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problems:
Syntax error, insert ")" to complete Expression
Syntax error on token ")", invalid Expression
at moppydesk.MoppySequencer.loadFile(MoppySequencer.j ava:103)
at moppydesk.MoppyMainWindow.loadSequenceFile(MoppyMa inWindow.java:787)
at moppydesk.MoppyMainWindow.initializeSequencer(Mopp yMainWindow.java:121)
at moppydesk.MoppyMainWindow.connectSequencerPressed( MoppyMainWindow.java:840)
at moppydesk.MoppyMainWindow.access$20(MoppyMainWindo w.java:838)
at moppydesk.MoppyMainWindow$21.actionPerformed(Moppy MainWindow.java:708)
at javax.swing.AbstractButton.fireActionPerformed(Unk nown Source)
at javax.swing.AbstractButton$Handler.actionPerformed (Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed (Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseRe leased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent( Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(U nknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unkno wn Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPri vilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPri vilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPri vilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
line 103 refers to this:
File a = new File(<filePath>); // filePath is a String object of the directory
doesn't really say anything about the nature of the error, but in using eclypse, it gives me little hints. For this it says the Parentheses are a syntax error, so I did this:
File a = new File<filePath>;
It then says this, "The type File is not generic; it cannot be parameterized with arguments <filePath>" and this, "filePath cannot be resolved to a type"
filePath is the argument for the method that I'm defining, so it should go like this:
public void loadFile(String filePath) throws InvalidMidiDataException, IOException, MidiUnavailableException {
File a = new File<filePath>;
/* for loop loading the indices of the file array */
sequencer.stop();
sequencer.setSequence(sequence);
System.out.println("Loaded sequence with "+(sequence.getTracks().length-1)+" MIDI channels.");
}
Re: Saving a List of MIDI files
Quote:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problems:
This part of the error message says there are compiler problems. You need to get a clean compile before trying to execute the program.
Quote:
File a = new File(<filePath>)
<filePath> needs to be replaced with what a valid value. See the File class's API doc for the choices.
Normally items written like: <filePath> are meta symbols that are supposed to be replaced with good values. Read the API doc to see what the valid values are.