This commit is contained in:
Victor 2018-11-14 19:45:18 +02:00
commit ed54cd866e
33 changed files with 7963 additions and 0 deletions

31
src/Main.java Normal file
View 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();
}
}

View File

@ -0,0 +1,14 @@
package midedit;
/**
*
* @author user
*/
public interface AbstractListener {
/**
*
* @param itemNum
*/
public void actionPerformed(int itemNum);
}

View 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);
}
}

View 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
View 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());
}
}

View 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);
}
}

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

404
src/midedit/MixerMain.java Normal file
View 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
View 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
View 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
View 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;
// }
}

View 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
View 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;
}

View 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();
}
}

View 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
View 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
View 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
View 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);
}
}
}

View 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
View 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
View 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
View File

@ -0,0 +1,24 @@
package midedit;
/**
*
* @author user
*/
public interface Waitable {
/**
*
* @return
*/
public int getCurPercent();
/**
*
*/
public void cancel();
/**
*
*/
public void reset();
}

View 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();
}

View 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
View 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 "";
}
}

View 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);
}

View 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;
}
}
}

View 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
View 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