01
This commit is contained in:
commit
ed54cd866e
31
src/Main.java
Normal file
31
src/Main.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* aNNiMON 2011
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
import javax.microedition.midlet.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Main extends MIDlet {
|
||||||
|
|
||||||
|
public Display dsp;
|
||||||
|
public static Main midlet;
|
||||||
|
|
||||||
|
public Main() {
|
||||||
|
midlet = Main.this;
|
||||||
|
dsp = Display.getDisplay(Main.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startApp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseApp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyApp(boolean ex) {
|
||||||
|
notifyDestroyed();
|
||||||
|
}
|
||||||
|
}
|
14
src/midedit/AbstractListener.java
Normal file
14
src/midedit/AbstractListener.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public interface AbstractListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param itemNum
|
||||||
|
*/
|
||||||
|
public void actionPerformed(int itemNum);
|
||||||
|
}
|
208
src/midedit/BufDataInputStream.java
Normal file
208
src/midedit/BufDataInputStream.java
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Áóôôåðèçèðîâàííûé ââîä-âûâîä
|
||||||
|
* @author vmx
|
||||||
|
*/
|
||||||
|
public class BufDataInputStream extends InputStream implements DataInput {
|
||||||
|
public byte[] buffer;
|
||||||
|
public int capacity, is_available, bpos, blen;
|
||||||
|
protected InputStream is;
|
||||||
|
|
||||||
|
public BufDataInputStream(InputStream iis) throws IOException {
|
||||||
|
bpos = blen = 0;
|
||||||
|
is = iis;
|
||||||
|
capacity = is_available = is.available ();
|
||||||
|
buffer = new byte[capacity];
|
||||||
|
if (is != null) is.read(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
if (is != null) is.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int available() {
|
||||||
|
return blen - bpos + is_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCapacity() {
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void seek(int pos) {
|
||||||
|
bpos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int tell() throws IOException {
|
||||||
|
return capacity - available();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (bpos > buffer.length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ((int) buffer[bpos++]) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readBack() throws IOException {
|
||||||
|
if (bpos == 0) {
|
||||||
|
if (available() == capacity) return -1;
|
||||||
|
int old = tell();
|
||||||
|
bpos = old;
|
||||||
|
}
|
||||||
|
return ((int) buffer[--bpos]) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean readBoolean() throws IOException {
|
||||||
|
int r = read();
|
||||||
|
if (r == -1) {
|
||||||
|
throw new IOException("EOF");
|
||||||
|
}
|
||||||
|
return r != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte readByte() throws IOException {
|
||||||
|
int r = read();
|
||||||
|
if (r == -1) {
|
||||||
|
throw new IOException("EOF");
|
||||||
|
}
|
||||||
|
return (byte) r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readChar() throws IOException {
|
||||||
|
return (char) ((readUnsignedByte() << 8) | readUnsignedByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFully(byte[] b) throws IOException {
|
||||||
|
if (read(b) < b.length) {
|
||||||
|
throw new IOException("EOF");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFully(byte[] b, int off, int len) throws IOException {
|
||||||
|
if (read(b, off, len) < len) {
|
||||||
|
throw new IOException("EOF");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt() throws IOException {
|
||||||
|
return (readUnsignedByte() << 24) |
|
||||||
|
(readUnsignedByte() << 16) |
|
||||||
|
(readUnsignedByte() << 8) |
|
||||||
|
(readUnsignedByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readLong() throws IOException {
|
||||||
|
byte bb[] = new byte[8];
|
||||||
|
readFully(bb);
|
||||||
|
return (bb[0] << 24) |
|
||||||
|
(bb[1] << 16) |
|
||||||
|
(bb[2] << 8) |
|
||||||
|
(bb[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short readShort() throws IOException {
|
||||||
|
return (short) ((readUnsignedByte() << 8) | readUnsignedByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUnsignedByte() throws IOException {
|
||||||
|
return ((int) readByte()) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUnsignedShort() throws IOException {
|
||||||
|
return ((int) readShort()) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int skipBytes(int len) throws IOException {
|
||||||
|
return (int) skip(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readUTF() throws IOException, UTFDataFormatException {
|
||||||
|
int n = readUnsignedShort();
|
||||||
|
byte b[] = new byte[n];
|
||||||
|
readFully(b);
|
||||||
|
return new String(b, 0, b.length, "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readCharUTF() throws IOException, UTFDataFormatException {
|
||||||
|
int b, c, d;
|
||||||
|
b = read();
|
||||||
|
if (b == -1) {
|
||||||
|
return (char) -1;
|
||||||
|
}
|
||||||
|
if ((b & 0x80) == 0) {
|
||||||
|
return (char) b;
|
||||||
|
} else if ((b & 0xE0) == 0xC0) {
|
||||||
|
c = read();
|
||||||
|
if ((c & 0xC0) != 0x80) {
|
||||||
|
throw new UTFDataFormatException();
|
||||||
|
}
|
||||||
|
return (char) (((b & 0x1F) << 6) | (c & 0x3F));
|
||||||
|
} else if ((b & 0xF0) == 0xE0) {
|
||||||
|
c = read();
|
||||||
|
d = read();
|
||||||
|
if ((c & 0xC0) != 0x80 || (d & 0xC0) != 0x80) {
|
||||||
|
throw new UTFDataFormatException();
|
||||||
|
}
|
||||||
|
return (char) (((b & 0x0F) << 12) | ((c & 0x3F) << 6) | (d & 0x3F));
|
||||||
|
}
|
||||||
|
throw new UTFDataFormatException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readCharBackUTF() throws IOException, UTFDataFormatException {
|
||||||
|
int b, c, d;
|
||||||
|
d = readBack();
|
||||||
|
c = readBack();
|
||||||
|
b = readBack();
|
||||||
|
if (d == -1) {
|
||||||
|
return (char) -1;
|
||||||
|
}
|
||||||
|
if ((d & 0x80) == 0) {
|
||||||
|
read();
|
||||||
|
read();
|
||||||
|
return (char) d;
|
||||||
|
} else if ((c & 0xE0) == 0xC0 && (d & 0xC0) == 0x80) {
|
||||||
|
read();
|
||||||
|
return (char) (((c & 0x1F) << 6) | (d & 0x3F));
|
||||||
|
} else if ((b & 0xF0) == 0xE0 && (c & 0xC0) == 0x80 && (d & 0xC0) == 0x80) {
|
||||||
|
return (char) (((b & 0x0F) << 12) | ((c & 0x3F) << 6) | (d & 0x3F));
|
||||||
|
}
|
||||||
|
throw new UTFDataFormatException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkBOM() {
|
||||||
|
try {
|
||||||
|
if (available() < 3 ||
|
||||||
|
read() != 0xEF ||
|
||||||
|
read() != 0xBB ||
|
||||||
|
read() != 0xBF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (IOException iox) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean find(byte[] b) {
|
||||||
|
if (b == null) return false;
|
||||||
|
int po = 0;
|
||||||
|
for (int i = bpos + 1; i < buffer.length; i++) {
|
||||||
|
po = 0;
|
||||||
|
if (buffer[i] == b[0]) {
|
||||||
|
for (int j = 0; j < b.length; j++) { //System.out.println("b "+b[j]);
|
||||||
|
if (buffer[i + j] == b[j]) {
|
||||||
|
po += 1;
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (po == b.length) {
|
||||||
|
bpos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (po > 0);
|
||||||
|
}
|
||||||
|
}
|
566
src/midedit/CompositionForm.java
Normal file
566
src/midedit/CompositionForm.java
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class CompositionForm extends Form implements CommandListener, Runnable, ItemCommandListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static CompositionForm curForm;
|
||||||
|
private static final byte SEEK_GAUGE_MAX = 10;
|
||||||
|
private byte seekGaugeCur = 0;
|
||||||
|
private MixerMain control;
|
||||||
|
private MixerModel model;
|
||||||
|
private Display display;
|
||||||
|
private NotesCanvas notesCanvas;
|
||||||
|
private DrumsCanvas drumsCanvas;
|
||||||
|
private MixerCanvas curCanvas;
|
||||||
|
private ChannelChoiceGroup choiseInstrument;
|
||||||
|
private Gauge seekingGauge;
|
||||||
|
private static Form listInstrumentsForm;
|
||||||
|
private Composition composition;
|
||||||
|
private String fileName;
|
||||||
|
public static boolean isPlaying,
|
||||||
|
isWorking,
|
||||||
|
isNew = false,
|
||||||
|
isAdd;
|
||||||
|
private Command addInstrument = new Command(Constants.getStringName(50), Command.HELP, 3),
|
||||||
|
edit = new Command(Constants.getStringName(51), Command.HELP, 1),
|
||||||
|
setInstrument = new Command(Constants.getStringName(52), Command.ITEM, 1),
|
||||||
|
delInstrument = new Command(Constants.getStringName(53), Command.ITEM, 2),
|
||||||
|
temp = new Command(Constants.getStringName(54), Command.ITEM, 3),
|
||||||
|
volume = new Command(Constants.getStringName(55), Command.ITEM, 4),
|
||||||
|
meter = new Command(Constants.getStringName(56), Command.ITEM, 5),
|
||||||
|
rmsMode = new Command(Constants.getStringName(9), Command.ITEM, 6),
|
||||||
|
jsr75Mode = new Command(Constants.getStringName(6), Command.ITEM, 7);
|
||||||
|
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static Command play = new Command(Constants.getStringName(57), Command.ITEM, 1),
|
||||||
|
playOrig = new Command(Constants.getStringName(58), Command.ITEM, 1),
|
||||||
|
stop = new Command(Constants.getStringName(35), Command.BACK, 0),
|
||||||
|
back = new Command(Constants.getStringName(25), Command.BACK, 2),
|
||||||
|
//cancel = new Command("Cancel",Command.BACK,1),
|
||||||
|
ok = new Command(Constants.getStringName(59), Command.ITEM, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ctrl
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public CompositionForm(MixerMain ctrl) throws Exception {
|
||||||
|
this(ctrl, null);
|
||||||
|
isNew = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ctrl
|
||||||
|
* @param fName
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public CompositionForm(MixerMain ctrl, String fName) throws Exception {
|
||||||
|
super((fName != null) ? fName : "New");
|
||||||
|
control = ctrl;
|
||||||
|
model = control.getModel();
|
||||||
|
model.crossPlayer.setCommandForm(this);
|
||||||
|
fileName = fName;
|
||||||
|
curForm = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isNew() {
|
||||||
|
return isNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param isNewComposition
|
||||||
|
*/
|
||||||
|
public void setNew(boolean isNewComposition) {
|
||||||
|
isNew = isNewComposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setComposForm() {
|
||||||
|
seekingGauge.setValue((composition.getCurWInPercent() + SEEK_GAUGE_MAX / 2) / SEEK_GAUGE_MAX);
|
||||||
|
seekGaugeCur = (byte) seekingGauge.getValue();
|
||||||
|
display.setCurrent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// public boolean isntCancel() {
|
||||||
|
// return isWorking;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
display = Display.getDisplay(MixerMain.curMIDlet);
|
||||||
|
|
||||||
|
WaitForm waitForm = new WaitForm(Constants.getStringName(19),//@@@
|
||||||
|
model.getWaitableFile(),
|
||||||
|
control.getCurrentlistMenu(),
|
||||||
|
model);
|
||||||
|
display.setCurrent(waitForm);
|
||||||
|
model.resetProgress();
|
||||||
|
new Thread(waitForm).start();
|
||||||
|
try {
|
||||||
|
composition = model.openMix(fileName);
|
||||||
|
buildContent();
|
||||||
|
display.callSerially(new Runnable() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
display.setCurrent(CompositionForm.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
isWorking = true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(12), Constants.getStringName(13) + "\n" + ex, null, null);//@@@
|
||||||
|
a.setTimeout(Alert.FOREVER);
|
||||||
|
waitForm.cancel();
|
||||||
|
isWorking = false;
|
||||||
|
control.setCurrentlistMenu(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void releaseMem() {
|
||||||
|
if (composition != null) {
|
||||||
|
composition.deleteNoteList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildContent() throws Exception {
|
||||||
|
|
||||||
|
//Constants constants = new Constants();
|
||||||
|
notesCanvas = null;
|
||||||
|
drumsCanvas = null;
|
||||||
|
curCanvas = null;
|
||||||
|
MixerCanvas.xBase = 0;
|
||||||
|
MixerCanvas.curX = 0;
|
||||||
|
|
||||||
|
String[] instrumentsStrings = composition.getInstrumentsStrings();
|
||||||
|
if (instrumentsStrings == null) {
|
||||||
|
throw new Exception("instruments==null");
|
||||||
|
}
|
||||||
|
|
||||||
|
choiseInstrument = new ChannelChoiceGroup(Constants.getStringName(23), instrumentsStrings, this.buildChansList());
|
||||||
|
if (choiseInstrument == null) {
|
||||||
|
throw new Exception("choiseInstrument==null");
|
||||||
|
}
|
||||||
|
this.append(choiseInstrument);
|
||||||
|
seekingGauge = new Gauge(Constants.getStringName(71), true, SEEK_GAUGE_MAX, 0);
|
||||||
|
this.append(seekingGauge);
|
||||||
|
this.addCommand(edit);
|
||||||
|
this.addCommand(play);
|
||||||
|
isPlaying = false;
|
||||||
|
this.addCommand(volume);
|
||||||
|
this.addCommand(temp);
|
||||||
|
this.addCommand(meter);
|
||||||
|
this.addCommand(addInstrument);
|
||||||
|
this.addCommand(setInstrument);
|
||||||
|
this.addCommand(delInstrument);
|
||||||
|
this.addCommand(back);
|
||||||
|
//this.addCommand(rmsMode);
|
||||||
|
this.setCommandListener(this);
|
||||||
|
MixerModel.isRMSMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] buildChansList() {
|
||||||
|
int[] instruments = composition.getInstruments();
|
||||||
|
int size = 0;
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
if (instruments[i] != Composition.NOTHING) {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] chans = new byte[size];
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
if (instruments[i] != Composition.NOTHING) {
|
||||||
|
chans[j++] = (byte) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param i
|
||||||
|
*/
|
||||||
|
//public void itemStateChanged(Item item){
|
||||||
|
//System.out.println ("itemStateChanged");
|
||||||
|
//if (item instanceof Choice){
|
||||||
|
// int instNum = ((Choice) item).getSelectedIndex();
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
public void commandAction(Command c, Item i) {
|
||||||
|
String instrName;
|
||||||
|
int instrumNum;
|
||||||
|
model.stopPlay();
|
||||||
|
if (i instanceof StringItem) {
|
||||||
|
instrName = Constants.getInstrName(0);
|
||||||
|
instrumNum = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instrName = ((ChoiceGroup) i).getString(((ChoiceGroup) i).getSelectedIndex());
|
||||||
|
instrumNum =Constants.instrVectorArr.indexOf(instrName)+1;
|
||||||
|
}
|
||||||
|
// System.out.println("instrName = " + instrName);
|
||||||
|
// System.out.println("instrumNum = " + instrumNum);
|
||||||
|
if (c == play) {
|
||||||
|
int channel=-1;
|
||||||
|
int lengthOfChannel=0;
|
||||||
|
try {
|
||||||
|
channel = choiseInstrument.getSelectedChannel();
|
||||||
|
lengthOfChannel = composition.tracks[channel].getLen();
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
}
|
||||||
|
//System.out.println ("Channel="+channel+" length="+lengthOfChannel);
|
||||||
|
if (channel == Constants.DRUMS_CHANNEL || isAdd || lengthOfChannel < 3) {
|
||||||
|
try {
|
||||||
|
model.playTest((byte) (instrumNum - 1));
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
model.playTrack(composition, channel, instrumNum - 1);
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
model.playTest((byte) (instrumNum - 1));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (c == ok) {
|
||||||
|
if (isAdd) {
|
||||||
|
byte channel = composition.addInstrument(instrumNum - 1);
|
||||||
|
if (channel != -1) {
|
||||||
|
choiseInstrument.appendChannel(instrName, channel);
|
||||||
|
} else {
|
||||||
|
Alert a = new Alert(Constants.getStringName(14), Constants.getStringName(15), null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
int channel = choiseInstrument.getSelectedChannel();
|
||||||
|
if (channel != -1 && channel != Constants.DRUMS_CHANNEL) {
|
||||||
|
choiseInstrument.setChannel(choiseInstrument.getSelectedIndex(), instrName, (byte) channel);
|
||||||
|
composition.setInstrument(channel, instrumNum - 1);
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display.setCurrent(CompositionForm.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @param displayable
|
||||||
|
*/
|
||||||
|
public void commandAction(Command command, Displayable displayable) {
|
||||||
|
// System.out.println("displayable = " + displayable);
|
||||||
|
// System.out.println("command = " + command);
|
||||||
|
// if (command!=delInstrument) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
int newVal = seekingGauge.getValue();
|
||||||
|
if (newVal != seekGaugeCur) {
|
||||||
|
byte channel=0;
|
||||||
|
try {
|
||||||
|
channel = choiseInstrument.getSelectedChannel();
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
composition.setCurW(seekingGauge.getValue() * 100 / SEEK_GAUGE_MAX, channel);
|
||||||
|
} catch (NullPointerException nullExc) {
|
||||||
|
seekingGauge.setValue(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((command == play) && (displayable == this)) {
|
||||||
|
try {
|
||||||
|
model.playMix(composition, 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
msg("" + e);
|
||||||
|
}
|
||||||
|
} else if (command == Settings.comCancel) {
|
||||||
|
model.stopPlay();
|
||||||
|
display.setCurrent(CompositionForm.this);
|
||||||
|
} else if (command == stop) {
|
||||||
|
model.stopPlay();
|
||||||
|
} else if (command == edit) {
|
||||||
|
int channel;
|
||||||
|
try {
|
||||||
|
channel = choiseInstrument.getSelectedChannel();
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
channel=-1;
|
||||||
|
}
|
||||||
|
if (channel == -1) {
|
||||||
|
Alert a = new Alert("CompositionForm", "getChannelFromInstrumName=" + channel, null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel == Constants.DRUMS_CHANNEL) {
|
||||||
|
if (drumsCanvas == null) {
|
||||||
|
drumsCanvas = new DrumsCanvas(control, composition);
|
||||||
|
}
|
||||||
|
curCanvas = drumsCanvas;
|
||||||
|
} else {
|
||||||
|
if (notesCanvas == null) {
|
||||||
|
notesCanvas = new NotesCanvas(control, composition, channel);
|
||||||
|
} else {
|
||||||
|
notesCanvas.setChannel(channel);
|
||||||
|
}
|
||||||
|
curCanvas = notesCanvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
display.setCurrent(curCanvas);
|
||||||
|
curCanvas.setNeedPaint();
|
||||||
|
} else if (command == addInstrument) {
|
||||||
|
isAdd = true;
|
||||||
|
display.setCurrent(getListOfInstruments());
|
||||||
|
System.out.println("displayable = " + displayable);
|
||||||
|
} else if (command == setInstrument) {
|
||||||
|
isAdd = false;
|
||||||
|
display.setCurrent(getListOfInstruments());
|
||||||
|
} else if (command == delInstrument) {
|
||||||
|
byte channel;
|
||||||
|
try {
|
||||||
|
channel = choiseInstrument.getSelectedChannel();
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
choiseInstrument.deleteChannel(choiseInstrument.getSelectedIndex());
|
||||||
|
composition.setInstrument(channel, Composition.NOTHING);
|
||||||
|
composition.delNotes(0, 0x7fffffff, (byte) channel, (byte) -1, (byte) 127);
|
||||||
|
} else if (command == temp) {
|
||||||
|
TempoList tempos = new TempoList(composition, model, this);
|
||||||
|
display.setCurrent(tempos);
|
||||||
|
} else if (command == volume) {
|
||||||
|
VolumeForm volForm = new VolumeForm(composition, choiseInstrument.getChansVector(), model, this);
|
||||||
|
display.setCurrent(volForm);
|
||||||
|
} else if (command == meter) {
|
||||||
|
Form textBoxTemp = new Form(Constants.getInstrName(72));
|
||||||
|
final TextField nomField = new TextField(Constants.getStringName(73), "" + composition.getNom(), 2, TextField.NUMERIC);
|
||||||
|
textBoxTemp.append(nomField);
|
||||||
|
final TextField denomField = new TextField(Constants.getStringName(74), "" + composition.getDenomE(), 1, TextField.NUMERIC);
|
||||||
|
textBoxTemp.append(denomField);
|
||||||
|
textBoxTemp.append(MixerMain.createStringItem(Constants.getStringName(76), 2));
|
||||||
|
textBoxTemp.addCommand(CompositionForm.ok);
|
||||||
|
textBoxTemp.addCommand(Settings.comCancel);
|
||||||
|
textBoxTemp.setCommandListener(new CommandListener() {
|
||||||
|
|
||||||
|
public void commandAction(Command command, Displayable displayable) {
|
||||||
|
if (command == CompositionForm.ok) {
|
||||||
|
composition.setMeter(Integer.parseInt(nomField.getString(), 10),
|
||||||
|
Integer.parseInt(denomField.getString(), 10));
|
||||||
|
}
|
||||||
|
display.setCurrent(CompositionForm.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
model.display.setCurrent(textBoxTemp);
|
||||||
|
|
||||||
|
} //else if(command == rmsMode)
|
||||||
|
//{
|
||||||
|
//MixerModel.isRMSMode=true;
|
||||||
|
//this.removeCommand (rmsMode);
|
||||||
|
//this.addCommand (jsr75Mode);
|
||||||
|
//}
|
||||||
|
//else if(command == jsr75Mode)
|
||||||
|
//{
|
||||||
|
//MixerModel.isRMSMode=false;
|
||||||
|
//this.removeCommand (jsr75Mode);
|
||||||
|
//this.addCommand (rmsMode);
|
||||||
|
//}
|
||||||
|
else if (command == back) {
|
||||||
|
control.comBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void saveComposition(String name) throws Exception {
|
||||||
|
this.setTitle(name);
|
||||||
|
final String nameFinal = name;
|
||||||
|
Thread runner = new Thread() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
WaitForm waitForm = new WaitForm(Constants.getStringName(18) + "...",
|
||||||
|
model.getWaitableFile(),
|
||||||
|
control.getCurrentlistMenu(),
|
||||||
|
model);
|
||||||
|
display.setCurrent(waitForm);
|
||||||
|
model.resetProgress();
|
||||||
|
new Thread(waitForm).start();
|
||||||
|
composition.setName(nameFinal);
|
||||||
|
try {
|
||||||
|
String ans = model.saveMix(composition, nameFinal);
|
||||||
|
Alert a = new Alert(Constants.getStringName(16), ans, null, null);
|
||||||
|
a.setTimeout(Alert.FOREVER);
|
||||||
|
control.setCurrentlistMenu(a);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(12),
|
||||||
|
Constants.getStringName(17) + "\n" + ex.getMessage(), null, null);
|
||||||
|
a.setTimeout(Alert.FOREVER);
|
||||||
|
waitForm.cancel();
|
||||||
|
control.setCurrentlistMenu(a);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
runner.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getCompositionName() {
|
||||||
|
return composition.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public static void msg(String s) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(12), Constants.getStringName(12) + "\n" + s, null, null);
|
||||||
|
MixerMain.display.setCurrent(a);
|
||||||
|
}
|
||||||
|
/*Form tabsInstruments (){
|
||||||
|
MyItem []groupsOfElements = new MyItem [16];
|
||||||
|
String [] groupOfElements = new String [8];
|
||||||
|
int numElementsInGroup = 8,
|
||||||
|
numIcosOnScreen = MyItem.SCREEN_WIDTH/32;
|
||||||
|
StringItem instruments[] = new StringItem [128];
|
||||||
|
return null;
|
||||||
|
}*/
|
||||||
|
private Form getListOfInstruments() {
|
||||||
|
System.out.println("in getListInstruments");
|
||||||
|
if (listInstrumentsForm == null) {
|
||||||
|
ChoiceGroup[] groupsChoiseGroup = new ChoiceGroup[16];
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
// for (int j = 0; j < 8; j++) {
|
||||||
|
// listOfElements[j] = j + i * 8 + 1 + ' ' + Constants.getInstrName(j + i * 8 + 1);
|
||||||
|
// }
|
||||||
|
String[] listOfElements = new String[8];
|
||||||
|
System.arraycopy(Settings.parserInstr.stringResourses, i*8+1, listOfElements,0, 8);
|
||||||
|
groupsChoiseGroup[i] = new ChoiceGroup(Constants.getInstrName(129 + i), 4, listOfElements, null);
|
||||||
|
//for (int j=0; j<8; j++)
|
||||||
|
//groupsOfElements[i].setFont(j,MixerMain.SMALL_FONT);
|
||||||
|
groupsChoiseGroup[i].addCommand(play);
|
||||||
|
groupsChoiseGroup[i].addCommand(ok);
|
||||||
|
groupsChoiseGroup[i].setItemCommandListener(this);
|
||||||
|
}
|
||||||
|
listInstrumentsForm = new Form(Constants.getStringName(75), groupsChoiseGroup);
|
||||||
|
Item drums = new StringItem(Constants.getInstrName(0), null);
|
||||||
|
drums.addCommand(ok);
|
||||||
|
drums.setItemCommandListener(this);
|
||||||
|
listInstrumentsForm.append(drums);
|
||||||
|
listInstrumentsForm.addCommand(Settings.comCancel);
|
||||||
|
listInstrumentsForm.setCommandListener(this);
|
||||||
|
}
|
||||||
|
//form.setItemStateListener(this);
|
||||||
|
return listInstrumentsForm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChannelChoiceGroup extends ChoiceGroup {
|
||||||
|
|
||||||
|
private Vector instrumentsVector;
|
||||||
|
|
||||||
|
public ChannelChoiceGroup(String label, String[] stringElements, byte[] chans) {
|
||||||
|
super(label, Choice.EXCLUSIVE, stringElements, null);
|
||||||
|
instrumentsVector = new Vector(Constants.NCHANNEL, 1);
|
||||||
|
for (int i = 0; i < chans.length; ++i) {
|
||||||
|
instrumentsVector.addElement(new Byte(chans[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getSelectedChannel() throws IllegalAccessException{
|
||||||
|
try{
|
||||||
|
Byte b = (Byte) instrumentsVector.elementAt(this.getSelectedIndex());
|
||||||
|
return b.byteValue();
|
||||||
|
}catch (ArrayIndexOutOfBoundsException arI){
|
||||||
|
throw new IllegalAccessException(arI.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int appendChannel(String stringElement, byte channel) {
|
||||||
|
if (instrumentsVector.size() < Constants.NCHANNEL) {
|
||||||
|
instrumentsVector.addElement(new Byte(channel));
|
||||||
|
return super.append(stringElement, null);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteChannel(int index) {
|
||||||
|
instrumentsVector.removeElementAt(index);
|
||||||
|
super.delete(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannel(int index, String stringElement, byte channel) {
|
||||||
|
instrumentsVector.setElementAt(new Byte(channel), index);
|
||||||
|
super.set(index, stringElement, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector getChansVector() {
|
||||||
|
return instrumentsVector;
|
||||||
|
}
|
||||||
|
}
|
142
src/midedit/Constants.java
Normal file
142
src/midedit/Constants.java
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//import java.util.*;
|
||||||
|
//import java.lang.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class Constants
|
||||||
|
{
|
||||||
|
// private static Hashtable hashInstrums ;
|
||||||
|
/**
|
||||||
|
public Constants()
|
||||||
|
{
|
||||||
|
//instruments = getInstruments();
|
||||||
|
// hashInstrums= new Hashtable(129);
|
||||||
|
// for(int i=0; i<instruments.length; ++i)
|
||||||
|
// hashInstrums.put(Settings.instrStrings[i], new Integer(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
// public int getInstrumInd(String s) throws Exception
|
||||||
|
// {
|
||||||
|
// Integer intVal = (Integer)hashInstrums.get(s);
|
||||||
|
// if(intVal == null)
|
||||||
|
// throw new Exception("intVal == null");
|
||||||
|
// return intVal.intValue();
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
public static String getStringName (int index){
|
||||||
|
return Settings.parserLang.getStringResourses(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getInstrName (int index){
|
||||||
|
return Settings.parserInstr.getStringResourses(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setTimeConst(int t)
|
||||||
|
{
|
||||||
|
timeConst = t;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// public static String getInstruments(int i){
|
||||||
|
// return (String);
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int INV_CANVAS_CONST = 131;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final char FILE_DELIM = '/';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static int timeConst = 10;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static int N_INSTR = 127,
|
||||||
|
DRUMS_LENGTH=61,//27__87
|
||||||
|
DRUMS_SHIFT = 27;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static int DRUMS_CHANNEL = 9;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int NCHANNEL = 16;
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
// public static final String[] noteNames = {"C","C#","D","D#","E",
|
||||||
|
// "F","F#","G","G#","A","A#","B"};
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int MAX_NOTE_LENGTH = 8; // min == 1/(2^5)
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static String[]KEY_MAP = {
|
||||||
|
"<LeftSoftKey>", getStringName(24),
|
||||||
|
"<RightSoftKey>", getStringName(25),
|
||||||
|
"<Fire>,<5>", getStringName(26)+"\n"+
|
||||||
|
getStringName(27),
|
||||||
|
"<9>,<Clear>", getStringName(28),
|
||||||
|
"<Red Phone>", getStringName(29),
|
||||||
|
"<Volume +'\'->", getStringName(30),
|
||||||
|
"<1>", getStringName(31),
|
||||||
|
"<3>", getStringName(32),
|
||||||
|
"<7>,<Green Phone>", getStringName(33),
|
||||||
|
"<*>,<#>,<0>", getStringName(34),
|
||||||
|
//Settings.settingsIndex[4]==0? "<5>": "<Fire>",getStringName(35),
|
||||||
|
Settings.settingsIndex[4]==0? "<up>,<down>,<left>,<right>": "<4>,<6>,<2>,<8> ",getStringName(36),
|
||||||
|
Settings.settingsIndex[4]==0? "<4>,<6>,<2>,<8>":"<up>,<down>,<left>,<right>", getStringName(37),
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static String[]QUICK_COMMANDS = {
|
||||||
|
"<1> ",getStringName(38),
|
||||||
|
"<2> ",getStringName(39),
|
||||||
|
"<3> ",getStringName(40),
|
||||||
|
"<4> ",getStringName(41),
|
||||||
|
"<5> ",getStringName(42),
|
||||||
|
"<6> ",getStringName(43),
|
||||||
|
"<7> ",getStringName(44),
|
||||||
|
"<8> ",getStringName(45),
|
||||||
|
"<9> ",getStringName(46),
|
||||||
|
"<*> ",getStringName(29),
|
||||||
|
"<0> ",getStringName(48),
|
||||||
|
"<#> ",getStringName(49),
|
||||||
|
};
|
||||||
|
static VectorArr instrVectorArr=new VectorArr(Settings.parserInstr.stringResourses, 1, 128);
|
||||||
|
}
|
||||||
|
class VectorArr extends Vector {
|
||||||
|
public VectorArr(Object src, int beg, int length) {
|
||||||
|
super(length);
|
||||||
|
setSize(length);
|
||||||
|
System.arraycopy(src, beg, elementData, 0, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
125
src/midedit/DrumsCanvas.java
Normal file
125
src/midedit/DrumsCanvas.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class DrumsCanvas extends MixerCanvas
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int drumsShift = Constants.DRUMS_SHIFT;
|
||||||
|
private byte[] drumsTable = null;
|
||||||
|
private byte[] drumsTableInverse = null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ctrl
|
||||||
|
* @param c
|
||||||
|
*/
|
||||||
|
public DrumsCanvas(MixerMain ctrl, Composition c)
|
||||||
|
{
|
||||||
|
super(ctrl,c,Constants.DRUMS_CHANNEL);
|
||||||
|
prepareConstants();
|
||||||
|
|
||||||
|
byte[] b = new byte[Constants.NCHANNEL];
|
||||||
|
for(int i=0; i<Constants.NCHANNEL; ++i)
|
||||||
|
b[i]=(byte)(drumsShift+i);
|
||||||
|
drumsTable = b;
|
||||||
|
newDrumsTableInverse();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected void prepareConstants()
|
||||||
|
{
|
||||||
|
if(nH> Constants.DRUMS_LENGTH)
|
||||||
|
nH = Constants.DRUMS_LENGTH;
|
||||||
|
hStep = 4;
|
||||||
|
hMin = drumsShift;
|
||||||
|
hMax = (drumsShift + Constants.DRUMS_LENGTH-1);
|
||||||
|
hBase = hMin;
|
||||||
|
curY = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean doKEY_NUM5()
|
||||||
|
{
|
||||||
|
if(super.doKEY_NUM5() == false)
|
||||||
|
composition.addNoteOn(getCurTime(),(byte)channel,
|
||||||
|
(byte)getNoteFromLine(curY), (byte)getCurVol(),0,true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected void doSmallDown (){
|
||||||
|
if(hBase+curY < hMax)
|
||||||
|
super.doSmallDown();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param val
|
||||||
|
public void setCurInstrument(int val)
|
||||||
|
{
|
||||||
|
int n = val + DrumsTable.SHIFT;
|
||||||
|
for(int i=0; i<nH; ++i)
|
||||||
|
if(drumsTable[i]==n)
|
||||||
|
return;
|
||||||
|
drumsTableInverse[drumsTable[curY]] = (byte)-1;
|
||||||
|
drumsTableInverse[n] = (byte)curY;
|
||||||
|
drumsTable[curY] = (byte)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
public void newDrumsTableInverse()
|
||||||
|
{
|
||||||
|
drumsTableInverse = new byte[Constants.N_INSTR];
|
||||||
|
for(int i=0; i<Constants.N_INSTR; ++i)
|
||||||
|
drumsTableInverse[i]=(byte)-1;
|
||||||
|
for(int i=0; i<Constants.NCHANNEL; ++i)
|
||||||
|
drumsTableInverse[drumsTable[i]]=(byte)i;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public byte[] getDrumsTable()
|
||||||
|
{ return drumsTable; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
*/
|
||||||
|
protected void paintScale(javax.microedition.lcdui.Graphics g)
|
||||||
|
{
|
||||||
|
for(int hh = hBeg; hh < hBeg + rollHeight ; hh+=hOne)
|
||||||
|
g.fillRect(4, hh, wBeg-5, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected byte getLineFromNote(int n)
|
||||||
|
{
|
||||||
|
return (byte)(n - hBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ln
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected int getNoteFromLine(int ln)
|
||||||
|
{
|
||||||
|
return (byte)(hBase + curY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
233
src/midedit/FileChooser.java
Normal file
233
src/midedit/FileChooser.java
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
import midedit.io.AbstractFile;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class FileChooser extends List implements CommandListener, Runnable {
|
||||||
|
|
||||||
|
private AbstractFile file;
|
||||||
|
private String path;
|
||||||
|
private String selectedFileName;
|
||||||
|
private AbstractListener listener = null;
|
||||||
|
private String[] fileNames;
|
||||||
|
private Displayable prevDisplay;
|
||||||
|
private Command up = new Command(Constants.getStringName(60), Command.BACK, 1),
|
||||||
|
delete = new Command(Constants.getStringName(61), Command.ITEM, 1),
|
||||||
|
saveThis;
|
||||||
|
private Form waitForm;
|
||||||
|
private boolean isSave;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static char FILE_DELIMITER = Constants.FILE_DELIM;
|
||||||
|
private String defaultPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param prev
|
||||||
|
* @param pathStr
|
||||||
|
* @param save
|
||||||
|
* @param aFile
|
||||||
|
*/
|
||||||
|
public FileChooser(Displayable prev, String pathStr, boolean save, AbstractFile aFile) {
|
||||||
|
|
||||||
|
super((save) ?Constants.getStringName(62) : Constants.getStringName(63), List.IMPLICIT);
|
||||||
|
file = aFile;
|
||||||
|
isSave = save;
|
||||||
|
prevDisplay = prev;
|
||||||
|
path = pathStr;
|
||||||
|
defaultPath = pathStr;
|
||||||
|
selectedFileName = "";
|
||||||
|
waitForm = new Form(Constants.getStringName(64));
|
||||||
|
waitForm.append("\n\n"+Constants.getStringName(65)+"..");
|
||||||
|
if (!MixerModel.isRMSMode) {
|
||||||
|
this.addCommand(up);
|
||||||
|
}
|
||||||
|
if (isSave) {
|
||||||
|
saveThis = new Command(Constants.getStringName(66), Command.SCREEN, 0);
|
||||||
|
this.addCommand(saveThis);
|
||||||
|
}
|
||||||
|
else if (MixerModel.isRMSMode)
|
||||||
|
this.addCommand(delete);
|
||||||
|
this.addCommand(Settings.comCancel);
|
||||||
|
this.setCommandListener(this);
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param aListener
|
||||||
|
*/
|
||||||
|
public void setAbstractListener(AbstractListener aListener) {
|
||||||
|
listener = aListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @param displayable
|
||||||
|
*/
|
||||||
|
public void commandAction(Command command, Displayable displayable) {
|
||||||
|
try {
|
||||||
|
if (command == up) {
|
||||||
|
int ind;
|
||||||
|
if (path.length() >= 3)
|
||||||
|
{
|
||||||
|
ind = path.lastIndexOf(FILE_DELIMITER, path.length() - 2);
|
||||||
|
String newPath;
|
||||||
|
if (ind >= 0) {
|
||||||
|
newPath = path.substring(0, ind + 1);
|
||||||
|
} else {
|
||||||
|
newPath = "" + FILE_DELIMITER;
|
||||||
|
}
|
||||||
|
path = newPath;
|
||||||
|
}
|
||||||
|
updateView();
|
||||||
|
} else if (command == delete) {
|
||||||
|
int ind = this.getSelectedIndex();
|
||||||
|
if (path.length() > 0) {
|
||||||
|
char ch = path.charAt(path.length() - 1);
|
||||||
|
if (ch != '/' && ch != '\\') {
|
||||||
|
path += FILE_DELIMITER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedFileName = fileNames[ind];
|
||||||
|
if (listener != null) {
|
||||||
|
file.delete(selectedFileName);
|
||||||
|
}
|
||||||
|
} else if (command == Settings.comCancel) {
|
||||||
|
path = null;
|
||||||
|
if (listener != null) {
|
||||||
|
listener.actionPerformed(0);
|
||||||
|
}
|
||||||
|
} else if (command == saveThis) {
|
||||||
|
if (listener != null) {
|
||||||
|
try{
|
||||||
|
listener.actionPerformed(0);
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
Alert a = new Alert(Constants.getStringName(12),Constants.getStringName(20)+":\nlistener.actionPerformed "+ e.getMessage(), null, null);
|
||||||
|
MixerMain.display.setCurrent(a, prevDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ind = this.getSelectedIndex();
|
||||||
|
String fullName;
|
||||||
|
if (path.length() > 0) {
|
||||||
|
char ch = path.charAt(path.length() - 1);
|
||||||
|
if (ch != '/' && ch != '\\') {
|
||||||
|
path += FILE_DELIMITER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fullName = path;
|
||||||
|
fullName += fileNames[ind];
|
||||||
|
if (file.isDirectory(
|
||||||
|
fullName)) {
|
||||||
|
selectedFileName = "";
|
||||||
|
path = fullName;
|
||||||
|
if (path.charAt(path.length() - 1) != '/') {
|
||||||
|
path += FILE_DELIMITER;
|
||||||
|
}
|
||||||
|
updateView();
|
||||||
|
} else if (!isSave)
|
||||||
|
{
|
||||||
|
selectedFileName = fileNames[ind];
|
||||||
|
{
|
||||||
|
if (listener != null) {
|
||||||
|
listener.actionPerformed(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(12),Constants.getStringName(20)+":\nFileChooser "+ e.getMessage(), null, null);
|
||||||
|
MixerMain.display.setCurrent(a, prevDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void update() {
|
||||||
|
MixerMain.display.callSerially(new Runnable() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateView() {
|
||||||
|
MixerMain.display.setCurrent(waitForm);
|
||||||
|
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (path == null) {
|
||||||
|
path = defaultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileNames = file.list(
|
||||||
|
path);
|
||||||
|
path = file.getLastListPath();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = this.size() - 1; i >= 0; --i) {
|
||||||
|
this.delete(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileNames != null) {
|
||||||
|
for (int i = 0; i < fileNames.length; ++i) {
|
||||||
|
this.insert(i, fileNames[i], null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setTicker(new Ticker(path));
|
||||||
|
MixerMain.display.setCurrent(this);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(21),Constants.getStringName(21)+ ":\n" + e.getMessage() + "\npath=" + path, null, null);
|
||||||
|
MixerMain.display.setCurrent(a, prevDisplay);
|
||||||
|
path = null;
|
||||||
|
selectedFileName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getSelectedFilePath() {
|
||||||
|
if (path == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return path + selectedFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getSelectedFolderPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
154
src/midedit/L.java
Normal file
154
src/midedit/L.java
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Êëàññ òåêñòîâûõ ìåòîê
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class L {
|
||||||
|
|
||||||
|
/** Íîìåðà ñòðîê òåêñòîâûõ ìåòîê */
|
||||||
|
public static final byte
|
||||||
|
create = 0,
|
||||||
|
resume = 1,
|
||||||
|
about = 2,
|
||||||
|
open = 3,
|
||||||
|
save = 4,
|
||||||
|
saveAs = 5,
|
||||||
|
file = 6,
|
||||||
|
options = 7,
|
||||||
|
exit = 8,
|
||||||
|
RMS = 9,
|
||||||
|
cancel = 10,
|
||||||
|
error = 11,
|
||||||
|
openError = 12,
|
||||||
|
toolsList = 13,
|
||||||
|
impossible = 14,
|
||||||
|
saved = 15,
|
||||||
|
savingError = 16,
|
||||||
|
saving = 17,
|
||||||
|
opening = 18,
|
||||||
|
chooserError = 19,
|
||||||
|
updateError = 20,
|
||||||
|
apiError = 21,
|
||||||
|
instruments = 22,
|
||||||
|
menu = 23,
|
||||||
|
back = 24,
|
||||||
|
insertNoteWithCurrentAttributes = 25,
|
||||||
|
noteAttributeHelp = 26,
|
||||||
|
deleteNote = 27,
|
||||||
|
undo = 28,
|
||||||
|
noteVolume = 29,
|
||||||
|
playFromCurrent = 30,
|
||||||
|
playNoteOnCursor = 31,
|
||||||
|
selectNoteAttribute = 32,
|
||||||
|
changeNoteAttribute = 33,
|
||||||
|
stop = 34,
|
||||||
|
navigationOnComposition = 35,
|
||||||
|
quicknav = 36,
|
||||||
|
markBegin = 37,
|
||||||
|
markEnd = 38,
|
||||||
|
copy = 39,
|
||||||
|
pasteInsert = 40,
|
||||||
|
pasteReplace = 41,
|
||||||
|
pasteOverwrite = 42,
|
||||||
|
shiftDelete = 43,
|
||||||
|
clean = 44,
|
||||||
|
playChannelOnScreen = 45,
|
||||||
|
playChannelAll = 46,
|
||||||
|
redo = 47,
|
||||||
|
addInstrument = 48,
|
||||||
|
edit = 49,
|
||||||
|
setInstrument = 50,
|
||||||
|
delInstrument = 51,
|
||||||
|
tempoBox = 52,
|
||||||
|
volumeBox = 53,
|
||||||
|
meter = 54,
|
||||||
|
play = 55,
|
||||||
|
playOrigin = 56,
|
||||||
|
ok = 57,
|
||||||
|
upOneLevel = 58,
|
||||||
|
delete = 59,
|
||||||
|
chooseFolder = 60,
|
||||||
|
openFile = 61,
|
||||||
|
pleaseWait = 62,
|
||||||
|
updatingList = 63,
|
||||||
|
saveInThisFolder = 64,
|
||||||
|
insertTempo = 65,
|
||||||
|
deleteTempo = 66,
|
||||||
|
tempo = 67,
|
||||||
|
time = 68,
|
||||||
|
seek = 69,
|
||||||
|
numerator = 70,
|
||||||
|
denominator = 71,
|
||||||
|
meterInfo = 72,
|
||||||
|
delta = 73,
|
||||||
|
playStop = 74,
|
||||||
|
playAll = 75,
|
||||||
|
playScreen = 76,
|
||||||
|
trackAll = 77,
|
||||||
|
trackScreen = 78,
|
||||||
|
mark = 79,
|
||||||
|
unmark = 80,
|
||||||
|
modifyBlock = 81,
|
||||||
|
modifyMode = 82,
|
||||||
|
paste = 83,
|
||||||
|
insert = 84,
|
||||||
|
replace = 85,
|
||||||
|
blend = 86,
|
||||||
|
removeSelection = 87,
|
||||||
|
help = 88,
|
||||||
|
keymap = 89,
|
||||||
|
quickCommands = 90,
|
||||||
|
navigation = 91,
|
||||||
|
numkeysOptionString = 92,
|
||||||
|
iconsOptionString = 93;
|
||||||
|
|
||||||
|
|
||||||
|
/** Ìàññèâ òåêñòîâûõ ìåòîê */
|
||||||
|
public static String[] str, instr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ïðî÷èòàòü ÿçûêîâîé ðåñóðñ
|
||||||
|
* @param lang èìÿ ëîêàëèçàöèè (en, ru)
|
||||||
|
* @param appLang ÷èòàòü ÿçûêîâîé ðåñóðñ ïðèëîæåíèÿ (true), èíñòðóìåíòîâ (false)
|
||||||
|
*/
|
||||||
|
public static void readLang(String lang, boolean appLang) {
|
||||||
|
try {
|
||||||
|
final String path = (appLang ? "strings" : "instr") + "_";
|
||||||
|
System.out.println("/lang/" + path + lang + ".loc");
|
||||||
|
BufDataInputStream bdis = new BufDataInputStream(Runtime.getRuntime().getClass().getResourceAsStream("/lang/" + path + lang + ".loc"));
|
||||||
|
if (!bdis.checkBOM()) {
|
||||||
|
bdis.close();
|
||||||
|
}
|
||||||
|
char c = ' ';
|
||||||
|
Vector v = new Vector();
|
||||||
|
StringBuffer s;
|
||||||
|
while (bdis.available() > 0) {
|
||||||
|
s = new StringBuffer();
|
||||||
|
do {
|
||||||
|
c = bdis.readCharUTF();
|
||||||
|
if (c == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s.append(c);
|
||||||
|
} while (bdis.available() > 0);
|
||||||
|
v.addElement(s.toString());
|
||||||
|
}
|
||||||
|
if(appLang) {
|
||||||
|
str = new String[v.size()];
|
||||||
|
v.copyInto(str);
|
||||||
|
} else {
|
||||||
|
instr = new String[v.size()];
|
||||||
|
v.copyInto(instr);
|
||||||
|
}
|
||||||
|
bdis.close();
|
||||||
|
v = null;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
219
src/midedit/LangParser.java
Normal file
219
src/midedit/LangParser.java
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
public class LangParser {
|
||||||
|
/**
|
||||||
|
|
||||||
|
<p>Эта версия также демонстрирует простой способ определения
|
||||||
|
локализованных ресурсов. Она считывает файл, который является
|
||||||
|
частью файла JAR приложения (не файла JAD)
|
||||||
|
для загрузки локализованных ресурсов. Файл
|
||||||
|
состоит из набора пар «ключ-значение», одной на строку,
|
||||||
|
которые представляют локализованные строки.
|
||||||
|
MID-лет должен затем проанализировать содержимое файла
|
||||||
|
и создать внутреннюю хэшированную таблицу для поиска.
|
||||||
|
|
||||||
|
<p>Этот подход требует слишком много усилий по обработке
|
||||||
|
потока, который содержит файл
|
||||||
|
локализованных ресурсов. Более того, этот подход
|
||||||
|
не отвечает за локализацию ресурсов, которые
|
||||||
|
не являются строками.
|
||||||
|
*/
|
||||||
|
/** Региональная настройка, указанная для выполнения данного
|
||||||
|
MID-лета.
|
||||||
|
* Извлекает региональную настройку из программного
|
||||||
|
обеспечения AMS. Региональная настройка должна быть
|
||||||
|
установлена до выполнения данного MID-лета.
|
||||||
|
*/
|
||||||
|
int isSupported=1;
|
||||||
|
private int maxSize;
|
||||||
|
String locale,extension;// = System.getProperty("microedition.locale");
|
||||||
|
/** Файл, который содержит ресурсы для
|
||||||
|
активной локальной настройки.
|
||||||
|
* Названия файлов локализованных ресурсов, соответствующих
|
||||||
|
форме: <язык>_<страна>.txt.
|
||||||
|
Создает строку имени файла и передает ее в
|
||||||
|
метод, который открывает файл и извлекает
|
||||||
|
содержимое.
|
||||||
|
|
||||||
|
*/
|
||||||
|
String resourceFile;// ="bin/"+locale + ".lang";
|
||||||
|
/* Символьная кодировка, установленная по умолчанию,
|
||||||
|
используемая данной платформой.
|
||||||
|
* В данном случае не используется
|
||||||
|
*/
|
||||||
|
//private String encoding;
|
||||||
|
/** HashTable, которая содержит локализованные
|
||||||
|
ресурсы.
|
||||||
|
*/
|
||||||
|
String [] stringResourses;
|
||||||
|
/**
|
||||||
|
Конструктор No-arg.
|
||||||
|
Получает текущее название
|
||||||
|
региональной настройки. Использует его для создания
|
||||||
|
имени файла, который содержит локализованные
|
||||||
|
ресурсы региональной настройки. Файл ресурса
|
||||||
|
находится в файле JAR приложения.
|
||||||
|
*/
|
||||||
|
public LangParser(String newLocale,String newExtension, int parSize) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
extension=newExtension;
|
||||||
|
maxSize=parSize;
|
||||||
|
stringResourses = new String [maxSize];
|
||||||
|
setLocale(newLocale,extension);
|
||||||
|
if (isSupported == 0) {
|
||||||
|
//do something, eg. throws Exception or generate Alert;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Выдает значение, связанное с указанным
|
||||||
|
ключом из пакета ресурсов приложения.
|
||||||
|
Если ресурс не найден возвращает указанный ключ
|
||||||
|
|
||||||
|
@param key - ключ пары «ключ-значение».
|
||||||
|
|
||||||
|
@ выдает значение, связанное с
|
||||||
|
указанным ключом.
|
||||||
|
*/
|
||||||
|
public String getStringResourses (int number){
|
||||||
|
if (stringResourses[number] == null || number<0 || number>stringResourses.length) {
|
||||||
|
return "*******";
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringResourses[number];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLocale (String newLocale,String newExtension){
|
||||||
|
locale=newLocale;
|
||||||
|
resourceFile ="/bin/"+locale + "."+newExtension;
|
||||||
|
loadResources(resourceFile);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
Загружает определенные пользователем ресурсы приложения
|
||||||
|
из указанного файла. Файл является частью файла JAR
|
||||||
|
приложения, расположенного на реальном устройстве.
|
||||||
|
J2MEWTK хранит файл в файле JAR приложения, расположенном
|
||||||
|
в директории приложения bin/.
|
||||||
|
|
||||||
|
@param file - имя определенного пользователем файла
|
||||||
|
ресурса приложения.
|
||||||
|
*/
|
||||||
|
private void loadResources(String file) {
|
||||||
|
Class с = getClass();
|
||||||
|
|
||||||
|
if (file == null) {
|
||||||
|
isSupported=0;
|
||||||
|
file=("/bin/en."+extension);
|
||||||
|
}
|
||||||
|
InputStream is = null;
|
||||||
|
is = с.getResourceAsStream(file);
|
||||||
|
if (is == null) {
|
||||||
|
isSupported=0;
|
||||||
|
file=("/bin/en."+extension);
|
||||||
|
}
|
||||||
|
if (is == null){
|
||||||
|
for (int i=0;i<maxSize;i++)
|
||||||
|
stringResourses[i]="******";
|
||||||
|
return;}
|
||||||
|
Reader reader;
|
||||||
|
try{
|
||||||
|
reader = new InputStreamReader(is,"UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException unEncExc){
|
||||||
|
reader = new InputStreamReader(is);
|
||||||
|
}
|
||||||
|
processStream(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
*/
|
||||||
|
private void processStream(Reader stream) {
|
||||||
|
if (stream == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int number=0;
|
||||||
|
StringBuffer value = new StringBuffer();
|
||||||
|
for ( ;number<maxSize;number++) {
|
||||||
|
// Считываем строку. Предполагается, что каждая строка
|
||||||
|
// содержит ключ и значение,
|
||||||
|
// отделенные двоеточием. Если -1, значит
|
||||||
|
// мы достигли конца файла.
|
||||||
|
value.delete(0, value.length());
|
||||||
|
int status = readLine(value, stream);
|
||||||
|
if (status == -1){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Вставляем этот ресурс в хэшированную таблицу
|
||||||
|
// ресурсов приложения.
|
||||||
|
try {
|
||||||
|
stringResourses[number]=value.toString();
|
||||||
|
}
|
||||||
|
catch (NullPointerException npe){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( ;number<maxSize;number++) {
|
||||||
|
stringResourses[number]="***";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Считывает и обрабатывает следующую не пустую строку
|
||||||
|
из потока. Формат строки ожидается следующий
|
||||||
|
<ключ>[ \t]*:[ и]*<значение>, где
|
||||||
|
<ключ> and <значение> являются метками, состоящими
|
||||||
|
из буквенных символов или знаков пунктуации, но не
|
||||||
|
из пустых знаков пробела.
|
||||||
|
*/
|
||||||
|
private int readLine(
|
||||||
|
StringBuffer value,
|
||||||
|
Reader stream) {
|
||||||
|
if (value == null ||
|
||||||
|
stream == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
char c=0;
|
||||||
|
try{
|
||||||
|
while (true){
|
||||||
|
c=(char)stream.read();
|
||||||
|
if (c==0x0D||c==0x0A){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
if (c==0x0D||c==0x0A||c==-1||c==0xffff){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value.append (c);
|
||||||
|
//System.out.println (value.toString()+" "+locale+"."+extension+" c="+(int)c);
|
||||||
|
c=(char)stream.read();
|
||||||
|
}
|
||||||
|
} catch (OutOfMemoryError ome){
|
||||||
|
//System.out.println ("OutOfMemoryError "+locale+"."+extension);
|
||||||
|
}
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
//ioe.printStackTrace();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (value==null)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
716
src/midedit/MidiFile.java
Normal file
716
src/midedit/MidiFile.java
Normal file
@ -0,0 +1,716 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
import midedit.io.AbstractFile;
|
||||||
|
import java.io.*;
|
||||||
|
//import com.siemens.mp.io.File;
|
||||||
|
|
||||||
|
public class MidiFile implements Waitable {
|
||||||
|
|
||||||
|
private String outStr;
|
||||||
|
private String url;
|
||||||
|
// private static File file = null;
|
||||||
|
private static AbstractFile file = null;
|
||||||
|
//private MixerModel mod;
|
||||||
|
private int seekPos = 0;
|
||||||
|
private int seekLen = 1;
|
||||||
|
private int maxTime = 0;
|
||||||
|
private boolean cancelStatus;
|
||||||
|
// private final int size = 49;
|
||||||
|
private final static int sizeMax/*=200000;*/ = 15000;
|
||||||
|
//private static int temp = 0x123456;
|
||||||
|
private static byte[] MTHD = {0x4D, 0x54, 0x68, 0x64};
|
||||||
|
private static byte[] MTRK = {0x4d, 0x54, 0x72, 0x6b};
|
||||||
|
private static byte[] ENDTrk = {0x00, -0x01, 0x2f, 0x00};
|
||||||
|
private static byte[] dat4PlayNote = {
|
||||||
|
77, 84, 104, 100, 0, 0, 0, 6,//7
|
||||||
|
0, 0, 0, 1, 0, 96, 77, 84,//15
|
||||||
|
114, 107, 0, 0, 0, 38, 0, -1,//23
|
||||||
|
88, 4, 4, 2, 24, 8, 0, -1,//31
|
||||||
|
81, 3, 33, -14, -13, 0, -64, 26,//39//instr
|
||||||
|
0, -112, 46, 1, 8, -103/*0x90*/, 46/*note height*/, 127,//55
|
||||||
|
127, -112/*0x80*/, 46, 1, 16, -112, 46/*note height*/, 1,//63
|
||||||
|
0, -1, 47, 0,};
|
||||||
|
//{0x4D,0x54,0x68,0x64,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x1,0x0,0x60,
|
||||||
|
//0x4d,0x54,0x72,0x6b,0x0,0x0,0x0,0x26/*len*/,0x0,0xff,0x58,0x04,0x04,0x02,0x18,0x08,
|
||||||
|
//0x0,0xff,0x51,0x03, /*temp->*/0x21,0xf2,0xf3,/*<-*/
|
||||||
|
///*37>*/0x00,0xc0,0x1a, /*40>*/0x00,0x90,0x2e,0x01,
|
||||||
|
//0x08,0x99,0x2e,0x7f, 0x7f,0x90,0x2e,0x01,
|
||||||
|
//0x10,0x90,0x2e,0x01, 0x00,0xff,0x2f,0x00};
|
||||||
|
private static byte[] bufTmp = new byte[16];
|
||||||
|
private static int intTmp;
|
||||||
|
private static byte[] bMidi = new byte[sizeMax];
|
||||||
|
|
||||||
|
//public static void setTemp(int t)
|
||||||
|
//{ temp = t; }
|
||||||
|
//public static int getTemp()
|
||||||
|
//{ return temp; }
|
||||||
|
public MidiFile(AbstractFile aFile) {
|
||||||
|
file = aFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean increaseBuffer() {
|
||||||
|
int prevLen = bMidi.length;
|
||||||
|
int nextLen;
|
||||||
|
if (prevLen > 32000) {
|
||||||
|
nextLen = prevLen + 32000;
|
||||||
|
} else {
|
||||||
|
nextLen = prevLen * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] newarr;
|
||||||
|
try {
|
||||||
|
newarr = new byte[nextLen];
|
||||||
|
System.arraycopy(bMidi, 0, newarr, 0, bMidi.length);
|
||||||
|
bMidi = newarr;
|
||||||
|
//System.out.println("bMidi.length="+bMidi.length);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
//System.out.println(""+e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile() {
|
||||||
|
file = MixerModel.isRMSMode ? MixerModel.rmsFile : MixerModel.jsr75File;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String writeMix(Composition c, int t, boolean forPlay) throws Exception {
|
||||||
|
return writeMixWithName(c, t, forPlay, "out.mid", -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String writeMixWithName(Composition c, int tBeg, boolean forPlay, String name) throws Exception {
|
||||||
|
return writeMixWithName(c, tBeg, forPlay, name, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//public String writeMixWithName(Composition c,int tBeg, boolean forPlay, String name,int channel)throws Exception{
|
||||||
|
//return writeMixWithName(c,tBeg,forPlay,name,channel, -1);
|
||||||
|
//}
|
||||||
|
public String writeMixWithName(Composition c, int tBeg, boolean forPlay, String name, int channel, int instrument) throws Exception {
|
||||||
|
System.gc();
|
||||||
|
outStr = name;
|
||||||
|
//byte[] tnote;
|
||||||
|
int iMidi; // index of b
|
||||||
|
int i;//,ind;
|
||||||
|
//Note note;
|
||||||
|
|
||||||
|
iMidi = 0;
|
||||||
|
//// begin header -------------------------
|
||||||
|
/// print MThd (4)
|
||||||
|
for (i = 0; i < MTHD.length; ++i) {
|
||||||
|
bMidi[iMidi++] = MTHD[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// print header lenght (4)
|
||||||
|
bMidi[iMidi] = 0;
|
||||||
|
bMidi[iMidi + 1] = 0;
|
||||||
|
bMidi[iMidi + 2] = 0;
|
||||||
|
bMidi[iMidi + 3] = 6; /// always =6
|
||||||
|
iMidi += 4;
|
||||||
|
|
||||||
|
/// print format (2)
|
||||||
|
bMidi[iMidi] = 0;
|
||||||
|
bMidi[iMidi + 1] = 1;
|
||||||
|
iMidi += 2;
|
||||||
|
|
||||||
|
/// print num track (2)
|
||||||
|
int numTracks = 0;
|
||||||
|
NoteList curList;
|
||||||
|
//// print tracks
|
||||||
|
seekLen = 1;
|
||||||
|
seekPos = 1;
|
||||||
|
int lastTrack = 0;
|
||||||
|
if (channel == -1) {
|
||||||
|
for (i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
curList = c.getNoteListByChannel(i);
|
||||||
|
seekLen += curList.getLen();
|
||||||
|
if (curList.getLen() > 0 && (!forPlay || c.isPlayChan(i))) {
|
||||||
|
numTracks++;
|
||||||
|
lastTrack = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
curList = c.getNoteListByChannel(channel);
|
||||||
|
seekLen += curList.getLen();
|
||||||
|
if (curList.getLen() > 0 && (!forPlay || c.isPlayChan(i))) {
|
||||||
|
numTracks++;
|
||||||
|
lastTrack = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bMidi[iMidi] = 0;
|
||||||
|
bMidi[iMidi + 1] = (byte) numTracks;
|
||||||
|
iMidi += 2;
|
||||||
|
|
||||||
|
/// print tick per quart (2)
|
||||||
|
short ticks = c.getTicksPer4();
|
||||||
|
bMidi[iMidi] = (byte) (ticks / 256);
|
||||||
|
bMidi[iMidi + 1] = (byte) (ticks % 256);
|
||||||
|
iMidi += 2;
|
||||||
|
|
||||||
|
/// end header -------------------
|
||||||
|
|
||||||
|
cancelStatus = false;
|
||||||
|
maxTime = 0; // global var
|
||||||
|
boolean isLastTrack = false;
|
||||||
|
if (channel == -1) {
|
||||||
|
for (i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
curList = c.getNoteListByChannel(i);
|
||||||
|
if (curList.getLen() > 0 && (!forPlay || c.isPlayChan(i))) { // track is not empty
|
||||||
|
if (i == lastTrack) {
|
||||||
|
isLastTrack = true;
|
||||||
|
}
|
||||||
|
int numByte = writeTrack(c, i, tBeg, iMidi, forPlay, isLastTrack, instrument);
|
||||||
|
iMidi += numByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
curList = c.getNoteListByChannel(channel);
|
||||||
|
if (curList.getLen() > 0 && (!forPlay || c.isPlayChan(i))) { // track is not empty
|
||||||
|
isLastTrack = true;
|
||||||
|
int numByte = writeTrack(c, channel, tBeg, iMidi, forPlay, isLastTrack, instrument);
|
||||||
|
iMidi += numByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// end print
|
||||||
|
int df = 0;
|
||||||
|
try {
|
||||||
|
/*if(file == null)
|
||||||
|
//file = new File();
|
||||||
|
file = new SiemensFile();*/
|
||||||
|
try {
|
||||||
|
if (file.exists(outStr) >= 0) {
|
||||||
|
file.delete(outStr);
|
||||||
|
}
|
||||||
|
} catch (/*IllegalArgument*/Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
df = file.open(outStr, true);
|
||||||
|
|
||||||
|
url = file.getURL();
|
||||||
|
|
||||||
|
file.write(df, bMidi, 0, iMidi);
|
||||||
|
file.close(df);
|
||||||
|
return file.getAns();
|
||||||
|
} catch (IOException e) {
|
||||||
|
//throw new Exception("IO:writeMixWithName()\n"+e.toString()+"\noutStr="+outStr);
|
||||||
|
throw new Exception("Can't write " + outStr);
|
||||||
|
} finally {
|
||||||
|
//file.close(df);
|
||||||
|
seekPos = seekLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int writeTrack(Composition c, int ch, int tBeg, int begInd, boolean forPlay, boolean isLastTrack, int instrument) throws Exception {
|
||||||
|
int ind = begInd;
|
||||||
|
int i;
|
||||||
|
/// track --------------
|
||||||
|
/// print MTrk (4)
|
||||||
|
for (i = 0; i < MTRK.length; ++i) {
|
||||||
|
bMidi[ind++] = MTRK[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// print track lenght (4)
|
||||||
|
int lenInd = ind;
|
||||||
|
//// write later
|
||||||
|
ind += 4;
|
||||||
|
int msgBegInd = ind;
|
||||||
|
if (instrument == -1) {
|
||||||
|
instrument = c.getInstrument(ch);
|
||||||
|
}
|
||||||
|
if (instrument != Composition.NOTHING && instrument != -1/*Drums*/) {
|
||||||
|
bMidi[ind] = (byte) 0;
|
||||||
|
bMidi[ind + 1] = (byte) (0xc0 | (0x0f & ch));
|
||||||
|
bMidi[ind + 2] = (byte) (instrument);
|
||||||
|
ind += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//NoteList notes = c.getNoteListByChannel(ch);
|
||||||
|
|
||||||
|
/// print notes
|
||||||
|
|
||||||
|
byte[] volumeExpArr = c.getVolumeExpArr();
|
||||||
|
|
||||||
|
//int iMax = bMidi.length - 200;
|
||||||
|
/* seekLen = mix.getLen()+1;
|
||||||
|
seekPos = 1;
|
||||||
|
cancelStatus = false;*/
|
||||||
|
int vol;
|
||||||
|
int kVol = 256 / c.channelVolExpMax;
|
||||||
|
byte[] tnote;
|
||||||
|
int tPrev = tBeg;
|
||||||
|
|
||||||
|
if (forPlay/* && false*/) {
|
||||||
|
int dTime = 2 * Constants.timeConst;
|
||||||
|
tnote = getVarLenRepr(/*dTime*/0); // Delta-Time
|
||||||
|
for (i = tnote.length - 1; i >= 0; --i, ++ind) {
|
||||||
|
bMidi[ind] = tnote[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//bMidi[ind++] = (byte) (Constants.timeConst * 2) + maxTime - tPrev;
|
||||||
|
bMidi[ind++] = (byte) (ch | ((byte) 0x90/*0x80*/));
|
||||||
|
//bMidi[ind++] = (byte) 0x99;
|
||||||
|
bMidi[ind++] = (byte) 0x2e;
|
||||||
|
bMidi[ind++] = (byte) 0x01;
|
||||||
|
|
||||||
|
tnote = getVarLenRepr(/*dTime*/dTime - 0); // Delta-Time
|
||||||
|
for (i = tnote.length - 1; i >= 0; --i, ++ind) {
|
||||||
|
bMidi[ind] = tnote[i];
|
||||||
|
}
|
||||||
|
bMidi[ind++] = (byte) (ch | ((byte) 0x80));
|
||||||
|
//bMidi[ind++] = (byte) 0x99;
|
||||||
|
bMidi[ind++] = (byte) 0x2e;
|
||||||
|
bMidi[ind++] = (byte) 0x00;
|
||||||
|
|
||||||
|
|
||||||
|
//tPrev -= dTime;
|
||||||
|
//tPrev =0;
|
||||||
|
}
|
||||||
|
for (Note note = c.getFirstNote(tBeg, ch); note != null; note = note.prev) {
|
||||||
|
if (note instanceof NoteLong) {
|
||||||
|
NoteLong tempoNote = (NoteLong) note;
|
||||||
|
byte[] dat = tempoNote.dat;
|
||||||
|
if ((dat[0] == (byte) 0xff && dat[1] == (byte) 0x51)) { //////write tempo
|
||||||
|
bMidi[ind++] = (byte) 0x0;
|
||||||
|
for (i = 0; i < dat.length; ++i, ind++) {
|
||||||
|
bMidi[ind] = dat[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Note note = c.getFirstNote(tBeg, ch); note != null/* && ind<iMax*/; note = note.next) {
|
||||||
|
if (cancelStatus) {
|
||||||
|
throw new Exception("Cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ind >= bMidi.length - 400) {
|
||||||
|
if (increaseBuffer() == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// calc maxTime for set end Note
|
||||||
|
if (note.t > maxTime) {
|
||||||
|
maxTime = note.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
tnote = getVarLenRepr(note.t - tPrev); // Delta-Time
|
||||||
|
if (tnote.length == 0) {
|
||||||
|
throw new Exception("len==0");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = tnote.length - 1; i >= 0; --i, ++ind) {
|
||||||
|
bMidi[ind] = tnote[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note instanceof NoteLong) {
|
||||||
|
NoteLong notelong = (NoteLong) note;
|
||||||
|
for (i = 0; i < notelong.dat.length; ++i, ind++) {
|
||||||
|
bMidi[ind] = notelong.dat[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else // simple Note
|
||||||
|
{
|
||||||
|
|
||||||
|
bMidi[ind] = (byte) (note.c | ((note.v == 0) ? (byte) 0x80 : (byte) 0x90));
|
||||||
|
|
||||||
|
//bMidi[iMidi]=(byte)0x99; // 0x99 -- Note On
|
||||||
|
bMidi[ind + 1] = note.n;
|
||||||
|
//bMidi[iMidi+2]=note.v; edit 08.07.2004
|
||||||
|
if ((note.v & 0x80) != 0) {
|
||||||
|
note.v = 0x7f;
|
||||||
|
}
|
||||||
|
vol = note.v + kVol * (volumeExpArr[note.c] - c.channelVolExpMax / 2); //*( 1<<(volumeExpArr[note.c]/2))/0x10000;
|
||||||
|
if (vol > 127) {
|
||||||
|
vol = 127;
|
||||||
|
} else if (vol < 0) {
|
||||||
|
vol = 0;
|
||||||
|
}
|
||||||
|
bMidi[ind + 2] = (byte) vol;
|
||||||
|
///////////
|
||||||
|
ind += 3;
|
||||||
|
}
|
||||||
|
tPrev = note.t;
|
||||||
|
seekPos++;
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
/// print last note
|
||||||
|
if (forPlay && isLastTrack/* && false*/) {
|
||||||
|
tnote = getVarLenRepr((Constants.timeConst * 2) + maxTime - tPrev); // Delta-Time
|
||||||
|
for (i = tnote.length - 1; i >= 0; --i, ++ind) {
|
||||||
|
bMidi[ind] = tnote[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//bMidi[ind++] = (byte) (Constants.timeConst * 2) + maxTime - tPrev;
|
||||||
|
bMidi[ind++] = (byte) 0x99;
|
||||||
|
bMidi[ind++] = (byte) 0x2e;
|
||||||
|
bMidi[ind++] = (byte) 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// print end track (4)
|
||||||
|
for (i = 0; i < ENDTrk.length; ++i) {
|
||||||
|
bMidi[ind++] = ENDTrk[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
writeIntBigEnding(bMidi, lenInd, ind - msgBegInd, 4); ///////?????
|
||||||
|
|
||||||
|
return ind - begInd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeIntBigEnding(byte[] dest, int begInd, int src, int numBytesToWrite) {
|
||||||
|
int t = src;
|
||||||
|
int ind = begInd + numBytesToWrite - 1;
|
||||||
|
for (; ind >= begInd; --ind) {
|
||||||
|
dest[ind] = (byte) t;
|
||||||
|
t >>= 8;
|
||||||
|
}
|
||||||
|
return /*numBytesToWrite*/;
|
||||||
|
}
|
||||||
|
// private byte getVolume
|
||||||
|
|
||||||
|
public byte[] writeNote(byte instr, byte nn)//+
|
||||||
|
{
|
||||||
|
// outStr = ""+nn+".mid";
|
||||||
|
//outStr = "note.mid";
|
||||||
|
// mod.msg("len dat ."+dat.length+" ");
|
||||||
|
//byte[] b = new byte[dat4PlayNote.length];
|
||||||
|
//for(int i=0; i<dat4PlayNote.length; ++i){
|
||||||
|
//b[i] = (byte)dat4PlayNote[i];
|
||||||
|
//System.out.print (b[i]+",");
|
||||||
|
//}
|
||||||
|
byte[] b = dat4PlayNote;
|
||||||
|
// System.out.println("b[39] = " + b[39]);
|
||||||
|
// System.out.println("b[45] = " + b[45]);
|
||||||
|
// System.out.println("b[49] = " + b[49]);
|
||||||
|
if (instr >= 0) {
|
||||||
|
b[39] = (byte) instr;
|
||||||
|
b[41 + 4] = (byte) (0x90);
|
||||||
|
b[45 + 4] = (byte) (0x80);
|
||||||
|
} else {
|
||||||
|
b[39] = 26;
|
||||||
|
b[45] = -103;
|
||||||
|
b[49] = -112;
|
||||||
|
}
|
||||||
|
b[39 + 3 + 4] = nn; // offset 39 -- note number
|
||||||
|
b[43 + 3 + 4] = nn;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] writeTest(byte instr) {
|
||||||
|
outStr = "test.mid";
|
||||||
|
//int df=0;
|
||||||
|
InputStream is = getClass().getResourceAsStream("/bin/test.mid");
|
||||||
|
byte b[] = new byte[148];
|
||||||
|
try {
|
||||||
|
is.read(b);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
}
|
||||||
|
b[24] = instr;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
private /*static*/ byte[] getVarLenRepr(int t) {
|
||||||
|
// if(t<0)
|
||||||
|
// mod.msgAll("Repr\nt="+t);
|
||||||
|
int tt = t;
|
||||||
|
if (tt < 0) {
|
||||||
|
tt = 0;
|
||||||
|
}
|
||||||
|
int i, end = 0; // 0 1 2 3
|
||||||
|
byte[] b = {0, -128, -128, -128}; // -128 == 0x80
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
b[i] |= (byte) (tt & 0x7f);
|
||||||
|
tt >>= 7;
|
||||||
|
if (tt == 0) {
|
||||||
|
end = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] r = new byte[end];
|
||||||
|
for (i = 0; i < r.length; ++i) {
|
||||||
|
r[i] = b[i];
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
// public int getTimeFromVLR(byte[] b)
|
||||||
|
// {
|
||||||
|
// int time=0;
|
||||||
|
// for(int i=0; i<b.length; ++i)
|
||||||
|
// {
|
||||||
|
// time = (time<<7) + (b[i] & 0x7f);
|
||||||
|
// }
|
||||||
|
// return time;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public String getURI() {
|
||||||
|
//return "file://"+outStr;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Composition readMix(String path) throws Exception {
|
||||||
|
// mod.msgAll("name="+name);
|
||||||
|
String name = /*file.getPrefix() + */ path;
|
||||||
|
int gcCount = 0;
|
||||||
|
System.gc();
|
||||||
|
Composition composition = new Composition();
|
||||||
|
//byte[] buf=null;
|
||||||
|
int df = 0;
|
||||||
|
try {
|
||||||
|
/*if(file == null)
|
||||||
|
//file = new File();
|
||||||
|
file = new SiemensFile();*/
|
||||||
|
//try
|
||||||
|
{
|
||||||
|
if (file.exists(name) < 0) {
|
||||||
|
throw new IOException("File not found");
|
||||||
|
}
|
||||||
|
// File.delete(outStr);
|
||||||
|
}
|
||||||
|
//catch (IllegalArgumentException e) {}
|
||||||
|
|
||||||
|
df = file.open(name, false);
|
||||||
|
seekLen = file.length(df);
|
||||||
|
seekPos = 0;
|
||||||
|
cancelStatus = false;
|
||||||
|
// if(df==df)
|
||||||
|
// throw new IOException("df="+df);
|
||||||
|
|
||||||
|
int d = 0x4d546864; // MThd
|
||||||
|
int t = readInt(df, 4);
|
||||||
|
if (t != d) {
|
||||||
|
throw new IOException(/*"Not Found MThd"*/"Can't read file");
|
||||||
|
}
|
||||||
|
t = readInt(df, 4);
|
||||||
|
if (t != 6) {
|
||||||
|
throw new IOException("len MThd=" + t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//skip(df,t);
|
||||||
|
int format = readInt(df, 2);
|
||||||
|
if (format > 1) {
|
||||||
|
throw new IOException("Format=" + format + "\nthis format don't support");
|
||||||
|
}
|
||||||
|
int numTrk = readInt(df, 2);
|
||||||
|
if (format == 0 && numTrk != 1) {
|
||||||
|
throw new IOException("ntrk=" + numTrk);
|
||||||
|
}
|
||||||
|
t = readInt(df, 2);
|
||||||
|
composition.setTicksPer4(t);
|
||||||
|
|
||||||
|
// format 1
|
||||||
|
for (int indTrk = 0; indTrk < numTrk; ++indTrk) {
|
||||||
|
d = 0x4d54726b; // MTrk
|
||||||
|
t = readInt(df, 4);
|
||||||
|
if (t != d) //throw new IOException("(2)Not Found MTrk \n"+"pos="
|
||||||
|
//+seekPos+"/"+seekLen+"\nind="+indTrk+"/"+numTrk+"mtrk="+t);
|
||||||
|
{
|
||||||
|
throw new IOException("Track not found");
|
||||||
|
}
|
||||||
|
t = readInt(df, 4); // length of track
|
||||||
|
boolean hasMoreNotes = true;
|
||||||
|
int timeDelta, timeAbs = 0;
|
||||||
|
int dPrev = 0;
|
||||||
|
int d1 = 0;
|
||||||
|
int d1h;
|
||||||
|
int d2;
|
||||||
|
int temp;
|
||||||
|
int n;
|
||||||
|
int datInt;
|
||||||
|
int datInt2;
|
||||||
|
|
||||||
|
byte channel;
|
||||||
|
byte note;
|
||||||
|
byte vel;
|
||||||
|
byte instrum;
|
||||||
|
|
||||||
|
while (hasMoreNotes) {
|
||||||
|
if (cancelStatus) {
|
||||||
|
throw new Exception("Cancel");
|
||||||
|
}
|
||||||
|
gcCount++;
|
||||||
|
if (gcCount % 150 == 0) {
|
||||||
|
if (gcCount % 1000 == 0) {
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
//mod.listener.setPercent(seekPos*100/fileLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeDelta = readTimeDelta(df);
|
||||||
|
timeAbs += timeDelta;
|
||||||
|
d = readInt(df, 1);
|
||||||
|
boolean isFBN = (d & 0x80) == 0x00; // FBN = first bit null
|
||||||
|
if (isFBN) {
|
||||||
|
if (dPrev == 0) //throw new IOException("Default no Repeat tA=" + timeAbs + "\nd=" + d);
|
||||||
|
{
|
||||||
|
throw new IOException("File corrupted");
|
||||||
|
}
|
||||||
|
d1 = dPrev;
|
||||||
|
d2 = d;
|
||||||
|
} else {
|
||||||
|
d1 = d;
|
||||||
|
d2 = readInt(df, 1);
|
||||||
|
}
|
||||||
|
d1h = d1 & 0xf0;
|
||||||
|
switch (d1h) {
|
||||||
|
case 0x90:
|
||||||
|
case 0x80:
|
||||||
|
channel = (byte) (d1 & 0x0f);
|
||||||
|
note = (byte) d2; //(readInt(df,1));
|
||||||
|
vel = (byte) (readInt(df, 1));
|
||||||
|
if (d1h == 0x90 && vel != 0) {
|
||||||
|
if (composition.getInstrument(channel)
|
||||||
|
== Composition.NOTHING) {
|
||||||
|
composition.setInstrument(channel, 0);
|
||||||
|
}
|
||||||
|
composition.addNoteOn(timeAbs, channel, note,
|
||||||
|
vel, 0/*Constants.timeConst*/, false);
|
||||||
|
//throw new IOException("Note ON tA="+timeAbs);
|
||||||
|
} else // if(channel != Constants.DRUMS_CHANNEL)
|
||||||
|
{
|
||||||
|
composition.addNoteOff(timeAbs, channel, note);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0xc0:
|
||||||
|
channel = (byte) (d1 & 0x0f);
|
||||||
|
instrum = (byte) d2; //(readInt(df,1));
|
||||||
|
if (channel != Constants.DRUMS_CHANNEL) {
|
||||||
|
composition.setInstrument(channel, instrum);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0xa0:
|
||||||
|
skip(df, 2 - 1);
|
||||||
|
break;
|
||||||
|
case 0xb0:
|
||||||
|
skip(df, 2 - 1);
|
||||||
|
break;
|
||||||
|
//case 0xd0:
|
||||||
|
// break;
|
||||||
|
case 0xe0:
|
||||||
|
skip(df, 2 - 1);
|
||||||
|
break;
|
||||||
|
case 0xf0:
|
||||||
|
switch (d1) {
|
||||||
|
case 0xff: // meta-events
|
||||||
|
switch (d2) {
|
||||||
|
case 0x58: // Time Signature
|
||||||
|
n = readInt(df, 1); // n == 4
|
||||||
|
datInt = readInt(df, 1);
|
||||||
|
datInt2 = readInt(df, 1);
|
||||||
|
composition.setMeter(datInt, datInt2);
|
||||||
|
//----
|
||||||
|
skip(df, 2);
|
||||||
|
break;
|
||||||
|
case 0x51: // Set tempo
|
||||||
|
skip(df, 1); // 0x03 - lenght
|
||||||
|
temp = readInt(df, 3);
|
||||||
|
//composition.setTemp(temp);
|
||||||
|
composition.addTemp(timeAbs, temp);
|
||||||
|
break;
|
||||||
|
case 0x2f:
|
||||||
|
skip(df, 1);
|
||||||
|
hasMoreNotes = false;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
n = readInt(df, 1);
|
||||||
|
skip(df, n);
|
||||||
|
// throw new IOException("Default 0xFF tA="+timeAbs+"\nd2="+d2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xf0:
|
||||||
|
do {
|
||||||
|
datInt = readInt(df, 1);
|
||||||
|
} while (datInt != 0xf7);
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
n = d2; // readInt(df,1);
|
||||||
|
skip(df, n);
|
||||||
|
// throw new IOException("Default tA="+timeAbs+"\nd="+d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//throw new IOException("Default(2) tA=" + timeAbs + "\nd=" + d);
|
||||||
|
throw new IOException("File corrupted");
|
||||||
|
}
|
||||||
|
dPrev = d1;
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//file.close(df);
|
||||||
|
} catch (IOException e) {// mod.msgAll("Open:"+e);
|
||||||
|
//throw new Exception("<"+e.toString()+">");
|
||||||
|
throw new Exception("Can't read:\n" + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
file.close(df);
|
||||||
|
seekPos = seekLen;
|
||||||
|
}
|
||||||
|
// mod.msgAll("mix.add ok");
|
||||||
|
// Composition c = new Composition(mix);
|
||||||
|
return composition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int readTimeDelta(int df) throws IOException {
|
||||||
|
int timeDelta = 0;
|
||||||
|
//int i=0;
|
||||||
|
byte[] buf = new byte[1];
|
||||||
|
do {
|
||||||
|
file.read(df, buf, 0, 1);
|
||||||
|
timeDelta = (timeDelta << 7) + (buf[0] & (byte) 0x7f);
|
||||||
|
//i++;
|
||||||
|
seekPos++;
|
||||||
|
} while ((buf[0] & (byte) 0x80) != 0);
|
||||||
|
|
||||||
|
return timeDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int readInt(int df, int len) throws IOException {
|
||||||
|
// byte[] buf = new byte[1];
|
||||||
|
int t = 0;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
file.read(df, bufTmp, 0, 1);
|
||||||
|
t = (t << 8) | 0xff & bufTmp[0];
|
||||||
|
}
|
||||||
|
seekPos += len;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skip(int df, int n) throws IOException {
|
||||||
|
/* if(n>0)
|
||||||
|
{
|
||||||
|
byte[] buf = new byte[n];
|
||||||
|
file.read(df, bufTmp,0,n);
|
||||||
|
seekPos += n;
|
||||||
|
}*/
|
||||||
|
while (n > 0) {
|
||||||
|
intTmp = (n > bufTmp.length) ? bufTmp.length : n;
|
||||||
|
file.read(df, bufTmp, 0, intTmp);
|
||||||
|
seekPos += intTmp;
|
||||||
|
n -= intTmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurPercent() {
|
||||||
|
return seekPos * 100 / seekLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
seekPos = 0;
|
||||||
|
seekLen = 4;
|
||||||
|
cancelStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
cancelStatus = true;
|
||||||
|
}
|
||||||
|
}
|
1766
src/midedit/MixerCanvas.java
Normal file
1766
src/midedit/MixerCanvas.java
Normal file
File diff suppressed because it is too large
Load Diff
404
src/midedit/MixerMain.java
Normal file
404
src/midedit/MixerMain.java
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import javax.microedition.midlet.*;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class MixerMain extends MIDlet implements CommandListener, AbstractListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ìàëåíüêèé øðèôò
|
||||||
|
*/
|
||||||
|
public static final Font SMALL_FONT = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
|
||||||
|
|
||||||
|
|
||||||
|
static MIDlet curMIDlet;
|
||||||
|
static Display display;
|
||||||
|
|
||||||
|
private static final int CREATE_NEW = 0;
|
||||||
|
private static final int RESUME = 1;
|
||||||
|
private static final int OPEN = 2;
|
||||||
|
private static final int SAVE = 3;
|
||||||
|
private static final int SAVE_AS = 4;
|
||||||
|
private static final int RMS_FS = 5;
|
||||||
|
private static final int OPTIONS = 6;
|
||||||
|
private static final int ABOUT = 7;
|
||||||
|
private static final int EXIT = 8;
|
||||||
|
|
||||||
|
private Item[] items;
|
||||||
|
private Item itemsRMS;
|
||||||
|
private Image[] iconsImgs;
|
||||||
|
private TextBox textBoxSave;
|
||||||
|
private String openSaveString;
|
||||||
|
private MixerModel model;
|
||||||
|
private Settings settings;
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private CompositionForm compositionForm;
|
||||||
|
private FileChooser chooser;
|
||||||
|
//static boolean isRMSMode = false;
|
||||||
|
private static Form aboutForm;
|
||||||
|
private static Screen iconsMenu;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static int ifFirstReturn = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public MixerMain() {
|
||||||
|
curMIDlet = MixerMain.this;
|
||||||
|
display = Display.getDisplay(MixerMain.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void startApp() {
|
||||||
|
Rms.restoreOptions();
|
||||||
|
L.readLang(Rms.languageApp, true);
|
||||||
|
//L.readLang(Rms.languageInstr, false);
|
||||||
|
settings = new Settings(MixerMain.this);
|
||||||
|
model = new MixerModel();
|
||||||
|
readImages();
|
||||||
|
createMenu();
|
||||||
|
display.setCurrent(iconsMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void pauseApp() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param unconditional
|
||||||
|
*/
|
||||||
|
public void destroyApp(boolean unconditional) {
|
||||||
|
if(Rms.firstStart) Rms.firstStart = false;
|
||||||
|
Rms.saveOptions();
|
||||||
|
notifyDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ïîëó÷èòü èçîáðàæåíèÿ èêîíîê ìåíþ
|
||||||
|
*/
|
||||||
|
private void readImages() {
|
||||||
|
iconsImgs = new Image[9];
|
||||||
|
for (int i = 0; i < iconsImgs.length; i++) {
|
||||||
|
try {
|
||||||
|
iconsImgs[i] = Image.createImage("/img/main/"+i+".png");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
iconsImgs[i] = Image.createImage(1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ñîçäàòü ìåíþ (èêîíêè, List ñ èêîíêàìè, List áåç èêîíîê)
|
||||||
|
*/
|
||||||
|
private void createMenu() {
|
||||||
|
try {
|
||||||
|
iconsMenu = createListMenu(true);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
iconsMenu = createListMenu(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param names
|
||||||
|
* @param cl
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List createListMenu(boolean withImgs) {
|
||||||
|
String[] menuNames = {
|
||||||
|
L.str[L.create],
|
||||||
|
L.str[L.resume],
|
||||||
|
L.str[L.open],
|
||||||
|
L.str[L.save],
|
||||||
|
L.str[L.saveAs],
|
||||||
|
L.str[L.file],
|
||||||
|
L.str[L.options],
|
||||||
|
L.str[L.about]
|
||||||
|
/*Constants.getStringName(1),
|
||||||
|
Constants.getStringName(2),
|
||||||
|
Constants.getStringName(3),
|
||||||
|
Constants.getStringName(4),
|
||||||
|
Constants.getStringName(5),
|
||||||
|
Constants.getStringName(6),
|
||||||
|
Constants.getStringName(7),
|
||||||
|
Constants.getStringName(8),*/
|
||||||
|
};
|
||||||
|
List list = new List("MIDEdit", 3, menuNames, withImgs ? iconsImgs : null);
|
||||||
|
list.setCommandListener(this);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* @param appearanceMode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Item createStringItem(String text, int appearanceMode) {
|
||||||
|
StringItem strItem = new StringItem(null, text, appearanceMode);
|
||||||
|
strItem.setFont(SMALL_FONT);
|
||||||
|
return strItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param d
|
||||||
|
*/
|
||||||
|
public void commandAction(Command c, Displayable d) {
|
||||||
|
if (d == iconsMenu) {
|
||||||
|
try {
|
||||||
|
actionPerformed(((List) iconsMenu).getSelectedIndex());
|
||||||
|
return;
|
||||||
|
} catch (ClassCastException clasCastE) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
actionPerformed(c.getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param itemNum
|
||||||
|
*/
|
||||||
|
public void actionPerformed(int itemNum) {
|
||||||
|
switch (itemNum) {
|
||||||
|
case CREATE_NEW:
|
||||||
|
try {
|
||||||
|
model.newMix();
|
||||||
|
if (compositionForm != null) {
|
||||||
|
compositionForm.releaseMem();
|
||||||
|
}
|
||||||
|
compositionForm = null;
|
||||||
|
System.gc();
|
||||||
|
openSaveString = "newmix";
|
||||||
|
MixerModel.isRMSMode = true;
|
||||||
|
compositionForm = new CompositionForm(this);
|
||||||
|
if (compositionForm == null) {
|
||||||
|
throw new Exception("compositionForm == null");
|
||||||
|
}
|
||||||
|
display.setCurrent(compositionForm);
|
||||||
|
new Thread(compositionForm).start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Alert a = new Alert(Constants.getStringName(12), e.getMessage(), null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RESUME:
|
||||||
|
if (ifFirstReturn == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MixerModel.isRMSMode = true;
|
||||||
|
display.setCurrent(compositionForm);
|
||||||
|
break;
|
||||||
|
case ABOUT:
|
||||||
|
Item aboutItems[] = {createStringItem("Midedit - mobile midi editor\nAuthor - Bingo\n", 0),
|
||||||
|
createStringItem("http://bing.at.tut.by\n", 2),
|
||||||
|
createStringItem("Mods - Cryingangel\n", 0),
|
||||||
|
createStringItem("http://midedit.wen.ru", 2),
|
||||||
|
new TextField("Forum seclub.org", "http://seclub.org/forum/index.php?tid=6551", 60, TextField.ANY),
|
||||||
|
createStringItem("Thanks to:", 2),
|
||||||
|
createStringItem("Cyber_PUNK - adapted for Nokia\nmaxtr86 - adapted for Sony Erricson\nHelion810\nDark_Dancer - ideas, beta-testing\nsegOro - graphics", 0),};
|
||||||
|
aboutForm = new Form("About", aboutItems);
|
||||||
|
aboutForm.addCommand(Settings.comCancel);
|
||||||
|
aboutForm.setCommandListener(this);
|
||||||
|
display.setCurrent(aboutForm);
|
||||||
|
break;
|
||||||
|
case OPEN:
|
||||||
|
openFile();
|
||||||
|
break;
|
||||||
|
case SAVE:
|
||||||
|
if (ifFirstReturn == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (compositionForm.isNew()) {
|
||||||
|
saveAsFile();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openSaveString = compositionForm.getCompositionName();
|
||||||
|
try {
|
||||||
|
model.setLocalFile();
|
||||||
|
compositionForm.saveComposition(openSaveString);
|
||||||
|
compositionForm.setTitle(openSaveString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(12), e.getMessage(), null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SAVE_AS:
|
||||||
|
if (ifFirstReturn == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saveAsFile();
|
||||||
|
break;
|
||||||
|
case RMS_FS:
|
||||||
|
MixerModel.isRMSMode = !MixerModel.isRMSMode;
|
||||||
|
//model.setLocalFile(MixerModel.isRMSMode);
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
((Form) iconsMenu).set(6, MixerModel.isRMSMode ? itemsRMS : items[6]);//!!!!!
|
||||||
|
} catch (IllegalStateException illegState) {
|
||||||
|
}
|
||||||
|
} catch (ClassCastException clasCast) {
|
||||||
|
((List) iconsMenu).set(6, Constants.getStringName(MixerModel.isRMSMode ? 9 : 6), iconsImgs[6]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OPTIONS:
|
||||||
|
display.setCurrent(settings.optionsForm);
|
||||||
|
// System.out.println("qwerty");
|
||||||
|
break;
|
||||||
|
case EXIT:
|
||||||
|
MixerMain.curMIDlet.notifyDestroyed();
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
setCurrentlistMenu(null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MixerModel getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
*/
|
||||||
|
public void setCurrentlistMenu(Alert a) {
|
||||||
|
if (a != null) {
|
||||||
|
display.setCurrent(a, iconsMenu);
|
||||||
|
} else {
|
||||||
|
display.setCurrent(iconsMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Displayable getCurrentlistMenu() {
|
||||||
|
return iconsMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void saveAsFile() {
|
||||||
|
model.setLocalFile();
|
||||||
|
final FileChooser chooserForSave = new FileChooser(iconsMenu, "/", true, MixerModel.getLocalFile());
|
||||||
|
chooserForSave.setAbstractListener(new AbstractListener() {
|
||||||
|
|
||||||
|
public void actionPerformed(int itemNum) {
|
||||||
|
if (chooserForSave.getSelectedFolderPath() != null) {
|
||||||
|
openSaveString = compositionForm.getCompositionName();
|
||||||
|
int indBeg = openSaveString.lastIndexOf(Constants.FILE_DELIM);
|
||||||
|
int indEnd = openSaveString.lastIndexOf('.');
|
||||||
|
if (indEnd == -1) {
|
||||||
|
indEnd = openSaveString.length();
|
||||||
|
}
|
||||||
|
openSaveString = openSaveString.substring(indBeg + 1, indEnd);
|
||||||
|
if (openSaveString.length() > 64) {
|
||||||
|
openSaveString = openSaveString.substring(0, 63);
|
||||||
|
}
|
||||||
|
textBoxSave = new TextBox(Constants.getStringName(5) + "...", openSaveString, 64, TextField.ANY);
|
||||||
|
textBoxSave.addCommand(Settings.comSave);
|
||||||
|
textBoxSave.addCommand(Settings.comCancel);
|
||||||
|
|
||||||
|
//System.out.println ("save as success 2\nopenSaveString="+openSaveString);
|
||||||
|
textBoxSave.setCommandListener(new CommandListener() {
|
||||||
|
|
||||||
|
public void commandAction(Command c, Displayable d) {
|
||||||
|
if (c == Settings.comSave) {
|
||||||
|
try {
|
||||||
|
openSaveString = chooserForSave.getSelectedFilePath() + textBoxSave.getString().trim() + ".mid";
|
||||||
|
compositionForm.saveComposition(openSaveString);
|
||||||
|
compositionForm.setTitle(openSaveString);
|
||||||
|
compositionForm.setNew(false);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(12), e.getMessage(), null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCurrentlistMenu(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
display.setCurrent(textBoxSave);
|
||||||
|
} else {
|
||||||
|
setCurrentlistMenu(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void openFile() {
|
||||||
|
model.setLocalFile();
|
||||||
|
if (chooser == null || chooser.getSelectedFilePath() == null) {
|
||||||
|
final FileChooser chooserLocale = new FileChooser(iconsMenu, "/", false, MixerModel.getLocalFile());
|
||||||
|
chooserLocale.setAbstractListener(new AbstractListener() {
|
||||||
|
|
||||||
|
public void actionPerformed(int itemNum) {
|
||||||
|
if (chooserLocale.getSelectedFilePath() != null) {
|
||||||
|
try {
|
||||||
|
if (compositionForm != null) {
|
||||||
|
compositionForm.releaseMem();
|
||||||
|
}
|
||||||
|
compositionForm = null;
|
||||||
|
System.gc();
|
||||||
|
display.setCurrent(iconsMenu);
|
||||||
|
openSaveString = chooserLocale.getSelectedFilePath();
|
||||||
|
compositionForm =
|
||||||
|
new CompositionForm(MixerMain.this,
|
||||||
|
openSaveString);
|
||||||
|
display.setCurrent(compositionForm);
|
||||||
|
new Thread(compositionForm).start();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(13), Constants.getStringName(13) + ":\n" + e.getMessage(), null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
if (compositionForm != null) {
|
||||||
|
compositionForm.releaseMem();
|
||||||
|
}
|
||||||
|
compositionForm = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCurrentlistMenu(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
chooser.update();
|
||||||
|
display.setCurrent(chooser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void comBack() {
|
||||||
|
ifFirstReturn = 1;
|
||||||
|
MixerModel.isRMSMode = false;
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
((Form) iconsMenu).set(6, items[6]);
|
||||||
|
} catch (ClassCastException clasCast) {
|
||||||
|
((List) iconsMenu).set(6, Constants.getStringName(6), iconsImgs[6]);
|
||||||
|
}
|
||||||
|
} catch (IllegalStateException ise) {
|
||||||
|
}
|
||||||
|
setCurrentlistMenu(null);
|
||||||
|
}
|
||||||
|
}
|
242
src/midedit/MixerModel.java
Normal file
242
src/midedit/MixerModel.java
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
//import java.io.IOException;
|
||||||
|
import midedit.media.Composition;
|
||||||
|
import midedit.media.AbstractPlayer;
|
||||||
|
import midedit.media.JSR135Player;
|
||||||
|
import midedit.io.RMSFile;
|
||||||
|
import midedit.io.JSR75File;
|
||||||
|
import midedit.io.AbstractFile;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class MixerModel extends Thread {
|
||||||
|
|
||||||
|
private MidiFile mfile = null;
|
||||||
|
static boolean isRMSMode = false;
|
||||||
|
/**
|
||||||
|
* Îáúåêò äèñïëåÿ
|
||||||
|
*/
|
||||||
|
public final Display display = MixerMain.display;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//public final MixerModel thisModel;
|
||||||
|
private NoteListUtils buffer;
|
||||||
|
static AbstractFile rmsFile = new RMSFile(),
|
||||||
|
//localFile,//=rmsFile,
|
||||||
|
jsr75File;//=rmsFile;// = new JSR75File();
|
||||||
|
AbstractPlayer crossPlayer = null;
|
||||||
|
|
||||||
|
public MixerModel() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
//System.out.println("microedition.io.file.FileConnection.version="+System.getProperty("microedition.io.file.FileConnection.version"));
|
||||||
|
if (System.getProperty("microedition.io.file.FileConnection.version") != null) {
|
||||||
|
jsr75File = new JSR75File();
|
||||||
|
} else {
|
||||||
|
jsr75File = rmsFile;
|
||||||
|
}
|
||||||
|
if (crossPlayer == null) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName("javax.microedition.media.Player");
|
||||||
|
crossPlayer = new JSR135Player();
|
||||||
|
} catch (ClassNotFoundException ex1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert a = new Alert(Constants.getStringName(22), Constants.getStringName(22) + ":\n" + e.getMessage(), null, null);
|
||||||
|
display.setCurrent(a);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mfile = new MidiFile(getLocalFile());
|
||||||
|
buffer = new NoteListUtils();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public NoteListUtils getBuffer() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @param c
|
||||||
|
// * @param count
|
||||||
|
// * @throws Exception
|
||||||
|
// */
|
||||||
|
// public void playMix(Composition c, int count) throws Exception {
|
||||||
|
// playMix(c, 0, 0);
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param count
|
||||||
|
* @param t
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void playMix(Composition c, int t) throws Exception {
|
||||||
|
|
||||||
|
crossPlayer.close();
|
||||||
|
getLocalFile().close(0);
|
||||||
|
setLocalFile();
|
||||||
|
mfile.writeMix(c, t, true);
|
||||||
|
String path = mfile.getURI();
|
||||||
|
crossPlayer.play(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param instrum
|
||||||
|
* @param nn
|
||||||
|
* @param vv
|
||||||
|
*/
|
||||||
|
public void playNote(byte instrum, byte nn) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
crossPlayer.close();
|
||||||
|
|
||||||
|
crossPlayer.playTest(mfile.writeNote(instrum, nn));
|
||||||
|
} catch (Exception e) {
|
||||||
|
CompositionForm.msg("MixerModel: 134: playNote " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playTest(byte instrum) {
|
||||||
|
|
||||||
|
|
||||||
|
crossPlayer.close();
|
||||||
|
mfile.writeTest(instrum);
|
||||||
|
crossPlayer.playTest(mfile.writeTest(instrum));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param count
|
||||||
|
* @param t
|
||||||
|
* @param channel
|
||||||
|
* @param instrument
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void playTrack(Composition c, int t, int channel, int instrument) throws Exception {
|
||||||
|
crossPlayer.close();
|
||||||
|
getLocalFile().close(0);
|
||||||
|
setLocalFile();
|
||||||
|
mfile.writeMixWithName(c, t, true, "out_track.mid", channel, instrument);
|
||||||
|
String path = mfile.getURI();
|
||||||
|
crossPlayer.play(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param count
|
||||||
|
* @param t
|
||||||
|
* @param channel
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void playTrack(Composition c, int t, int channel) throws Exception {
|
||||||
|
playTrack(c, t, channel, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void stopPlay() {
|
||||||
|
crossPlayer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String saveMix(Composition c, String name) throws Exception {
|
||||||
|
return mfile.writeMixWithName(c, 0, false,
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void resetProgress() {
|
||||||
|
mfile.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public Composition openMix(String name) throws Exception {
|
||||||
|
Composition c;
|
||||||
|
if (name != null) {
|
||||||
|
c = mfile.readMix(
|
||||||
|
name);
|
||||||
|
c.setName(name);
|
||||||
|
} else {
|
||||||
|
c = new Composition();
|
||||||
|
c.addTemp(0, 500000);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Composition newMix() {
|
||||||
|
Composition c = new Composition();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Waitable getWaitableFile() {
|
||||||
|
return mfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @param RMSMode
|
||||||
|
// */
|
||||||
|
// public void setLocalFile(boolean RMSMode) {
|
||||||
|
// isRMSMode = RMSMode;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setLocalFile() {
|
||||||
|
mfile.setFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static AbstractFile getLocalFile() {
|
||||||
|
return isRMSMode ? rmsFile : jsr75File;
|
||||||
|
}
|
||||||
|
}
|
29
src/midedit/Note.java
Normal file
29
src/midedit/Note.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class Note {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tt
|
||||||
|
* @param ch
|
||||||
|
* @param nn
|
||||||
|
* @param vv
|
||||||
|
* @param ll
|
||||||
|
*/
|
||||||
|
public byte c, n, v, mark;
|
||||||
|
public int t, len;
|
||||||
|
public Note next = null, prev = null;
|
||||||
|
|
||||||
|
public Note(int tt, byte ch, byte nn, byte vv, int ll) {
|
||||||
|
t = tt;
|
||||||
|
c = ch;
|
||||||
|
n = nn;
|
||||||
|
v = vv;
|
||||||
|
len = ll;
|
||||||
|
mark = NoteListUtils.NOTE_NOT_MARKED;
|
||||||
|
}
|
||||||
|
}
|
304
src/midedit/NoteList.java
Normal file
304
src/midedit/NoteList.java
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class NoteList
|
||||||
|
{
|
||||||
|
private Note note=null,noteBeg=null;
|
||||||
|
private Note noteTmp;
|
||||||
|
private Note noteNew;
|
||||||
|
private int len=0;
|
||||||
|
private int timeLastDelOn = -1;
|
||||||
|
private int timeNoteOff;
|
||||||
|
private int t;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int CHANNEL_LONG_NOTE = -2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public NoteList()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param noteExist
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Note add(Note noteExist)
|
||||||
|
{
|
||||||
|
if(noteExist==null)
|
||||||
|
return null;
|
||||||
|
t = noteExist.t;
|
||||||
|
len++;
|
||||||
|
if(noteBeg == null)
|
||||||
|
noteBeg = note = noteExist;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
noteNew = noteExist;
|
||||||
|
if(note == null)
|
||||||
|
note = noteBeg;
|
||||||
|
if(note.t != t)
|
||||||
|
{ if(t < note.t)
|
||||||
|
{
|
||||||
|
for(noteTmp = note;
|
||||||
|
noteTmp != null && t < noteTmp.t;
|
||||||
|
noteTmp = noteTmp.prev)
|
||||||
|
;
|
||||||
|
if(noteTmp == null)
|
||||||
|
{
|
||||||
|
addInto(null,noteNew,noteBeg);
|
||||||
|
return noteNew;
|
||||||
|
}
|
||||||
|
note = noteTmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ for(noteTmp = note;
|
||||||
|
noteTmp.next != null && (noteTmp.next.t < t ) ;
|
||||||
|
noteTmp = noteTmp.next)
|
||||||
|
;
|
||||||
|
note = noteTmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(noteExist.v!=0)
|
||||||
|
{
|
||||||
|
for( ; note.next != null && t == note.next.t ; note = note.next )
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( ; note.prev != null && t == note.t ; note = note.prev )
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
addInto(note, noteNew, note.next);
|
||||||
|
note = noteNew;
|
||||||
|
}
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
private void addInto(Note n1, Note note, Note n2)
|
||||||
|
{
|
||||||
|
note.next = n2;
|
||||||
|
if(n2 != null)
|
||||||
|
n2.prev = note;
|
||||||
|
note.prev = n1;
|
||||||
|
if(n1 != null)
|
||||||
|
n1.next = note;
|
||||||
|
else
|
||||||
|
noteBeg = note;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @param c
|
||||||
|
* @param n
|
||||||
|
* @param v
|
||||||
|
*/
|
||||||
|
public void delOne(int t, byte c, byte n, byte v)
|
||||||
|
{
|
||||||
|
for(note = searchNoteByTime(t); note != null && note.t <= t; note = note.next)
|
||||||
|
if(t==note.t && c == note.c && n == note.n && (v!=0 ^ note.v==0))
|
||||||
|
{
|
||||||
|
if (note.next != null)
|
||||||
|
note.next.prev = note.prev;
|
||||||
|
if (note.prev != null)
|
||||||
|
note.prev.next = note.next;
|
||||||
|
else
|
||||||
|
noteBeg = note.next;
|
||||||
|
|
||||||
|
note = (note.next != null)? note.next : note.prev;
|
||||||
|
len--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param delNote
|
||||||
|
*/
|
||||||
|
public void delOne(Note delNote)
|
||||||
|
{
|
||||||
|
for(note = getFirst(); note != null && note.t <= t; note = note.next)
|
||||||
|
if(note == delNote)
|
||||||
|
{
|
||||||
|
if (note.next != null)
|
||||||
|
note.next.prev = note.prev;
|
||||||
|
if (note.prev != null)
|
||||||
|
note.prev.next = note.next;
|
||||||
|
else
|
||||||
|
noteBeg = note.next;
|
||||||
|
|
||||||
|
note = (note.next != null)? note.next : note.prev;
|
||||||
|
len--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param undo
|
||||||
|
*/
|
||||||
|
public void delSelected(UndoableAction undo)
|
||||||
|
{
|
||||||
|
for(note = getFirst(); note != null; note = note.next)
|
||||||
|
if(note.mark == NoteListUtils.NOTE_MARKED)
|
||||||
|
{
|
||||||
|
if (note.next != null)
|
||||||
|
note.next.prev = note.prev;
|
||||||
|
if (note.prev != null)
|
||||||
|
note.prev.next = note.next;
|
||||||
|
else
|
||||||
|
noteBeg = note.next;
|
||||||
|
|
||||||
|
if(undo!=null && note.v!=0)
|
||||||
|
{
|
||||||
|
undo.log2DelNoteList(note.t,note.c,note.n,note.v,note.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @param tMax
|
||||||
|
* @param c
|
||||||
|
* @param n
|
||||||
|
* @param v
|
||||||
|
* @param undo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int del(int t,int tMax, byte c, byte n, byte v,UndoableAction undo)
|
||||||
|
{
|
||||||
|
if(t == tMax)
|
||||||
|
tMax++;
|
||||||
|
int tOffMax = tMax;
|
||||||
|
boolean isdel=false;
|
||||||
|
timeNoteOff = -1;
|
||||||
|
|
||||||
|
for(note = searchNoteByTime(t); note != null && note.t <= tMax; note = note.next)
|
||||||
|
if ( (note.c == c || c == (byte)-1) &&
|
||||||
|
(note.t > t || v!=0 && note.t == t) &&
|
||||||
|
(note.t < tMax || v==0 && note.t == tMax) &&
|
||||||
|
(note.n == n || n == (byte)-1) &&
|
||||||
|
( (v != 0 && (note.v != 0 || note.t - note.len >= t)) ||
|
||||||
|
(v == 0 && (note.v == 0 && timeLastDelOn <= note.t-note.len && note.t-note.len < t ))))
|
||||||
|
{
|
||||||
|
if(note.next != null)
|
||||||
|
note.next.prev = note.prev;
|
||||||
|
if(note.prev != null)
|
||||||
|
note.prev.next = note.next;
|
||||||
|
else
|
||||||
|
noteBeg = note.next;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
if( v != 0)
|
||||||
|
{
|
||||||
|
if(tOffMax < note.t+note.len)
|
||||||
|
tOffMax = note.t+note.len;
|
||||||
|
if(undo!=null && note.v!=0)
|
||||||
|
{
|
||||||
|
undo.log2DelNoteList(note.t,note.c,note.n,note.v,note.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(note.v==0)
|
||||||
|
timeNoteOff = note.t;
|
||||||
|
isdel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(v!=0 && tOffMax>tMax)
|
||||||
|
{
|
||||||
|
timeLastDelOn = t;
|
||||||
|
del(tMax, tOffMax, c, n, (byte) 0,null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
timeLastDelOn = -1;
|
||||||
|
if(isdel == false)
|
||||||
|
return -2;
|
||||||
|
return timeNoteOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Note searchBack(byte c, byte n)
|
||||||
|
{
|
||||||
|
if(note == null)
|
||||||
|
return null;
|
||||||
|
for(noteTmp = note;
|
||||||
|
noteTmp != null && (noteTmp.c!=c || noteTmp.n!=n);
|
||||||
|
noteTmp = noteTmp.prev)
|
||||||
|
;
|
||||||
|
|
||||||
|
return noteTmp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Note searchNoteByTime(int t)
|
||||||
|
{
|
||||||
|
if(note == null)
|
||||||
|
{
|
||||||
|
if(noteBeg != null)
|
||||||
|
note = noteBeg;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if(t <= note.t)
|
||||||
|
{
|
||||||
|
for(noteTmp = note;
|
||||||
|
noteTmp.prev != null && t <= noteTmp.t;
|
||||||
|
noteTmp = noteTmp.prev)
|
||||||
|
;
|
||||||
|
if(noteTmp.t<t && noteTmp.next!=null)
|
||||||
|
noteTmp = noteTmp.next;
|
||||||
|
note = noteTmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(noteTmp = note;
|
||||||
|
noteTmp.next != null && noteTmp.t < t ;
|
||||||
|
noteTmp = noteTmp.next)
|
||||||
|
;
|
||||||
|
note = noteTmp;
|
||||||
|
}
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getLen()
|
||||||
|
{ return len;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Note getFirst()
|
||||||
|
{
|
||||||
|
note = noteBeg;
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public Note getNext()
|
||||||
|
// {
|
||||||
|
// if(note != null)
|
||||||
|
// note = note.next;
|
||||||
|
// return note;
|
||||||
|
// }
|
||||||
|
}
|
315
src/midedit/NoteListUtils.java
Normal file
315
src/midedit/NoteListUtils.java
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class NoteListUtils {
|
||||||
|
|
||||||
|
private NoteList bufferList;
|
||||||
|
private byte bufferChannel;
|
||||||
|
private int bufticksPer4;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int OVERWRITE = 0;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int REPLACE = 1;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int INSERT = 2;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte NOTE_MARKED = 1;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte NOTE_NOT_MARKED = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public NoteListUtils() {
|
||||||
|
bufferList = null;
|
||||||
|
bufferChannel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param composition
|
||||||
|
* @param channel
|
||||||
|
* @param timeMarkBeg
|
||||||
|
* @param timeMarkEnd
|
||||||
|
* @param markNotes
|
||||||
|
*/
|
||||||
|
public void copy2Buffer(Composition composition, byte channel,
|
||||||
|
int timeMarkBeg, int timeMarkEnd, boolean markNotes) {
|
||||||
|
bufferList = new NoteList();
|
||||||
|
bufticksPer4 = composition.getTicksPer4();
|
||||||
|
|
||||||
|
|
||||||
|
if (markNotes == false) {
|
||||||
|
copySelected(bufferList, composition.getNoteListByChannel(channel));
|
||||||
|
} else {
|
||||||
|
copy(bufferList, bufticksPer4, channel, 0,
|
||||||
|
composition.getNoteListByChannel(channel), bufticksPer4, channel,
|
||||||
|
timeMarkBeg, timeMarkEnd, null, markNotes);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferChannel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param composition
|
||||||
|
* @param channel
|
||||||
|
* @param timeBeg
|
||||||
|
* @param attr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int paste2Composition(Composition composition, byte channel,
|
||||||
|
int timeBeg, int attr) {
|
||||||
|
int retVal = 0;
|
||||||
|
if (bufferList != null) {
|
||||||
|
NoteList dest = composition.getNoteListByChannel(channel);
|
||||||
|
int newTicksPer4 = composition.getTicksPer4();
|
||||||
|
UndoableAction undo = composition.getUndoableAction();
|
||||||
|
undo.prepare();
|
||||||
|
|
||||||
|
if (attr == INSERT) {
|
||||||
|
undo.addAction(UndoableAction.DELETE_LIST);
|
||||||
|
undo.addAction(UndoableAction.SHIFT_LIST);
|
||||||
|
undo.addAction(UndoableAction.ADD_LIST);
|
||||||
|
int bufLen = bufferList.searchNoteByTime(0x7fffffff).t;
|
||||||
|
shift(dest, timeBeg,
|
||||||
|
(bufLen * newTicksPer4) / bufticksPer4, undo);
|
||||||
|
retVal = bufLen;
|
||||||
|
} else if (attr == REPLACE) {
|
||||||
|
undo.addAction(UndoableAction.DELETE_LIST);
|
||||||
|
undo.addAction(UndoableAction.ADD_LIST);
|
||||||
|
int bufLen = bufferList.searchNoteByTime(0x7fffffff).t;
|
||||||
|
dest.del(timeBeg, timeBeg
|
||||||
|
+ (bufLen * newTicksPer4) / bufticksPer4,
|
||||||
|
channel, (byte) -1, (byte) 127, undo);
|
||||||
|
} else if (attr == OVERWRITE) {
|
||||||
|
undo.addAction(UndoableAction.ADD_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(dest, newTicksPer4, channel, timeBeg,
|
||||||
|
bufferList, bufticksPer4, bufferChannel, 0, 0x7fffffff, undo, false);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* @param src
|
||||||
|
*/
|
||||||
|
private static void copySelected(NoteList dest, NoteList src) {
|
||||||
|
Note note = src.getFirst();
|
||||||
|
int timeShift = -1;
|
||||||
|
for (; note != null; note = note.next) {
|
||||||
|
if (note.mark == NOTE_MARKED) {
|
||||||
|
if (timeShift == -1) {
|
||||||
|
timeShift = note.t;
|
||||||
|
}
|
||||||
|
dest.add(new Note(note.t - timeShift, note.c, note.n, note.v, note.len));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* @param destTicksPer4
|
||||||
|
* @param chDest
|
||||||
|
* @param tDestBeg
|
||||||
|
* @param src
|
||||||
|
* @param srcTicksPer4
|
||||||
|
* @param chSrc
|
||||||
|
* @param tSrcBeg
|
||||||
|
* @param tSrcEnd
|
||||||
|
* @param undo
|
||||||
|
* @param onlyMarkSrc
|
||||||
|
*/
|
||||||
|
private static void copy(NoteList dest, int destTicksPer4, byte chDest, int tDestBeg,
|
||||||
|
NoteList src, int srcTicksPer4, byte chSrc, int tSrcBeg, int tSrcEnd,
|
||||||
|
UndoableAction undo, boolean onlyMarkSrc) {
|
||||||
|
int t, len;
|
||||||
|
byte n;
|
||||||
|
Note srcNote;
|
||||||
|
for (srcNote = src.searchNoteByTime(tSrcBeg);
|
||||||
|
srcNote != null && srcNote.t <= tSrcEnd; srcNote = srcNote.next) {
|
||||||
|
if (srcNote.c == chSrc && (srcNote.v == 0 && srcNote.t - srcNote.len >= tSrcBeg
|
||||||
|
|| srcNote.v != 0 && srcNote.t + srcNote.len <= tSrcEnd)
|
||||||
|
&& (srcNote.v != 0 || onlyMarkSrc)) {
|
||||||
|
if (onlyMarkSrc) {
|
||||||
|
srcNote.mark = NOTE_MARKED;
|
||||||
|
} else {
|
||||||
|
t = tDestBeg
|
||||||
|
+ ((srcNote.t - tSrcBeg) * destTicksPer4) / srcTicksPer4;
|
||||||
|
n = srcNote.n;
|
||||||
|
len = (srcNote.len * destTicksPer4) / srcTicksPer4;
|
||||||
|
dest.add(new Note(t, chDest, n, srcNote.v, len));
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
dest.add(new Note(t + len, chDest, n, (byte) 0, len));
|
||||||
|
}
|
||||||
|
if (undo != null) {
|
||||||
|
undo.log2AddNoteList(t, chDest, n, srcNote.v, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* @param tBeg
|
||||||
|
* @param shiftLen
|
||||||
|
* @param undo
|
||||||
|
*/
|
||||||
|
public static void shift(NoteList list, int tBeg, int shiftLen, UndoableAction undo) {
|
||||||
|
Note note = list.searchNoteByTime(0x7fffffff);
|
||||||
|
for (; note != null && note.t >= tBeg; note = note.prev) {
|
||||||
|
if (note.v == 0 && note.t - note.len < tBeg) {
|
||||||
|
Note noteTmp;
|
||||||
|
for (noteTmp = note.prev;
|
||||||
|
noteTmp != null && (noteTmp.c != note.c || noteTmp.n != note.n);
|
||||||
|
noteTmp = noteTmp.prev)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (noteTmp != null && noteTmp.c == note.c && noteTmp.n == note.n) {
|
||||||
|
if (undo != null) {
|
||||||
|
undo.log2DelNoteList(noteTmp.t, noteTmp.c, noteTmp.n, noteTmp.v, noteTmp.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
noteTmp.len = note.t - noteTmp.t + shiftLen;
|
||||||
|
|
||||||
|
if (noteTmp.t + noteTmp.len < tBeg) {
|
||||||
|
noteTmp.len = tBeg - noteTmp.t;
|
||||||
|
}
|
||||||
|
note.len = noteTmp.len;
|
||||||
|
|
||||||
|
if (undo != null) {
|
||||||
|
undo.log2AddNoteList(noteTmp.t, noteTmp.c, noteTmp.n, noteTmp.v, noteTmp.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
note.t += shiftLen;
|
||||||
|
if (note.t < tBeg) {
|
||||||
|
if (undo != null && note.v != 0) {
|
||||||
|
undo.log2DelNoteList(note.t - shiftLen, note.c, note.n, note.v, note.len);
|
||||||
|
undo.log2AddNoteList(tBeg, note.c, note.n, note.v, note.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
note.t = tBeg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (undo != null) {
|
||||||
|
undo.logShift(tBeg, shiftLen, list.getFirst().c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param composition
|
||||||
|
* @param channel
|
||||||
|
* @param timeBeg
|
||||||
|
* @param timeEnd
|
||||||
|
*/
|
||||||
|
public void delete(Composition composition, byte channel, int timeBeg, int timeEnd) {
|
||||||
|
NoteList list = composition.getNoteListByChannel(channel);
|
||||||
|
UndoableAction undo = composition.getUndoableAction();
|
||||||
|
undo.prepare();
|
||||||
|
undo.addAction(UndoableAction.DELETE_LIST);
|
||||||
|
|
||||||
|
list.del(timeBeg, timeEnd, (byte) -1, (byte) -1, (byte) 127, undo);
|
||||||
|
undo.addAction(UndoableAction.SHIFT_LIST);
|
||||||
|
undo.addAction(UndoableAction.ADD_LIST);
|
||||||
|
shift(list, timeBeg, timeBeg - timeEnd, undo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param composition
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
public static void unMarkNotes(Composition composition, byte channel) {
|
||||||
|
NoteList list = composition.getNoteListByChannel(channel);
|
||||||
|
for (Note note = list.getFirst(); note != null; note = note.next) {
|
||||||
|
note.mark = NOTE_NOT_MARKED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param composition
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
public static void deleteSelected(Composition composition, byte channel) {
|
||||||
|
UndoableAction undo = composition.getUndoableAction();
|
||||||
|
undo.prepare();
|
||||||
|
undo.addAction(UndoableAction.DELETE_LIST);
|
||||||
|
NoteList list = composition.getNoteListByChannel(channel);
|
||||||
|
list.delSelected(undo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param composition
|
||||||
|
* @param channel
|
||||||
|
* @param shiftTime
|
||||||
|
* @param shiftNote
|
||||||
|
* @param shiftVol
|
||||||
|
*/
|
||||||
|
public static void doMove(Composition composition, byte channel, int shiftTime, int shiftNote, int shiftVol) {
|
||||||
|
UndoableAction undo = composition.getUndoableAction();
|
||||||
|
undo.addAction(UndoableAction.ADD_LIST);
|
||||||
|
NoteList dest = composition.getNoteListByChannel(channel);
|
||||||
|
int newTime;
|
||||||
|
byte newVol;
|
||||||
|
int tmp;
|
||||||
|
byte newN;
|
||||||
|
for (Note note = undo.getDeletedList().getFirst();
|
||||||
|
note != null; note = note.next) {
|
||||||
|
if (note.c == channel && note.v != 0) {
|
||||||
|
newTime = note.t + shiftTime;
|
||||||
|
if (newTime < 0) {
|
||||||
|
newTime = 0;
|
||||||
|
}
|
||||||
|
newN = (byte) (note.n + shiftNote);
|
||||||
|
|
||||||
|
tmp = note.v + shiftVol;
|
||||||
|
if (tmp < 1) {
|
||||||
|
tmp = 1;
|
||||||
|
} else if (tmp > 127) {
|
||||||
|
tmp = 127;
|
||||||
|
}
|
||||||
|
newVol = (byte) tmp;
|
||||||
|
|
||||||
|
dest.add(new Note(newTime, channel, newN, newVol, note.len));
|
||||||
|
|
||||||
|
if (note.len > 0) {
|
||||||
|
dest.add(new Note(newTime + note.len, channel, newN, (byte) 0, note.len));
|
||||||
|
}
|
||||||
|
if (undo != null && note.v != 0) {
|
||||||
|
undo.log2AddNoteList(newTime, channel, newN, newVol, note.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
src/midedit/NoteLong.java
Normal file
26
src/midedit/NoteLong.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class NoteLong extends Note
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @param d
|
||||||
|
*/
|
||||||
|
public NoteLong(int t,byte[] d)
|
||||||
|
{
|
||||||
|
super(t,(byte)NoteList.CHANNEL_LONG_NOTE,(byte)0,(byte)0,0);
|
||||||
|
dat = d;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public byte[] dat;
|
||||||
|
}
|
128
src/midedit/NotesCanvas.java
Normal file
128
src/midedit/NotesCanvas.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class NotesCanvas extends MixerCanvas
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ctrl
|
||||||
|
* @param c
|
||||||
|
* @param ch
|
||||||
|
*/
|
||||||
|
public NotesCanvas(MixerMain ctrl, Composition c, int ch)
|
||||||
|
{
|
||||||
|
super(ctrl, c, ch);
|
||||||
|
hMax = 127;
|
||||||
|
hBase = 60;
|
||||||
|
curY = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
*/
|
||||||
|
public void setChannel(int ch)
|
||||||
|
{
|
||||||
|
channel = ch;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getChannel()
|
||||||
|
{
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean doKEY_NUM5()
|
||||||
|
{
|
||||||
|
if(super.doKEY_NUM5() == false)
|
||||||
|
{
|
||||||
|
int dt;
|
||||||
|
dt = super.getCurLen();
|
||||||
|
byte n = (byte)getNoteFromLine(curY);
|
||||||
|
int curT = getCurTime();
|
||||||
|
composition.addNoteOn(curT, (byte) channel, n, super.getCurVol(), dt,true);
|
||||||
|
composition.addNoteOffWithoutSearch(curT + dt, (byte) channel, n, dt);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected String getCurTuneString()
|
||||||
|
{
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
* @param note
|
||||||
|
* @param shiftTime
|
||||||
|
* @param shiftNote
|
||||||
|
*/
|
||||||
|
protected void paintNote(Graphics g, Note note,int shiftTime,int shiftNote)
|
||||||
|
{
|
||||||
|
int x,h;
|
||||||
|
int dx, t=1;
|
||||||
|
x = getXInPixel(note.t +shiftTime);
|
||||||
|
h = getLineFromNote(note.n +shiftNote);
|
||||||
|
dx = (note.len*wOne)/Constants.timeConst;
|
||||||
|
if(dx==0)
|
||||||
|
dx=2;
|
||||||
|
if(x+dx>=0 && x<rollWidth)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(h>=0 && h<nH)
|
||||||
|
{
|
||||||
|
g.fillRect(x + t, h*hOne+1, dx - t, hOne-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
h = (h<0)? -1 : nH;
|
||||||
|
g.fillRect(x+t,h*hOne+1,2,hOne-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected byte getLineFromNote(int n)
|
||||||
|
{
|
||||||
|
return (byte)((Constants.INV_CANVAS_CONST - n) - hBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected int getNoteFromLine(int ch)
|
||||||
|
{
|
||||||
|
return (byte)getCurNote();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
176
src/midedit/PrintSmallFont.java
Normal file
176
src/midedit/PrintSmallFont.java
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class PrintSmallFont
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
* @param num
|
||||||
|
* @param dot
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int print(Graphics g,int num,int dot,int x, int y,int color)
|
||||||
|
{
|
||||||
|
int xLen=0;
|
||||||
|
int nt = Math.abs(num);
|
||||||
|
int dig;
|
||||||
|
int i;
|
||||||
|
Image[] imgs = digImages[color];
|
||||||
|
|
||||||
|
while(dot>0 && nt/denom[dot] >= nMax[dot])
|
||||||
|
{
|
||||||
|
dot--;
|
||||||
|
nt /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dot>0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < dot; ++i, nt /= 10, xLen += digLen)
|
||||||
|
{
|
||||||
|
dig = nt % 10;
|
||||||
|
g.drawImage(imgs[dig], x - xLen, y, Graphics.RIGHT | Graphics.BOTTOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawImage(imgs[10], x - xLen, y, Graphics.RIGHT | Graphics.BOTTOM);
|
||||||
|
xLen += digLen;
|
||||||
|
}
|
||||||
|
do{
|
||||||
|
dig = nt % 10;
|
||||||
|
g.drawImage(imgs[dig], x - xLen, y, Graphics.RIGHT | Graphics.BOTTOM);
|
||||||
|
nt /= 10;
|
||||||
|
xLen += digLen;
|
||||||
|
}while(nt!=0);
|
||||||
|
|
||||||
|
if(num<0)
|
||||||
|
{
|
||||||
|
dig = 11;
|
||||||
|
g.drawImage(imgs[dig], x - xLen, y, Graphics.RIGHT | Graphics.BOTTOM);
|
||||||
|
xLen += digLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xLen;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
* @param n
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param color
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int printNote(Graphics g,int n,int x, int y,int color)
|
||||||
|
{
|
||||||
|
g.drawImage(notesImages[color][n],x,y,Graphics.RIGHT|Graphics.BOTTOM);
|
||||||
|
|
||||||
|
return noteLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int[] nMax = {100000,1000,100,10,1,0};
|
||||||
|
static int[] denom = {1,10,100,1000,10000,100000};
|
||||||
|
|
||||||
|
static Image[][] digImages;
|
||||||
|
static Image[][] notesImages;
|
||||||
|
static private int digLen = 4;
|
||||||
|
static private int noteLen = 11;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public int noteLenY=5;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public final int NUM_CHAR=12;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public final int NUM_COLOR=2;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public final int NUM_NOTES=12;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public final int NUM_NOTES_LINE=6;
|
||||||
|
|
||||||
|
static{
|
||||||
|
try {
|
||||||
|
Image numbers0 = Image.createImage("/img/nums0m.png");
|
||||||
|
Image numbers1 = Image.createImage("/img/nums1m.png");
|
||||||
|
Image notes0 = Image.createImage("/img/notes0.png");
|
||||||
|
Image notes1 = Image.createImage("/img/notes1.png");
|
||||||
|
digImages = new Image[NUM_COLOR][];
|
||||||
|
digImages[0] = new Image[NUM_CHAR];
|
||||||
|
digImages[1] = new Image[NUM_CHAR];
|
||||||
|
|
||||||
|
notesImages = new Image[NUM_COLOR][];
|
||||||
|
notesImages[0] = new Image[NUM_NOTES];
|
||||||
|
notesImages[1] = new Image[NUM_NOTES];
|
||||||
|
|
||||||
|
|
||||||
|
int len = 0;
|
||||||
|
for(int i = 0; i<NUM_CHAR; ++i, len+=digLen)
|
||||||
|
{
|
||||||
|
digImages[0][i] = Image.createImage(4,5);
|
||||||
|
digImages[0][i].getGraphics().
|
||||||
|
drawImage(numbers0,-len,0,Graphics.LEFT|Graphics.TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
for(int i = 0; i<NUM_CHAR; ++i, len+=digLen)
|
||||||
|
{
|
||||||
|
digImages[1][i] = Image.createImage(4,5);
|
||||||
|
digImages[1][i].getGraphics().
|
||||||
|
drawImage(numbers1,-len,0,Graphics.LEFT|Graphics.TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
len=0;
|
||||||
|
int lenY=0;
|
||||||
|
for(int i = 0; i<NUM_NOTES; )
|
||||||
|
{
|
||||||
|
notesImages[0][i] = Image.createImage(noteLen,noteLenY);
|
||||||
|
notesImages[0][i].getGraphics().
|
||||||
|
drawImage(notes0,-len,-lenY,Graphics.LEFT|Graphics.TOP);
|
||||||
|
len+=noteLen;
|
||||||
|
if(++i==NUM_NOTES_LINE)
|
||||||
|
{
|
||||||
|
lenY = noteLenY;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len =0;
|
||||||
|
lenY=0;
|
||||||
|
for(int i = 0; i<NUM_NOTES; )
|
||||||
|
{
|
||||||
|
notesImages[1][i] = Image.createImage(noteLen,noteLenY);
|
||||||
|
notesImages[1][i].getGraphics().
|
||||||
|
drawImage(notes1,-len,-lenY,Graphics.LEFT|Graphics.TOP);
|
||||||
|
len+=noteLen;
|
||||||
|
if(++i==NUM_NOTES_LINE)
|
||||||
|
{
|
||||||
|
lenY = noteLenY;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
src/midedit/Rms.java
Normal file
76
src/midedit/Rms.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import javax.microedition.rms.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Êëàññ ñîõðàíåíèÿ íàñòðîåê
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Rms {
|
||||||
|
|
||||||
|
private static final String rmsName = "MidEdit_2_1";
|
||||||
|
private static RecordStore rmsStore;
|
||||||
|
|
||||||
|
// Ïàðàìåòðû
|
||||||
|
public static boolean firstStart = true; // ïåðâûé ñòàðò
|
||||||
|
public static String languageApp = "en"; // ÿçûê ïðîãðàììû
|
||||||
|
public static String languageInstr = "en"; // ÿçûê èíñòðóìåíòîâ
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ñîõðàíåíèå íàñòðîåê
|
||||||
|
*/
|
||||||
|
public static void saveOptions() {
|
||||||
|
if (rmsStore != null) {
|
||||||
|
byte[] options = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(baos);
|
||||||
|
dos.writeBoolean(firstStart);
|
||||||
|
dos.writeUTF(languageApp);
|
||||||
|
dos.writeUTF(languageInstr);
|
||||||
|
dos.flush();
|
||||||
|
options = baos.toByteArray();
|
||||||
|
dos.close();
|
||||||
|
rmsStore.setRecord(1, options, 0, options.length);
|
||||||
|
} catch (InvalidRecordIDException ridex) {
|
||||||
|
try {
|
||||||
|
rmsStore.addRecord(options, 0, options.length);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rmsStore != null) {
|
||||||
|
try {
|
||||||
|
rmsStore.closeRecordStore();
|
||||||
|
rmsStore = null;
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Âîññòàíîâèòü íàñòðîéêè
|
||||||
|
* Ïóñòûå dis.readBoolean() îñòàâëåíû äëÿ ñîâìåñòèìîñòè ñ ïðîøëûìè âåðñèÿìè
|
||||||
|
*/
|
||||||
|
public static void restoreOptions() {
|
||||||
|
try {
|
||||||
|
rmsStore = RecordStore.openRecordStore(rmsName, true);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
rmsStore = null;
|
||||||
|
}
|
||||||
|
if (rmsStore != null) {
|
||||||
|
try {
|
||||||
|
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(rmsStore.getRecord(1)));
|
||||||
|
firstStart = dis.readBoolean(); // ïåðâûé ðàç çàïóùåí
|
||||||
|
languageApp = dis.readUTF();
|
||||||
|
languageInstr = dis.readUTF();
|
||||||
|
dis.close();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
129
src/midedit/Settings.java
Normal file
129
src/midedit/Settings.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.microedition.rms.*;
|
||||||
|
|
||||||
|
public class Settings implements CommandListener {
|
||||||
|
|
||||||
|
public static byte[] settingsIndex = {5, 6, 0, 0, 0, 0, 0, 0};
|
||||||
|
public static String tempDir = "e:/other/",
|
||||||
|
setName = "MIDSET1";
|
||||||
|
MixerMain mixerCntrl;
|
||||||
|
static LangParser parserLang, parserInstr;
|
||||||
|
//RMSFile rmsFile = new RMSFile();
|
||||||
|
static String[] langList = {"en", "ru"};
|
||||||
|
Image[] langImgs = {createImg("/img/en_GB.png"), createImg("/img/ru_RU.png")},
|
||||||
|
controlImgs = {createImg("/img/keyPad.png"), createImg("/img/iconsMenu.png")};
|
||||||
|
ChoiceGroup langChoice = new ChoiceGroup("Language", 1, langList, langImgs),
|
||||||
|
langInstr = new ChoiceGroup("Instruments Language", 1, langList, langImgs),
|
||||||
|
controlChoice;// = new ChoiceGroup("Controls", 1, controlList, controlImgs);
|
||||||
|
TextField tempDirField;
|
||||||
|
Gauge noteHeightGauge;
|
||||||
|
Gauge noteLengthGauge;
|
||||||
|
Item[] itemList;
|
||||||
|
Form optionsForm;
|
||||||
|
static Command comCancel,
|
||||||
|
comSave;
|
||||||
|
|
||||||
|
Settings(MixerMain mixerControl) {
|
||||||
|
mixerCntrl = mixerControl;
|
||||||
|
readFromRms();
|
||||||
|
//settingsIndex[2]= (byte) (settingsIndex[2]* parserLang.isSupported);
|
||||||
|
parserLang = new LangParser(langList[settingsIndex[2]], "lang", 103);
|
||||||
|
parserInstr = new LangParser(langList[settingsIndex[3]], "instr", 206);
|
||||||
|
String[] controlList = {Constants.getStringName(100), Constants.getStringName(101)};
|
||||||
|
controlChoice = new ChoiceGroup(Constants.getStringName(99), 2, controlList, controlImgs);
|
||||||
|
tempDirField = new TextField("Temp Dir", tempDir, 30, 4);
|
||||||
|
noteHeightGauge = new Gauge("Note Height", true, 10, settingsIndex[0]);
|
||||||
|
noteLengthGauge = new Gauge("Note Length", true, 10, settingsIndex[1]);
|
||||||
|
Item[] itemListLocal = {langChoice, langInstr, controlChoice, noteHeightGauge, noteLengthGauge, tempDirField};
|
||||||
|
optionsForm = new Form("Options", itemListLocal);
|
||||||
|
if (parserLang.isSupported == 0) {
|
||||||
|
optionsForm.append("File " + parserLang.resourceFile + " not found. To localizate programm translate 'en.lang' and 'en.instr' in UTF-8 encoding in the package and rename them into " + parserLang.resourceFile + " and " + parserInstr.resourceFile + "\n Also you\n can put your country's image '" + parserLang.locale + ".png' in the package /img/");
|
||||||
|
}
|
||||||
|
langChoice.setSelectedIndex(settingsIndex[2] * parserLang.isSupported, true);
|
||||||
|
langInstr.setSelectedIndex(settingsIndex[3] * parserInstr.isSupported, true);
|
||||||
|
controlChoice.setSelectedIndex(0, settingsIndex[4] == 1);
|
||||||
|
controlChoice.setSelectedIndex(1, settingsIndex[5] == 1);
|
||||||
|
comCancel = new Command(Constants.getStringName(10), Command.BACK, 10);
|
||||||
|
comSave = new Command(Constants.getStringName(11), Command.CANCEL, 11);
|
||||||
|
optionsForm.addCommand(comCancel);
|
||||||
|
optionsForm.addCommand(comSave);
|
||||||
|
optionsForm.setCommandListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commandAction(Command c, Displayable d) {
|
||||||
|
if (c == comSave) {
|
||||||
|
saveOptions();
|
||||||
|
}
|
||||||
|
mixerCntrl.setCurrentlistMenu(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveOptions() {
|
||||||
|
settingsIndex[0] = (byte) noteHeightGauge.getValue();
|
||||||
|
settingsIndex[1] = (byte) noteLengthGauge.getValue();
|
||||||
|
settingsIndex[2] = (byte) langChoice.getSelectedIndex();
|
||||||
|
settingsIndex[3] = (byte) langInstr.getSelectedIndex();
|
||||||
|
settingsIndex[4] = (byte) (controlChoice.isSelected(0) ? 1 : 0);
|
||||||
|
settingsIndex[5] = (byte) (controlChoice.isSelected(1) ? 1 : 0);
|
||||||
|
//System.out.println ("settingsIndex[4]="+settingsIndex[4]);
|
||||||
|
//System.out.println ("settingsIndex[5]="+settingsIndex[5]);
|
||||||
|
tempDir = tempDirField.getString();
|
||||||
|
byte records[][] = {settingsIndex, tempDir.getBytes()};
|
||||||
|
writeToRms(records);
|
||||||
|
}
|
||||||
|
|
||||||
|
Image createImg(String path) {
|
||||||
|
Image img = null;
|
||||||
|
try {
|
||||||
|
img = Image.createImage(path);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeToRms(byte[][] rec) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
RecordStore.deleteRecordStore(setName);
|
||||||
|
} catch (RecordStoreNotFoundException rse) {
|
||||||
|
}
|
||||||
|
RecordStore recordStore = RecordStore.openRecordStore(setName, true);
|
||||||
|
for (int i = 0; i < rec.length; i++) {
|
||||||
|
recordStore.addRecord(rec[i], 0, rec[i].length);
|
||||||
|
//System.out.println ("Success write "+id);
|
||||||
|
}
|
||||||
|
// System.out.println ("indexes = " + recordStore.getRecord(1));
|
||||||
|
//System.out.println ("temp dir =" + new String(recordStore.getRecord(2)));
|
||||||
|
recordStore.closeRecordStore();
|
||||||
|
} catch (RecordStoreException rse) {
|
||||||
|
//System.out.println ("RecordStoreException in read");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean readFromRms() {
|
||||||
|
try {
|
||||||
|
RecordStore recordStore;// = null;
|
||||||
|
try {
|
||||||
|
recordStore = RecordStore.openRecordStore(setName, false);
|
||||||
|
} catch (NullPointerException nullPointer) {
|
||||||
|
recordStore = null;
|
||||||
|
//System.out.println("NullPointerException in readFrom rms"+nullPointer.getMessage());
|
||||||
|
}
|
||||||
|
if (recordStore == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
settingsIndex = recordStore.getRecord(1);
|
||||||
|
tempDir = new String(recordStore.getRecord(2));
|
||||||
|
recordStore.closeRecordStore();
|
||||||
|
} catch (IllegalArgumentException illegArg) {
|
||||||
|
recordStore.closeRecordStore();
|
||||||
|
}
|
||||||
|
} catch (RecordStoreException rse) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
171
src/midedit/TempoList.java
Normal file
171
src/midedit/TempoList.java
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.microedition.lcdui.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class TempoList extends List implements CommandListener
|
||||||
|
{
|
||||||
|
private Composition composition;
|
||||||
|
private MixerModel model;
|
||||||
|
private Displayable backForm;
|
||||||
|
private Vector tempNotes;
|
||||||
|
static private Command instempo = new Command(Constants.getStringName(67),Command.ITEM, 1);
|
||||||
|
static private Command deltempo = new Command(Constants.getStringName(68),Command.ITEM, 1);
|
||||||
|
private int tick = 0;
|
||||||
|
private int meterNom=4,meterDenom=4;
|
||||||
|
private int editNum = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param m
|
||||||
|
* @param back
|
||||||
|
*/
|
||||||
|
public TempoList(Composition c,MixerModel m,Displayable back)
|
||||||
|
{
|
||||||
|
super(Constants.getStringName(69),IMPLICIT);
|
||||||
|
composition = c;
|
||||||
|
model = m;
|
||||||
|
backForm = back;
|
||||||
|
tempNotes = new Vector();
|
||||||
|
meterNom = composition.getNom();
|
||||||
|
meterDenom = 1<<composition.getDenomE();
|
||||||
|
tick = composition.getTicksPer4() * 4 * meterNom/meterDenom;
|
||||||
|
System.out.println("tick = " + tick);
|
||||||
|
this.addCommand(instempo);
|
||||||
|
this.addCommand(deltempo);
|
||||||
|
this.addCommand(CompositionForm.back);
|
||||||
|
this.setCommandListener(this);
|
||||||
|
int
|
||||||
|
tmp;
|
||||||
|
NoteLong notelong;
|
||||||
|
for(Note note = c.getNoteListByChannel(Composition.DEFAULT_CHANNEL).getFirst(); note != null ; note = note.next)
|
||||||
|
{
|
||||||
|
if(note instanceof NoteLong)
|
||||||
|
{
|
||||||
|
notelong = (NoteLong)note;
|
||||||
|
if(notelong.dat[0] == (byte)0xff && notelong.dat[1] == (byte)0x51)
|
||||||
|
{
|
||||||
|
tmp = 0;
|
||||||
|
for (int i = 3; i <= 5; ++i) {
|
||||||
|
tmp = (tmp << 8) | 0xff & notelong.dat[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
tempNotes.addElement(notelong);
|
||||||
|
this.append(getTempoString(note, tmp), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private String getTempoString(Note note,int tempMsPer4)
|
||||||
|
{
|
||||||
|
int tempBPM;
|
||||||
|
int mod = (composition.getTicksPer4()<<2)>>(composition.getDenomE());
|
||||||
|
tempBPM = Composition.getTempBeatPerMin(tempMsPer4);
|
||||||
|
return ""+note.t/tick+":"+(note.t*meterNom/tick)%meterNom+":"+
|
||||||
|
note.t%mod+" - "+ tempBPM;
|
||||||
|
|
||||||
|
}
|
||||||
|
private void viewInsertForm(int time,int tempo)
|
||||||
|
{
|
||||||
|
Form textBoxTemp = new Form(Constants.getStringName(67));
|
||||||
|
final TextField timeField = new TextField(Constants.getStringName(70), ""+time, 4, TextField.NUMERIC);
|
||||||
|
textBoxTemp.append(timeField);
|
||||||
|
final TextField tempoField = new TextField(Constants.getStringName(69), "" + tempo, 4, TextField.NUMERIC);
|
||||||
|
textBoxTemp.append(tempoField);
|
||||||
|
textBoxTemp.addCommand(CompositionForm.ok);
|
||||||
|
textBoxTemp.addCommand(Settings.comCancel);
|
||||||
|
textBoxTemp.setCommandListener(new CommandListener()
|
||||||
|
{
|
||||||
|
public void commandAction(Command command, Displayable displayable)
|
||||||
|
{
|
||||||
|
if (command == CompositionForm.ok)
|
||||||
|
{
|
||||||
|
if(editNum>=0)
|
||||||
|
delTemp(editNum);
|
||||||
|
editNum = -1;
|
||||||
|
|
||||||
|
int tempMsPer4 = Composition.getMsPer4(Integer.parseInt(tempoField.getString(),
|
||||||
|
10));
|
||||||
|
int time = tick * Integer.parseInt(timeField.getString(), 10);
|
||||||
|
NoteLong noteTemp = composition.addTemp(time, tempMsPer4);
|
||||||
|
Note note;
|
||||||
|
int ind;
|
||||||
|
for (ind = 0; ind < tempNotes.size(); ++ind) {
|
||||||
|
note = (NoteLong) tempNotes.elementAt(ind);
|
||||||
|
if (note.t > time)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tempNotes.insertElementAt(noteTemp, ind);
|
||||||
|
TempoList.this.insert(ind, getTempoString(noteTemp, tempMsPer4), null);
|
||||||
|
|
||||||
|
}
|
||||||
|
model.display.setCurrent(TempoList.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
model.display.setCurrent(textBoxTemp);
|
||||||
|
|
||||||
|
}
|
||||||
|
private void delTemp(int ind)
|
||||||
|
{
|
||||||
|
composition.delTemp( (NoteLong) tempNotes.elementAt(ind));
|
||||||
|
tempNotes.removeElementAt(ind);
|
||||||
|
this.delete(ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @param displayable
|
||||||
|
*/
|
||||||
|
public void commandAction(Command command, Displayable displayable)
|
||||||
|
{
|
||||||
|
if(command == instempo)
|
||||||
|
{
|
||||||
|
editNum = -1;
|
||||||
|
viewInsertForm(0,120);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(command == deltempo)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(tempNotes.size()>1)
|
||||||
|
{
|
||||||
|
delTemp(this.getSelectedIndex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(command == CompositionForm.back)
|
||||||
|
{
|
||||||
|
model.display.setCurrent(backForm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ind = this.getSelectedIndex();
|
||||||
|
|
||||||
|
NoteLong notelong = (NoteLong)tempNotes.elementAt(ind);
|
||||||
|
int tmp = 0;
|
||||||
|
for (int i = 3; i <= 5; ++i) {
|
||||||
|
tmp = (tmp << 8) | 0xff & notelong.dat[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int mod = (composition.getTicksPer4() << 2) >> (composition.getDenomE());
|
||||||
|
int tempBPM =Composition.getTempBeatPerMin(tmp);
|
||||||
|
int time = notelong.t/tick;
|
||||||
|
|
||||||
|
editNum = ind;
|
||||||
|
|
||||||
|
viewInsertForm(time,tempBPM);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
257
src/midedit/UndoableAction.java
Normal file
257
src/midedit/UndoableAction.java
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class UndoableAction
|
||||||
|
{
|
||||||
|
private NoteList dellist = null;
|
||||||
|
private NoteList addlist = null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte DELETE_LIST = 1;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte ADD_LIST = 2;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte SHIFT_LIST = 3;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte ADD_NOTE = 4;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final byte DEL_NOTE = 5;
|
||||||
|
private static final byte NUM_ACT = 3;
|
||||||
|
|
||||||
|
private Note noteAddDel;
|
||||||
|
//private Note note;
|
||||||
|
private int indOrder=0;
|
||||||
|
private int shiftBeg;
|
||||||
|
private int shiftLen;
|
||||||
|
private byte[] order = new byte[NUM_ACT];
|
||||||
|
private Composition composition;
|
||||||
|
private byte channel;
|
||||||
|
private boolean canUndo;
|
||||||
|
private boolean canRedo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
*/
|
||||||
|
public UndoableAction(Composition c)
|
||||||
|
{
|
||||||
|
composition = c;
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
*/
|
||||||
|
public void addAction(byte n)
|
||||||
|
{
|
||||||
|
order[indOrder++] = n;
|
||||||
|
canUndo = true;
|
||||||
|
canRedo = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public NoteList getDeletedList()
|
||||||
|
{
|
||||||
|
return dellist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void clean()
|
||||||
|
{
|
||||||
|
dellist = null;
|
||||||
|
addlist = null;
|
||||||
|
indOrder = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void prepare()
|
||||||
|
{
|
||||||
|
order[0]=0;
|
||||||
|
indOrder = 0;
|
||||||
|
dellist = new NoteList();
|
||||||
|
addlist = new NoteList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param singleNote
|
||||||
|
*/
|
||||||
|
public void logAddNote(Note singleNote)
|
||||||
|
{
|
||||||
|
channel = singleNote.c;
|
||||||
|
clean();
|
||||||
|
addAction(ADD_NOTE);
|
||||||
|
noteAddDel = singleNote;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param singleNote
|
||||||
|
*/
|
||||||
|
public void logDelNote(Note singleNote)
|
||||||
|
{
|
||||||
|
channel = singleNote.c;
|
||||||
|
clean();
|
||||||
|
addAction(DEL_NOTE);
|
||||||
|
noteAddDel = singleNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @param ch
|
||||||
|
* @param n
|
||||||
|
* @param v
|
||||||
|
* @param len
|
||||||
|
*/
|
||||||
|
public void log2AddNoteList(int t, byte ch, byte n, byte v,int len)
|
||||||
|
{
|
||||||
|
addlist.add(new Note(t,ch,n,v,len));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @param ch
|
||||||
|
* @param n
|
||||||
|
* @param v
|
||||||
|
* @param len
|
||||||
|
*/
|
||||||
|
public void log2DelNoteList(int t, byte ch, byte n, byte v,int len)
|
||||||
|
{
|
||||||
|
dellist.add(new Note(t,ch,n,v,len));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param timeBeg
|
||||||
|
* @param len
|
||||||
|
* @param ch
|
||||||
|
*/
|
||||||
|
public void logShift(int timeBeg,int len,byte ch)
|
||||||
|
{
|
||||||
|
channel = ch;
|
||||||
|
shiftBeg = timeBeg;
|
||||||
|
shiftLen = len;
|
||||||
|
}
|
||||||
|
private void doAction()
|
||||||
|
{
|
||||||
|
NoteList list;
|
||||||
|
for(int i=indOrder-1; i>=0; --i)
|
||||||
|
switch(order[i])
|
||||||
|
{
|
||||||
|
case ADD_NOTE:
|
||||||
|
composition.getNoteListByChannel(channel).delOne(noteAddDel.t, noteAddDel.c,
|
||||||
|
noteAddDel.n, noteAddDel.v);
|
||||||
|
if(noteAddDel.len != 0)
|
||||||
|
composition.getNoteListByChannel(channel).delOne(noteAddDel.t+noteAddDel.len,
|
||||||
|
noteAddDel.c,noteAddDel.n,(byte)0);
|
||||||
|
break;
|
||||||
|
case DEL_NOTE:
|
||||||
|
composition.getNoteListByChannel(channel).add(new Note(noteAddDel.t,noteAddDel.c,
|
||||||
|
noteAddDel.n,noteAddDel.v,noteAddDel.len));
|
||||||
|
if(noteAddDel.len != 0)
|
||||||
|
composition.getNoteListByChannel(channel).add(new Note(noteAddDel.t+noteAddDel.len,
|
||||||
|
noteAddDel.c,noteAddDel.n, (byte)0,noteAddDel.len));
|
||||||
|
break;
|
||||||
|
case DELETE_LIST:
|
||||||
|
Note noteLocal = dellist.getFirst();
|
||||||
|
if(noteLocal!=null)
|
||||||
|
channel = noteLocal.c;
|
||||||
|
list = composition.getNoteListByChannel(channel);
|
||||||
|
for(noteLocal = dellist.getFirst(); noteLocal!=null; noteLocal = noteLocal.next)
|
||||||
|
{
|
||||||
|
list.add(new Note(noteLocal.t,noteLocal.c,noteLocal.n,noteLocal.v,noteLocal.len));
|
||||||
|
if(noteLocal.len != 0)
|
||||||
|
list.add(new Note(noteLocal.t+noteLocal.len,noteLocal.c,noteLocal.n,(byte)0,noteLocal.len));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ADD_LIST:
|
||||||
|
noteLocal = addlist.getFirst();
|
||||||
|
if(noteLocal!=null)
|
||||||
|
channel = noteLocal.c;
|
||||||
|
|
||||||
|
list = composition.getNoteListByChannel(channel);
|
||||||
|
for(noteLocal = addlist.getFirst(); noteLocal!=null; noteLocal = noteLocal.next)
|
||||||
|
{
|
||||||
|
list.delOne(noteLocal.t,noteLocal.c,noteLocal.n,noteLocal.v);
|
||||||
|
if(noteLocal.len != 0)
|
||||||
|
list.delOne(noteLocal.t+noteLocal.len,noteLocal.c,noteLocal.n,(byte)0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHIFT_LIST:
|
||||||
|
NoteListUtils.shift(composition.getNoteListByChannel(channel),shiftBeg,-shiftLen,null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reverseActOrder();
|
||||||
|
canUndo = !canUndo;
|
||||||
|
canRedo = !canRedo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reverseActOrder()
|
||||||
|
{
|
||||||
|
byte[] newOrder = new byte[NUM_ACT];
|
||||||
|
NoteList newAddlist=addlist, newDellist=dellist;
|
||||||
|
for(int i=0 ; i<indOrder; ++i)
|
||||||
|
switch(order[indOrder - 1 - i])
|
||||||
|
{
|
||||||
|
case ADD_NOTE:
|
||||||
|
newOrder[i] = DEL_NOTE;
|
||||||
|
break;
|
||||||
|
case DEL_NOTE:
|
||||||
|
newOrder[i] = ADD_NOTE;
|
||||||
|
break;
|
||||||
|
case ADD_LIST:
|
||||||
|
newOrder[i] = DELETE_LIST;
|
||||||
|
newDellist = addlist;
|
||||||
|
break;
|
||||||
|
case DELETE_LIST:
|
||||||
|
newOrder[i] = ADD_LIST;
|
||||||
|
newAddlist = dellist;
|
||||||
|
break;
|
||||||
|
case SHIFT_LIST:
|
||||||
|
newOrder[i] = SHIFT_LIST;
|
||||||
|
shiftLen = -shiftLen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
addlist = newAddlist;
|
||||||
|
dellist = newDellist;
|
||||||
|
order = newOrder;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void undo()
|
||||||
|
{
|
||||||
|
if(canUndo)
|
||||||
|
doAction();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void redo()
|
||||||
|
{
|
||||||
|
if(canRedo)
|
||||||
|
doAction();
|
||||||
|
}
|
||||||
|
}
|
140
src/midedit/VolumeForm.java
Normal file
140
src/midedit/VolumeForm.java
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
import midedit.media.Composition;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class VolumeForm extends Form implements CommandListener {
|
||||||
|
|
||||||
|
private Gauge[] volumeGauges;
|
||||||
|
private ChoiceGroup[] soloChecks;
|
||||||
|
private Vector channels = null;
|
||||||
|
private Composition composition;
|
||||||
|
private Displayable backForm;
|
||||||
|
private MixerModel model;
|
||||||
|
private byte gaugeVolMax = 16;
|
||||||
|
private byte[] dupVols = null;
|
||||||
|
private boolean[] dupSolo = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @param chans
|
||||||
|
* @param m
|
||||||
|
* @param back
|
||||||
|
*/
|
||||||
|
public VolumeForm(Composition c, Vector chans, MixerModel m, Displayable back) {
|
||||||
|
super("Volume");
|
||||||
|
composition = c;
|
||||||
|
channels = chans;
|
||||||
|
model = m;
|
||||||
|
backForm = back;
|
||||||
|
dupVols = composition.getVolumeExpArr();
|
||||||
|
dupSolo = composition.getSoloList();
|
||||||
|
buildContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildContent() {
|
||||||
|
int size = channels.size();
|
||||||
|
soloChecks = new ChoiceGroup[size];
|
||||||
|
volumeGauges = new Gauge[size];
|
||||||
|
String[] muteString = new String[1];
|
||||||
|
muteString[0] = "Solo";
|
||||||
|
String gaugeString = "";
|
||||||
|
boolean[] solo = composition.getSoloList();
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
byte channel = ((Byte) channels.elementAt(i)).byteValue();
|
||||||
|
soloChecks[i] = new ChoiceGroup("Channel #" + channel + ":\n" +
|
||||||
|
Constants.getInstrName(composition.getInstrument(channel) + 1),
|
||||||
|
Choice.MULTIPLE, muteString, null);
|
||||||
|
soloChecks[i].setSelectedIndex(0, solo[channel]);
|
||||||
|
volumeGauges[i] = new Gauge(gaugeString, true, gaugeVolMax, convVolExp2Gauge(dupVols[channel]));
|
||||||
|
this.append(soloChecks[i]);
|
||||||
|
this.append(volumeGauges[i]);
|
||||||
|
this.append(" ");
|
||||||
|
}
|
||||||
|
this.addCommand(CompositionForm.play);
|
||||||
|
this.addCommand(CompositionForm.playOrig);
|
||||||
|
this.addCommand(CompositionForm.ok);
|
||||||
|
this.addCommand(Settings.comCancel);
|
||||||
|
this.setCommandListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @param displayable
|
||||||
|
*/
|
||||||
|
public void commandAction(Command command, Displayable displayable) {
|
||||||
|
if (command == CompositionForm.ok) {
|
||||||
|
setVolumeFromGaugesSolo();
|
||||||
|
MixerMain.display.setCurrent(backForm);
|
||||||
|
} else if (command == Settings.comCancel) {
|
||||||
|
restoreVolumesArr();
|
||||||
|
MixerMain.display.setCurrent(backForm);
|
||||||
|
} else if (command == CompositionForm.play) {
|
||||||
|
setVolumeFromGaugesSolo();
|
||||||
|
try {
|
||||||
|
model.playMix(composition, MixerCanvas.xBase * Constants.timeConst);
|
||||||
|
this.addCommand(CompositionForm.stop);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (command == CompositionForm.playOrig) {
|
||||||
|
restoreVolumesArr();
|
||||||
|
try {
|
||||||
|
model.playMix(composition, MixerCanvas.xBase * Constants.timeConst);
|
||||||
|
this.addCommand(CompositionForm.stop);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
} else if (command == CompositionForm.stop) {
|
||||||
|
model.stopPlay();
|
||||||
|
this.removeCommand(CompositionForm.stop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void setVolumeFromGaugesSolo() {
|
||||||
|
for (int ind = 0; ind < channels.size(); ++ind) {
|
||||||
|
byte channel = ((Byte) channels.elementAt(ind)).byteValue();
|
||||||
|
composition.setVolumeExp(channel,
|
||||||
|
convVolGauge2Exp(volumeGauges[ind].getValue()));
|
||||||
|
composition.setSolo(channel, soloChecks[ind].isSelected(0));
|
||||||
|
}
|
||||||
|
composition.setSoloMode(isSolo());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSolo() {
|
||||||
|
boolean solo = false;
|
||||||
|
for (int ind = 0; ind < channels.size(); ++ind) {
|
||||||
|
if (soloChecks[ind].isSelected(0)) {
|
||||||
|
solo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return solo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreVolumesArr() {
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
composition.setVolumeExp(i, dupVols[i]);
|
||||||
|
composition.setSolo(i, dupSolo[i]);
|
||||||
|
}
|
||||||
|
composition.setSoloMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte convVolGauge2Exp(int val) {
|
||||||
|
return (byte) (val * Composition.channelVolExpMax / gaugeVolMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int convVolExp2Gauge(byte e) {
|
||||||
|
return e * gaugeVolMax / Composition.channelVolExpMax;
|
||||||
|
}
|
||||||
|
}
|
87
src/midedit/WaitForm.java
Normal file
87
src/midedit/WaitForm.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
import javax.microedition.lcdui.Command;
|
||||||
|
import javax.microedition.lcdui.Displayable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class WaitForm extends Form implements Runnable, CommandListener
|
||||||
|
{
|
||||||
|
private Gauge percentBar;
|
||||||
|
private Gauge memoryBar;
|
||||||
|
Runtime r;
|
||||||
|
int total;
|
||||||
|
int curPercent;
|
||||||
|
Waitable activity;
|
||||||
|
Displayable next;
|
||||||
|
MixerModel model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
* @param act
|
||||||
|
* @param n
|
||||||
|
* @param mod
|
||||||
|
*/
|
||||||
|
public WaitForm(String title,Waitable act, Displayable n,MixerModel mod)
|
||||||
|
{
|
||||||
|
super("MidEdit");
|
||||||
|
activity = act;
|
||||||
|
next = n;
|
||||||
|
model = mod;
|
||||||
|
r = Runtime.getRuntime();
|
||||||
|
total = (int)r.totalMemory();
|
||||||
|
percentBar = new Gauge(title,false,100,0);
|
||||||
|
memoryBar = new Gauge("Memory",false,100,(total-(int)r.freeMemory())*100/total);
|
||||||
|
append(percentBar);
|
||||||
|
append(memoryBar);
|
||||||
|
this.addCommand(Settings.comCancel);
|
||||||
|
this.setCommandListener(this);
|
||||||
|
}
|
||||||
|
private void setPercent(int percent)
|
||||||
|
{
|
||||||
|
percentBar.setValue(percent);
|
||||||
|
memoryBar.setValue((total-(int)r.freeMemory())*100/total);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
curPercent = 0;
|
||||||
|
while(curPercent<100)
|
||||||
|
{
|
||||||
|
setPercent(activity.getCurPercent());
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @param displayable
|
||||||
|
*/
|
||||||
|
public void commandAction(Command command, Displayable displayable)
|
||||||
|
{
|
||||||
|
cancel();
|
||||||
|
model.display.setCurrent(next);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void cancel()
|
||||||
|
{
|
||||||
|
activity.cancel();
|
||||||
|
curPercent = 100;
|
||||||
|
}
|
||||||
|
}
|
24
src/midedit/Waitable.java
Normal file
24
src/midedit/Waitable.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package midedit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public interface Waitable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getCurPercent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void cancel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void reset();
|
||||||
|
}
|
142
src/midedit/io/AbstractFile.java
Normal file
142
src/midedit/io/AbstractFile.java
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package midedit.io;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public abstract class AbstractFile {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected String lastPath = "";
|
||||||
|
protected InputStream is = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pathName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract String[] list(String pathName) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public final String getLastListPath() {
|
||||||
|
return lastPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pathName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract boolean isDirectory(String pathName) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @param buf
|
||||||
|
* @param offset
|
||||||
|
* @param numBytes
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int write(int fileDescriptor,
|
||||||
|
byte[] buf,
|
||||||
|
int offset,
|
||||||
|
int numBytes) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @param buf
|
||||||
|
* @param offset
|
||||||
|
* @param numBytes
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int read(int fileDescriptor,
|
||||||
|
byte[] buf,
|
||||||
|
int offset,
|
||||||
|
int numBytes) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int close(int fileDescriptor) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int length(int fileDescriptor) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int exists(String fileName) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @param isSave
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int open(String fileName, boolean isSave) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract InputStream getInputStreambyURL(String url) throws IOException;
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @param fileName
|
||||||
|
// * @return
|
||||||
|
// * @throws IOException
|
||||||
|
// */
|
||||||
|
// protected abstract int checkFileName(String fileName) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract int delete(String fileName) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract String getPrefix();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract String getURL();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract String getAns();
|
||||||
|
}
|
284
src/midedit/io/JSR75File.java
Normal file
284
src/midedit/io/JSR75File.java
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
package midedit.io;
|
||||||
|
|
||||||
|
import midedit.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.microedition.io.*;
|
||||||
|
import javax.microedition.io.file.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class JSR75File extends AbstractFile {
|
||||||
|
|
||||||
|
private FileConnection fc = null;
|
||||||
|
private DataOutputStream dos = null;
|
||||||
|
private boolean isSave = false;
|
||||||
|
private String lastFileURL = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pathName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public String[] list(String pathName) throws IOException {
|
||||||
|
lastPath = pathName;
|
||||||
|
Enumeration e;
|
||||||
|
FileConnection currDir = null;
|
||||||
|
|
||||||
|
|
||||||
|
if (pathName.equals("/")) {
|
||||||
|
e = FileSystemRegistry.listRoots();
|
||||||
|
lastPath = "/";
|
||||||
|
} else {
|
||||||
|
currDir = (FileConnection) Connector.open(getPrefix() + pathName);
|
||||||
|
if (currDir.exists() && currDir.isDirectory()) {
|
||||||
|
e = currDir.list();
|
||||||
|
lastPath = pathName;
|
||||||
|
} else {
|
||||||
|
e = FileSystemRegistry.listRoots();
|
||||||
|
lastPath = "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (e == null) {
|
||||||
|
throw new IOException("e==null");
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector v = new Vector();
|
||||||
|
for (; e.hasMoreElements();) {
|
||||||
|
v.addElement(e.nextElement());
|
||||||
|
}
|
||||||
|
String[] listFile = new String[v.size()];
|
||||||
|
int i;
|
||||||
|
Enumeration enumer;
|
||||||
|
for (i = 0, enumer = v.elements(); i < listFile.length; ++i) {
|
||||||
|
listFile[i] = (String) (enumer.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return listFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pathName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public boolean isDirectory(String pathName) throws IOException {
|
||||||
|
FileConnection currDir = null;
|
||||||
|
|
||||||
|
if (pathName == null) {
|
||||||
|
throw new IOException("step -4: pathName==null");
|
||||||
|
}
|
||||||
|
|
||||||
|
currDir = (FileConnection) Connector.open(getPrefix() + pathName);
|
||||||
|
|
||||||
|
if (currDir == null) {
|
||||||
|
throw new IOException("step -3:" + getPrefix() + pathName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (currDir.exists() && currDir.isDirectory());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @param buf
|
||||||
|
* @param offset
|
||||||
|
* @param numBytes
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int write(int fileDescriptor,
|
||||||
|
byte[] buf,
|
||||||
|
int offset,
|
||||||
|
int numBytes) throws IOException {
|
||||||
|
dos.write(buf, offset, numBytes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @param buf
|
||||||
|
* @param offset
|
||||||
|
* @param numBytes
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int read(int fileDescriptor,
|
||||||
|
byte[] buf,
|
||||||
|
int offset,
|
||||||
|
int numBytes) throws IOException {
|
||||||
|
return is.read(buf, offset, numBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int close(int fileDescriptor) throws IOException {
|
||||||
|
if (is != null) {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
is = null;
|
||||||
|
if (dos != null) {
|
||||||
|
dos.close();
|
||||||
|
}
|
||||||
|
dos = null;
|
||||||
|
if (fc != null) {
|
||||||
|
fc.close();
|
||||||
|
}
|
||||||
|
fc = null;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileDescriptor
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int length(int fileDescriptor) throws IOException {
|
||||||
|
int len = 0;
|
||||||
|
if (fc != null) {
|
||||||
|
len = (int) fc.fileSize();
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int exists(String fileName) throws IOException {
|
||||||
|
FileConnection fcTmp = (FileConnection) Connector.open(getPrefix() + fileName);
|
||||||
|
if (!fcTmp.exists()) {
|
||||||
|
fcTmp.close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fcTmp.close();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @param isSaveMode
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int open(String fileName, boolean isSaveMode) throws IOException {
|
||||||
|
String fullName;
|
||||||
|
if (fileName.charAt(0) != '/') {
|
||||||
|
try {
|
||||||
|
Enumeration e = FileSystemRegistry.listRoots();
|
||||||
|
if (e.hasMoreElements()) {
|
||||||
|
FileConnection fcTmp = (FileConnection) Connector.open(getPrefix() + Settings.tempDir);
|
||||||
|
if (!fcTmp.exists()) {
|
||||||
|
fcTmp.mkdir();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("Can't create tmp directory");
|
||||||
|
}
|
||||||
|
fullName = getPrefix() + "/" + Settings.tempDir + fileName;
|
||||||
|
} else {
|
||||||
|
fullName = getPrefix() + fileName;
|
||||||
|
}
|
||||||
|
lastFileURL = fullName;
|
||||||
|
isSave = isSaveMode;
|
||||||
|
fc = (FileConnection) Connector.open(fullName);
|
||||||
|
|
||||||
|
if (isSaveMode) {
|
||||||
|
if (!fc.exists()) {
|
||||||
|
fc.create();
|
||||||
|
} else {
|
||||||
|
fc.truncate(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!isSave) {
|
||||||
|
is = fc.openInputStream();
|
||||||
|
dos = null;
|
||||||
|
} else {
|
||||||
|
dos = fc.openDataOutputStream();
|
||||||
|
is = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public InputStream getInputStreambyURL(String url) throws IOException {
|
||||||
|
FileConnection fcTmp = (FileConnection) Connector.open(url);
|
||||||
|
|
||||||
|
InputStream input = fcTmp.openInputStream();
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
// public int checkFileName(String fileName) throws IOException
|
||||||
|
// {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public int delete(String fileName) throws IOException {
|
||||||
|
FileConnection fcTmp = (FileConnection) Connector.open(getPrefix() + fileName);
|
||||||
|
fcTmp.delete();
|
||||||
|
fcTmp.close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected String getPrefix() {
|
||||||
|
return "file://";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getURL() {
|
||||||
|
return lastFileURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getAns() {
|
||||||
|
return "save ok";
|
||||||
|
}
|
||||||
|
}
|
203
src/midedit/io/RMSFile.java
Normal file
203
src/midedit/io/RMSFile.java
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
package midedit.io;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import javax.microedition.rms.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Title: </p>
|
||||||
|
* <p>Description: </p>
|
||||||
|
* <p>Copyright: Copyright (c) 2004</p>
|
||||||
|
* <p>Company: </p>
|
||||||
|
* @author not attributable
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class RMSFile extends AbstractFile {
|
||||||
|
|
||||||
|
private RecordStore curRecordStore = null;
|
||||||
|
private int recordID = 0;
|
||||||
|
|
||||||
|
public String[] list(String pathName) throws IOException {
|
||||||
|
String[] fileList = RecordStore.listRecordStores();
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int write(int fileDescriptor,
|
||||||
|
byte[] buf,
|
||||||
|
int offset,
|
||||||
|
int numBytes) throws IOException {
|
||||||
|
if (curRecordStore != null) {
|
||||||
|
try {
|
||||||
|
curRecordStore.addRecord(buf, offset, numBytes);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
throw new IOException(ex.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IOException("not opened");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(int fileDescriptor,
|
||||||
|
byte[] buf,
|
||||||
|
int offset,
|
||||||
|
int numBytes) throws IOException {
|
||||||
|
|
||||||
|
if (curRecordStore != null) {
|
||||||
|
//readBuf
|
||||||
|
is.read(buf, offset, numBytes);
|
||||||
|
//System.arraycopy(readBuf,readBufInd,buf,offset,numBytes);
|
||||||
|
//readBufInd += numBytes;
|
||||||
|
} else {
|
||||||
|
throw new IOException("not opened");
|
||||||
|
}
|
||||||
|
|
||||||
|
return numBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int close(int fileDescriptor) throws IOException {
|
||||||
|
try {
|
||||||
|
if (curRecordStore != null) {
|
||||||
|
curRecordStore.closeRecordStore();
|
||||||
|
curRecordStore = null;
|
||||||
|
//readBuf = null;
|
||||||
|
is = null;
|
||||||
|
//System.out.println ("Local file closed");
|
||||||
|
}
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
throw new IOException(ex.getMessage());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int length(int fileDescriptor) throws IOException {
|
||||||
|
if (curRecordStore != null) {
|
||||||
|
int len = 0;
|
||||||
|
try {
|
||||||
|
len = curRecordStore.getRecordSize(recordID);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
throw new IOException(ex.getMessage());
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int exists(String fileName) throws IOException {
|
||||||
|
String name = getLastName(fileName);
|
||||||
|
RecordStore test = null;
|
||||||
|
try {
|
||||||
|
test = RecordStore.openRecordStore(name, false);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
}
|
||||||
|
if (test != null) {
|
||||||
|
try {
|
||||||
|
test.closeRecordStore();
|
||||||
|
} catch (RecordStoreException ex1) {
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int open(String fileName, boolean isSave) throws IOException {
|
||||||
|
String name = getLastName(fileName);
|
||||||
|
lastPath = name;
|
||||||
|
try {
|
||||||
|
curRecordStore = RecordStore.openRecordStore(name, isSave);
|
||||||
|
if (curRecordStore == null) {
|
||||||
|
throw new IOException("not found in RMS");
|
||||||
|
}
|
||||||
|
if (isSave == false) /// read
|
||||||
|
{
|
||||||
|
RecordEnumeration enumer = curRecordStore.enumerateRecords(null, null, false);
|
||||||
|
if (enumer.hasNextElement()) {
|
||||||
|
recordID = enumer.nextRecordId();
|
||||||
|
|
||||||
|
//recordID = curRecordStore.getNextRecordID();
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(curRecordStore.getRecord(recordID));
|
||||||
|
is = bais;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//curRecordStore.closeRecordStore();
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
//close(0);
|
||||||
|
curRecordStore = null;
|
||||||
|
throw new IOException(ex.toString() + " open");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public int checkFileName(String fileName) throws IOException
|
||||||
|
// {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
public int delete(String fileName) throws IOException {
|
||||||
|
String name = getLastName(fileName);
|
||||||
|
try {
|
||||||
|
RecordStore.deleteRecordStore(name);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*protected String getPrefix()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public String getURL() {
|
||||||
|
return lastPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAns() {
|
||||||
|
return "RMS save ok";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLastName(String fullName) {
|
||||||
|
int ind = fullName.lastIndexOf('/');
|
||||||
|
String name;
|
||||||
|
name = (ind > 0) ? fullName.substring(ind + 1) : fullName;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getInputStreambyURL(String url) throws IOException {
|
||||||
|
String fileName = url;
|
||||||
|
InputStream isLocal = null;
|
||||||
|
////// copy from open();
|
||||||
|
|
||||||
|
String name = getLastName(fileName);
|
||||||
|
lastPath = name;
|
||||||
|
try {
|
||||||
|
boolean isSave = false;
|
||||||
|
curRecordStore = RecordStore.openRecordStore(name, isSave);
|
||||||
|
if (curRecordStore == null) {
|
||||||
|
throw new IOException("not found in RMS");
|
||||||
|
}
|
||||||
|
if (isSave == false) /// read
|
||||||
|
{
|
||||||
|
RecordEnumeration enumer = curRecordStore.enumerateRecords(null, null, false);
|
||||||
|
if (enumer.hasNextElement()) {
|
||||||
|
recordID = enumer.nextRecordId();
|
||||||
|
|
||||||
|
//recordID = curRecordStore.getNextRecordID();
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(curRecordStore.getRecord(recordID));
|
||||||
|
isLocal = bais;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
curRecordStore = null;
|
||||||
|
throw new IOException(ex.toString() + " open");
|
||||||
|
}
|
||||||
|
|
||||||
|
return isLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDirectory(String pathName) throws IOException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getPrefix() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
38
src/midedit/media/AbstractPlayer.java
Normal file
38
src/midedit/media/AbstractPlayer.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package midedit.media;
|
||||||
|
|
||||||
|
import midedit.*;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public abstract class AbstractPlayer {
|
||||||
|
|
||||||
|
private Displayable commandForm;
|
||||||
|
|
||||||
|
public final void setCommandForm(Displayable d) {
|
||||||
|
commandForm = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void play(String path) throws Exception;
|
||||||
|
|
||||||
|
protected abstract void stop() throws Exception;
|
||||||
|
|
||||||
|
public abstract void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param is
|
||||||
|
*/
|
||||||
|
protected void setIsPlaying(boolean is) {
|
||||||
|
CompositionForm.isPlaying = is;
|
||||||
|
if (is) {
|
||||||
|
commandForm.addCommand(CompositionForm.stop);
|
||||||
|
} else {
|
||||||
|
commandForm.removeCommand(CompositionForm.stop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void playTest(byte[] writeTest);
|
||||||
|
}
|
537
src/midedit/media/Composition.java
Normal file
537
src/midedit/media/Composition.java
Normal file
@ -0,0 +1,537 @@
|
|||||||
|
package midedit.media;
|
||||||
|
|
||||||
|
import midedit.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class Composition {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
public NoteList[] tracks;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_CHANNEL = 0;
|
||||||
|
private int timeNoteOff;
|
||||||
|
private int volume;
|
||||||
|
private int ticksPer4;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static int NOTHING = -127;
|
||||||
|
private int[] instruments;
|
||||||
|
private byte[] channelVolExp;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final static byte channelVolExpMax = 64;
|
||||||
|
private boolean[] soloList;
|
||||||
|
private boolean isSoloMode;
|
||||||
|
private int nom = 4;
|
||||||
|
private int denomE = 2;
|
||||||
|
private NoteLong meterNote = null;
|
||||||
|
private UndoableAction undoableAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
private Composition(String s) {
|
||||||
|
setName(s);
|
||||||
|
|
||||||
|
tracks = new NoteList[Constants.NCHANNEL];
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
tracks[i] = new NoteList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
instruments = new int[Constants.NCHANNEL];
|
||||||
|
channelVolExp = new byte[Constants.NCHANNEL];
|
||||||
|
soloList = new boolean[Constants.NCHANNEL];
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
instruments[i] = NOTHING;
|
||||||
|
channelVolExp[i] = (byte) (channelVolExpMax / 2);
|
||||||
|
soloList[i] = false;
|
||||||
|
}
|
||||||
|
instruments[Constants.DRUMS_CHANNEL] = -1;
|
||||||
|
|
||||||
|
isSoloMode = false;
|
||||||
|
volume = 60;
|
||||||
|
setTicksPer4(240);
|
||||||
|
|
||||||
|
undoableAction = new UndoableAction(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public Composition() {
|
||||||
|
this("new");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void deleteNoteList() {
|
||||||
|
tracks = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String[] getInstrumentsStrings() {
|
||||||
|
// String[] allInstrums = Constants.instruments;
|
||||||
|
int size = 0;
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
if (instruments[i] != NOTHING) {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] ss = new String[size];
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
if (instruments[i] != NOTHING) {
|
||||||
|
ss[j++] = Constants.getInstrName(instruments[i] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param iNum
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public byte addInstrument(int iNum) {
|
||||||
|
if (iNum == -1) {
|
||||||
|
if (instruments[Constants.DRUMS_CHANNEL] == NOTHING) {
|
||||||
|
instruments[Constants.DRUMS_CHANNEL] = iNum;
|
||||||
|
return (byte) Constants.DRUMS_CHANNEL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < Constants.NCHANNEL
|
||||||
|
&& instruments[i] != NOTHING || i == Constants.DRUMS_CHANNEL; ++i);
|
||||||
|
if (i < Constants.NCHANNEL) {
|
||||||
|
instruments[i] = iNum;
|
||||||
|
return (byte) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
* @param iNum
|
||||||
|
*/
|
||||||
|
public void setInstrument(int ch, int iNum) {
|
||||||
|
if (ch >= 0) {
|
||||||
|
instruments[ch] = iNum;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int[] getInstruments() {
|
||||||
|
int[] t = new int[instruments.length];
|
||||||
|
for (int i = 0; i < instruments.length; ++i) {
|
||||||
|
t[i] = instruments[i];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getInstrument(int ch) {
|
||||||
|
return instruments[ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public void setVolumeExp(int ch, byte e) {
|
||||||
|
channelVolExp[ch] = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @param ch
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public byte getVolumeExp(int ch) {
|
||||||
|
// return channelVolExp[ch];
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public byte[] getVolumeExpArr() {
|
||||||
|
byte[] t = new byte[channelVolExp.length];
|
||||||
|
for (int i = 0; i < channelVolExp.length; ++i) {
|
||||||
|
t[i] = channelVolExp[i];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean[] getSoloList() {
|
||||||
|
boolean[] dup = new boolean[soloList.length];
|
||||||
|
System.arraycopy(soloList, 0, dup, 0, soloList.length);
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param channel
|
||||||
|
* @param solo
|
||||||
|
*/
|
||||||
|
public void setSolo(int channel, boolean solo) {
|
||||||
|
soloList[channel] = solo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param solo
|
||||||
|
*/
|
||||||
|
public void setSoloMode(boolean solo) {
|
||||||
|
isSoloMode = solo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setSoloMode() {
|
||||||
|
boolean solo = false;
|
||||||
|
for (int ind = 0; ind < instruments.length; ++ind) {
|
||||||
|
if (soloList[ind]) {
|
||||||
|
solo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isSoloMode = solo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isPlayChan(int ch) {
|
||||||
|
return !isSoloMode || soloList[ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public boolean isSoloMode() {
|
||||||
|
// return isSoloMode;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tt
|
||||||
|
* @param ch
|
||||||
|
* @param nn
|
||||||
|
* @param vv
|
||||||
|
* @param ll
|
||||||
|
* @param log
|
||||||
|
*/
|
||||||
|
public void addNoteOn(int tt, byte ch, byte nn, byte vv, int ll, boolean log) {
|
||||||
|
tracks[ch].add(new Note(tt, ch, nn, vv, ll));
|
||||||
|
if (log) {
|
||||||
|
undoableAction.logAddNote(new Note(tt, ch, nn, vv, ll));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tt
|
||||||
|
* @param ch
|
||||||
|
* @param nn
|
||||||
|
*/
|
||||||
|
public void addNoteOff(int tt, byte ch, byte nn) {
|
||||||
|
Note noteTmp = tracks[ch].searchBack(ch, nn);
|
||||||
|
if (noteTmp != null) {
|
||||||
|
noteTmp.len = tt - noteTmp.t;
|
||||||
|
tracks[ch].add(new Note(tt, ch, nn, (byte) 0, noteTmp.len));
|
||||||
|
} else {
|
||||||
|
tracks[ch].add(new Note(tt, ch, nn, (byte) 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tt
|
||||||
|
* @param ch
|
||||||
|
* @param nn
|
||||||
|
* @param backLen
|
||||||
|
*/
|
||||||
|
public void addNoteOffWithoutSearch(int tt, byte ch, byte nn, int backLen) {
|
||||||
|
tracks[ch].add(new Note(tt, ch, nn, (byte) 0, backLen));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tt
|
||||||
|
* @param ch
|
||||||
|
* @param nn
|
||||||
|
* @param vv
|
||||||
|
*/
|
||||||
|
public void delNote(int tt, byte ch, byte nn, byte vv) {
|
||||||
|
timeNoteOff = tracks[ch].del(tt, tt + Constants.timeConst - 1, ch, nn, vv, null);
|
||||||
|
if (timeNoteOff == -2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int len;
|
||||||
|
if (timeNoteOff == -1) {
|
||||||
|
len = 0;
|
||||||
|
} else {
|
||||||
|
len = timeNoteOff - tt;
|
||||||
|
}
|
||||||
|
undoableAction.logDelNote(new Note(tt, ch, nn, vv, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tBeg
|
||||||
|
* @param tEnd
|
||||||
|
* @param ch
|
||||||
|
* @param nn
|
||||||
|
* @param vv
|
||||||
|
*/
|
||||||
|
public void delNotes(int tBeg, int tEnd, byte ch, byte nn, byte vv) {
|
||||||
|
if (ch == -1) {
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
tracks[i].del(tBeg, tEnd, ch, nn, vv, null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tracks[ch].del(tBeg, tEnd, ch, nn, vv, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* @param ch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Note getFirstNote(int t, int ch) {
|
||||||
|
return tracks[ch].searchNoteByTime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* @param newTemp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public NoteLong addTemp(int time, int newTemp) {
|
||||||
|
byte[] dat = new byte[]{(byte) 0xff, (byte) 0x51, 0x03, 3, 4, 5};
|
||||||
|
int tmp = newTemp;
|
||||||
|
for (int i = 5; i >= 3; --i) {
|
||||||
|
dat[i] = (byte) (tmp & 0xff);
|
||||||
|
tmp >>= 8;
|
||||||
|
}
|
||||||
|
NoteLong noteTemp = new NoteLong(time, dat);
|
||||||
|
tracks[DEFAULT_CHANNEL].add(noteTemp);
|
||||||
|
return noteTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param delTemp
|
||||||
|
*/
|
||||||
|
public void delTemp(Note delTemp) {
|
||||||
|
tracks[DEFAULT_CHANNEL].delOne(delTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param tempBPM
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getMsPer4(int tempBPM) {
|
||||||
|
return 500000 * 120 / tempBPM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param msPer4
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getTempBeatPerMin(int msPer4) {
|
||||||
|
return 120 * 500000 / msPer4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
public void setTicksPer4(int t) {
|
||||||
|
ticksPer4 = t;
|
||||||
|
Constants.setTimeConst(getTime2CanvasConst());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public short getTicksPer4() {
|
||||||
|
return (short) ticksPer4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getTime2CanvasConst() {
|
||||||
|
return ticksPer4 / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param v
|
||||||
|
*/
|
||||||
|
public void setVolume(int v) {
|
||||||
|
volume = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getVolume() {
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public NoteList getNoteListByChannel(int ch) {
|
||||||
|
return tracks[ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public void setName(String s) {
|
||||||
|
name = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param percent
|
||||||
|
* @param ch
|
||||||
|
*/
|
||||||
|
public void setCurW(int percent, byte ch) {
|
||||||
|
int timeNew;
|
||||||
|
if (percent == 0) {
|
||||||
|
timeNew = 0;
|
||||||
|
} else {
|
||||||
|
timeNew = this.getFirstNote(this.getLastTime() * percent / 100, ch).t;
|
||||||
|
MixerCanvas.curX = 0;
|
||||||
|
}
|
||||||
|
MixerCanvas.xBase = (short) (timeNew / Constants.timeConst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getCurWInPercent() {
|
||||||
|
int timeMax = this.getLastTime();
|
||||||
|
return (MixerCanvas.xBase * Constants.timeConst * 100) / (timeMax > 0 ? timeMax : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getLastTime() {
|
||||||
|
int tCur, tMax = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Constants.NCHANNEL; ++i) {
|
||||||
|
Note noteTimeMax = this.getFirstNote(0x7fffffff, i);
|
||||||
|
if (noteTimeMax != null) {
|
||||||
|
tCur = noteTimeMax.t + noteTimeMax.len;
|
||||||
|
if (tCur > tMax) {
|
||||||
|
tMax = tCur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public UndoableAction getUndoableAction() {
|
||||||
|
return undoableAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getNom() {
|
||||||
|
return nom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getDenomE() {
|
||||||
|
return denomE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nomNew
|
||||||
|
* @param deNomNew
|
||||||
|
*/
|
||||||
|
public void setMeter(int nomNew, int deNomNew) {
|
||||||
|
nom = nomNew;
|
||||||
|
denomE = deNomNew;
|
||||||
|
|
||||||
|
if (meterNote == null) {
|
||||||
|
byte[] dat = new byte[]{(byte) 0xff, (byte) 0x58, 0x04, 0x04, 0x02, 0x18, 0x08};
|
||||||
|
dat[3] = (byte) nomNew;
|
||||||
|
dat[4] = (byte) deNomNew;
|
||||||
|
NoteLong newMeter = new NoteLong(0, dat);
|
||||||
|
tracks[DEFAULT_CHANNEL].add(newMeter);
|
||||||
|
meterNote = newMeter;
|
||||||
|
} else {
|
||||||
|
meterNote.dat[3] = (byte) nomNew;
|
||||||
|
meterNote.dat[4] = (byte) deNomNew;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
src/midedit/media/JSR135Player.java
Normal file
66
src/midedit/media/JSR135Player.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package midedit.media;
|
||||||
|
|
||||||
|
import midedit.*;
|
||||||
|
import javax.microedition.media.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author user
|
||||||
|
*/
|
||||||
|
public class JSR135Player extends AbstractPlayer implements PlayerListener {
|
||||||
|
|
||||||
|
private Player player;
|
||||||
|
|
||||||
|
public void playerUpdate(Player player, java.lang.String event, java.lang.Object eventData) {
|
||||||
|
if (event.equals(STARTED)) {
|
||||||
|
setIsPlaying(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.equals(STOPPED) || event.equals(CLOSED) || event.equals(END_OF_MEDIA)) {
|
||||||
|
setIsPlaying(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play(String path) throws Exception {
|
||||||
|
if (player != null) {
|
||||||
|
player.close();
|
||||||
|
}
|
||||||
|
InputStream is = MixerModel.getLocalFile().getInputStreambyURL(path);
|
||||||
|
player = Manager.createPlayer(is, "audio/midi");
|
||||||
|
player.addPlayerListener(this);
|
||||||
|
player.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stop() throws Exception {
|
||||||
|
if (player != null) {
|
||||||
|
player.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
if (player != null) {
|
||||||
|
player.close();
|
||||||
|
}
|
||||||
|
player = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playTest(byte[] writeTest) {
|
||||||
|
ByteArrayInputStream is = new ByteArrayInputStream(writeTest);
|
||||||
|
if (player != null) {
|
||||||
|
player.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
player = Manager.createPlayer(is, "audio/midi");
|
||||||
|
player.addPlayerListener(this);
|
||||||
|
player.start();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
} catch (MediaException ex) {
|
||||||
|
//ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/text.txt
Normal file
11
src/text.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
MIDedit 2.1 / 3.0
|
||||||
|
|
||||||
|
По просьбе одного человека, на основе исходников MidEdit 2.0.5 (http://sunet.dl.sourceforge.net/project/midedit/MideditProject.tgz) начал делать модификацию.
|
||||||
|
Изменения:
|
||||||
|
- Сохранение в .mid, а не в .MID
|
||||||
|
- Исправления в локализации. Добавлен украинский язык.
|
||||||
|
|
||||||
|
|
||||||
|
******
|
||||||
|
При первом запуске - настройки
|
||||||
|
player.realize
|
Loading…
Reference in New Issue
Block a user