Java midi program selection strange behaviour - java

I've tried to find any information regarding this but I haven't been able to find anything that helps.
I'm trying to make a program that generates a midi-file consisting of two instruments playing at once using different instruments(programs) on them. I have been using a sample program:
http://www.cs.cornell.edu/courses/cs211/2008sp/examples/MidiSynth.java.txt
as a template but when I try and create the midi events artificially(as opposed to generating them on the fly with the synth in the sample program), the resulting midi-file doesn't seem to care that I have switched programs, using the last changed-to program for every note in the file, consisting of two midi-tracks, even though I have saved program-change data to both tracks. I have pasted the code for my program beneith:
import java.io.File;
import java.io.IOException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Soundbank;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Instrument;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.sound.midi.InvalidMidiDataException;
public class MidiTest2
{
/* This velocity is used for all notes.
*/
private static final int VELOCITY = 64;
final int PROGRAM = 192;
final int NOTEON = 144;
final int NOTEOFF = 128;
long startTime;
Sequence sequence;
Synthesizer synthesizer;
Sequencer sequencer;
Instrument instruments[];
ChannelData channels[];
ChannelData cc;
//int instrumentCounter = 0;
Track track;
MidiTest2(){
try{
if(synthesizer == null){
if((synthesizer = MidiSystem.getSynthesizer()) == null){
System.out.println("getSynthesizer() failed");
return;
}
}
synthesizer.open();
sequencer = MidiSystem.getSequencer();
sequence = new Sequence(Sequence.PPQ, 10);
}catch(Exception e){
e.printStackTrace();
return;
}
Soundbank sb = synthesizer.getDefaultSoundbank();
if(sb != null){
instruments = synthesizer.getDefaultSoundbank().getInstruments();
synthesizer.loadInstrument(instruments[0]);
}
MidiChannel midiChannels[] = synthesizer.getChannels();
channels = new ChannelData[midiChannels.length];
for(int i = 0; i < channels.length;++i){
channels[i] = new ChannelData(midiChannels[i], i);
}
cc = channels[0];
}
public void createShortEvent(int type, int num){
ShortMessage message = new ShortMessage();
try{
long millis = System.currentTimeMillis() - startTime;
long tick = millis * sequence.getResolution() / 500;
message.setMessage(type+cc.num, num, cc.velocity);
System.out.println("Type: " + message.getCommand() + ", Data1: " + message.getData1() + ", Data2: " + message.getData2() + ", Tick: " + tick);
MidiEvent event = new MidiEvent(message, tick);
track.add(event);
}catch (Exception e){
e.printStackTrace();
}
}
public void createShortEvent(int type, int num, int eventTime){
ShortMessage message = new ShortMessage();
try{
//long millis = System.currentTimeMillis() - startTime;
long tick = eventTime * sequence.getResolution();
message.setMessage(type+cc.num, num, cc.velocity);
System.out.println("Type: " + message.getCommand() + ", Data1: " + message.getData1() + ", Data2: " + message.getData2() + ", Tick: " + tick);
MidiEvent event = new MidiEvent(message, tick);
track.add(event);
}catch (Exception e){
e.printStackTrace();
}
}
public void saveMidiFile(){
try {
int[] fileTypes = MidiSystem.getMidiFileTypes(sequence);
if (fileTypes.length == 0) {
System.out.println("Can't save sequence");
} else {
if (MidiSystem.write(sequence, fileTypes[0], new File("testmidi.mid")) == -1) {
throw new IOException("Problems writing to file");
}
}
} catch (SecurityException ex) {
} catch (Exception ex) {
ex.printStackTrace();
}
}
void run(){
//System.out.println("sequence: " + sequence.getTracks().length);
createNewTrack(0);
createShortEvent(NOTEON, 60, 2);
createShortEvent(NOTEOFF, 60, 3);
createShortEvent(NOTEON, 61, 3);
createShortEvent(NOTEOFF, 61, 4);
createShortEvent(NOTEON, 62, 4);
createShortEvent(NOTEOFF, 62, 5);
createShortEvent(NOTEON, 63, 5);
createShortEvent(NOTEOFF, 63, 6);
createNewTrack(5);
createShortEvent(NOTEON, 50, 1);
createShortEvent(NOTEOFF, 50, 5);
playMidiFile();
saveMidiFile();
}
void printTrack(int num){
Track tempTrack = sequence.getTracks()[num];
System.out.println(tempTrack.get(0).getTick());
}
void playMidiFile(){
try{
sequencer.open();
sequencer.setSequence(sequence);
}catch (Exception e){
e.printStackTrace();
}
sequencer.start();
}
void createNewTrack(int program){
track = sequence.createTrack();
programChange(program);
}
void programChange(int program){
cc.channel.programChange(program);
System.out.println("program: " + program);
startTime = System.currentTimeMillis();
createShortEvent(PROGRAM, program);
}
public static void main(String[] args)
{
MidiTest2 mt = new MidiTest2();
mt.run();
}
}
The ChannelData-class(that doesn't do anything but I thought I'd post it for completeness sake):
public class ChannelData {
MidiChannel channel;
boolean solo, mono, mute, sustain;
int velocity, pressure, bend, reverb;
int row, col, num;
public ChannelData(MidiChannel channel, int num) {
this.channel = channel;
this.num = num;
velocity = pressure = bend = reverb = 64;
}
public void setComponentStates() {
}
}
In the program I try to create 5 notes with the acoustic piano-sound and one note with an electric piano sound. However all notes are played back with the electric piano sound even though I create a new track before I switch instrument.
I have been trying to figure this out now for 5 hours or something and I'm all out of ideas.

Tracks can help your own program with organizing events, but they do not affect the synthesizer in any way.
To be able have different settings, you must use different channels.

Related

Display joystick input in java

How can I make java display joystick input whenever I press a button?
I'm using lwjgl. I tried using this loop I found online but is there any alternatives without using this?
I want it to be like a keyListener that whenever I press a button in the joystick It would display something.
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import org.lwjgl.glfw.GLFW;
public class Input {
public static void main(String[] args) {
// to initialize. Most GLFW functions will not work without this.
if (!GLFW.glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
GLFW.glfwPollEvents();
int qanbainput;
for (qanbainput = 0; qanbainput <= GLFW.GLFW_JOYSTICK_LAST; qanbainput++) {
if (!GLFW.glfwJoystickPresent(qanbainput)) continue;
System.out.println("JoyStick(" + qanbainput + ")Name:" +
GLFW.glfwGetJoystickName(qanbainput) + " " +
GLFW.glfwGetGamepadName(qanbainput));
break;
}
if (qanbainput > GLFW.GLFW_JOYSTICK_LAST) return;
for (int i = 0; i < 1000; i++) {
int count1 = 0;
FloatBuffer floatBuffer = GLFW.glfwGetJoystickAxes(qanbainput);
System.out.print("Axes:");
while (floatBuffer.hasRemaining()) {
float axes = floatBuffer.get();
System.out.print(count1 + "," + axes + " ");
count1++;
}
int count2 = 0;
System.out.print("Button:");
ByteBuffer byteBuffer = GLFW.glfwGetJoystickButtons(qanbainput);
while (byteBuffer.hasRemaining()) {
byte button = byteBuffer.get();
System.out.print(count2 + "," + button + " ");
count2++;
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

Every time a new swing windows opens in code that is executed in a for loop

Every time a new swing windows opens in code that is executed in a for loop.
I have some code that is runned in a for loop.
The for loop gives every time a new value to my multidimensional array.
But, every time my for loop creates open's a new windows but does not close the old window.
How can I solve this issues? I want to close the old windows and refresh my window with the new actual values or that only one Windows is opened and that the new values of the for loop refreshes the values inside the table based on the multidimensional array names data.
Because now more than 200 (every second a new windows is opened) windows are opened and after 1 minute I don’t see new values appearing on my window and the computer freezes.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.Timer;
public class UAppWin {
private static final int Status_COL = 1;
String[][] data = new String[3][3];
int dptr;
String[] cols = { "Feature", "Status", "Value" };
public UAppWin(String label, int nphases) {
System.out.println("UApp \"" + label + "\" (" + nphases + " phases)");
}
void newCycle(int phasenr) {
System.out.println("UApp =============================");
dptr = 0;
}
void addEntry(int index, double tim, String label, int status, double dval) {
System.out.println("Uapp [" + index + "] " + label + "(" + status + ") " + dval);
data[dptr][0] = label;
data[dptr][1] = "" + status;
data[dptr][2] = "" + dval;
dptr++;
}
void addMessage(String msg) {
System.out.println("Uapp alert: " + msg);
// rode balk met bericht
}
void deleteMessage() {
}
void endCycle() {
System.out.println("UApp =============================");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null, new JScrollPane(getNewRenderedTable(getTable())));
}
});
}
private JTable getTable() {
DefaultTableModel model = new DefaultTableModel(data, cols);
return new JTable(model) {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(300, 150);
}
};
}
private static JTable getNewRenderedTable(final JTable table) {
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int col) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
String Status = (String) table.getModel().getValueAt(row, Status_COL);
if ("0".equals(Status)) {
setBackground(Color.GREEN);
setForeground(Color.BLACK);
} else if ("2".equals(Status)) {
setBackground(Color.RED);
setForeground(Color.BLACK);
} else {
setBackground(Color.YELLOW);
setForeground(Color.BLACK);
}
return this;
}
});
return table;
}
}
The second part of the code edited:
public class HmOpIntf {
static final String DFLT_IP_ADDR = "127.0.0.1";
static final int DFLT_IP_PORT = 9502;
static final int DFLT_MB_UNIT = 1;
static final int DFLT_POLL_TM = 2;
public static ModbusClient connectPLC(String ipAddr, int port, int unitNr)
{
ModbusClient mc = null;
System.out.println("Connecting to " + ipAddr + " port " + port + " unit " + unitNr);
try {
mc = new ModbusClient(ipAddr, port);
mc.Connect();
mc.setUnitIdentifier((byte)unitNr);
mc.WriteSingleCoil(0, true);
} catch (Exception e) {
System.err.println("*** connectPLC: exception caught");
return null;
}
System.out.println("Connected!");
return mc;
}
public static void disconnectPLC(ModbusClient mc)
{
mc = null;
}
public static String MyConvertRegistersToString(int[] regs, int startIx, int len) {
char[] ca = new char[len];
for (int i = 0; i < len; i++) {
ca[i] = (char) regs[startIx + i];
}
return new String(ca);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ModbusClient mc = null;
String ipAddr = DFLT_IP_ADDR;
int ipPort = DFLT_IP_PORT;
int mbUnit = DFLT_MB_UNIT;
int pollTime = DFLT_POLL_TM;
int tlBase = 2000; /* Offset in PLC's holding registry */
int tlBlocksz = 84;
String[] tlLabel = {"T4 mould", "T injection valve"}; /* Default */
int trafLightNum = tlLabel.length;
String[] colors = { "green", "yellow", "red" };
int status;
// Notifications.infoBox("Hello world!", "Welcome message");
if (args != null && args.length > 0) {
if (args.length < 4) {
System.err.println("*** Error (" + args.length +"): arguments are: ip-addr port unit polltime label-1 ...");
System.exit(1);
}
ipAddr = args[0];
ipPort = Integer.parseInt(args[1]);
mbUnit = Integer.parseInt(args[2]);
pollTime = Integer.parseInt(args[3]);
}
if (args.length > 4) {
trafLightNum = args.length - 4;
tlLabel = new String[trafLightNum];
for (int i = 0; i < trafLightNum; i++) {
tlLabel[i] = args[i + 4];
}
}
// Scope sc = new Scope();
// sc.runScope();
if ((mc = connectPLC(ipAddr, ipPort, mbUnit)) == null) {
System.out.println("*** Failed to connect to PLC");
System.exit(1);
}
TrafficLight tlLast = null;
int[] values = new int[tlBlocksz];
TrafficLight[] tl = new TrafficLight[trafLightNum];
Scope[] sc = new Scope[trafLightNum];
Notifications nots = new Notifications(trafLightNum);
int locX, locY;
for (int i = 0; i < tl.length; i++) {
tl[i] = new TrafficLight();
tl[i].setLbl(tlLabel[i]);
tl[i].setVisible(true);
if (tlLast != null) {
locX = tlLast.getLocation().x;
locY = tlLast.getLocation().y + tlLast.getHeight();
} else {
locX = tl[i].getLocation().x;
locY = tl[i].getLocation().y;
}
tl[i].setLocation(locX, locY);
sc[i] = new Scope(tlLabel[i], locX + tl[i].getWidth(), locY, 320, 290 /* tl[i].getHeight()-80 */ );
sc[i].setGrid(10, 5);
tlLast = tl[i];
}
UAppWin uw = new UAppWin("RTM Facility", 5);
int phase = 1;
// tl2.setVisible(true); tl2.setLocation(tl.getWidth(), 0);
try {
double t = 0.0;
int[] dreg = new int[2];
for (;;) {
uw.newCycle(phase);
for (int i = 0; i < tl.length; i++) {
values = mc.ReadHoldingRegisters(tlBase + i * tlBlocksz, values.length);
status = values[0];
if (status >= 0 && status < colors.length) {
// System.out.println(i + ": " + colors[status]);
if (status == 0) tl[i].greenOn();
else if (status == 1) tl[i].yellowOn();
else tl[i].redOn();
}
else
System.out.println("Status value " + i + " out of range: " + status);
dreg[0] = values[1]; dreg[1] = values[2];
double dval = (double) ModbusClient.ConvertRegistersToFloat(dreg);
sc[i].addValue(t, dval);
sc[i].drawSignal();
// w.addEntry(int i, float t, String label, int status (o = groen, 1 = yellow, 2 = red), float dval);
uw.addEntry(i, t, tlLabel[i], status, dval);
int msglen = values[3];
if (msglen > 0) {
String msg = MyConvertRegistersToString(values, 4, msglen);
System.out.println("DEBUG: received message for " + tlLabel[i] + ": " + msg);
nots.notify(i, msg);
uw.addMessage(msg);
}
else {
nots.notify(i, null);
uw.deleteMessage();
}
// System.out.println("Received for set " + i + ": status=" + status + " dval=" + dval + " msglen=" + msglen);
}
uw.endCycle();
t += 1.0;
Thread.sleep(pollTime * 500);
}
} catch (Exception e) {
System.out.println("*** Failed to communicate with PLC - exit");
System.exit(1);
}
try {
mc.Disconnect();
} catch (IOException e) {
System.out.println("*** Failed to disconnect from PLC");
}
}
}
The UappWin seems to be tied to a window. So when you create it, also create a JFrame. Then nothing else would need to change except the run method and declaring the JFrame.
public class UAppWin {
private JFrame frame;
public UAppWin(String label, int nphases) {
//System.out.println("UApp \"" + label + "\" (" + nphases + " phases)");
JLabel label = new JLabel("UApp \"" + label + "\" (" + nphases + " phases)");
frame = new JFrame("title");
frame.add(label);
frame.setVisible(true);
}
Then when you create the window.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//JOptionPane.showMessageDialog(null, new JScrollPane(getNewRenderedTable(getTable())));
frame.setContentPane( new JScrollPane( getNewRenderedTable( getTable() ) );
frame.setVisible(true);
}
});

Java MIDI Sequencer is not playing at a regular pace

Here I have a simple piece of code that plays 10 notes at a constant interval with a custom Soundbank, but the result is not playing at a regular pace, or something is introducing a significant delay. Am I doing something wrong ? Is there a "warm-up" time ?
I'm on Ubuntu with OpenJDK 8.
Thanks :).
import java.io.File;
import java.io.IOException;
import javax.sound.midi.*;
public class MidiTest
{
static public void main(String[] args) throws MidiUnavailableException, InvalidMidiDataException, IOException
{
Sequence sequence = new Sequence(Sequence.PPQ, 1000);
Track track = sequence.createTrack();
for (int i = 0; i < 10; i++)
{
ShortMessage noteOn = new ShortMessage(ShortMessage.NOTE_ON , 0, 50, 100);
ShortMessage noteOff = new ShortMessage(ShortMessage.NOTE_OFF, 0, 50, 100);
int noteOnTime = 1000 * i;
int noteOffTime = 1000 * (i + 1);
track.add(new MidiEvent(noteOn , noteOnTime ));
track.add(new MidiEvent(noteOff, noteOffTime));
}
Soundbank soundbank = MidiSystem.getSoundbank(new File("titanic.sf2"));
Synthesizer synth = MidiSystem.getSynthesizer();
synth.open();
synth.loadAllInstruments(soundbank);
synth.getChannels()[0].programChange(1);
Sequencer sequencer = MidiSystem.getSequencer(false);
sequencer.open();
sequencer.setSequence(sequence);
sequencer.setTempoInBPM(120);
sequencer.addMetaEventListener(new MetaEventListener() {
public void meta(MetaMessage msg)
{
if (msg.getType() == 47) {
// end of sequence
System.exit(0);
}
}
});
sequencer.getTransmitter().setReceiver(synth.getReceiver());
sequencer.start();
}
}
First loadAllInstruments and then open the synth:
synth.loadAllInstruments(soundbank);
synth.open();

I/O Java required int

I am trying to use I/O to give a report on the stock that I need (if the stock is below 8).
It tells me it requires an int for myShop.listLowStockToFile());; when I add a number it tells me that 'void is not allowed here'. How can I fix this?
public void listLowStockToFile(int threshhold)
{
System.out.println("****The Stock that is getting low is: " + " Minimum " +threshhold + " Report for Bob Shaw****\n");
for (Item nextItem : items)
{
if(nextItem.getNuminStock() < threshhold)
{
System.out.println(nextItem);
}
}
}
public class Report {
public static void main(String[] args) {
Shop myShop = new Shop();
CD cd1 = new CD("Abba Gold", "Abba", 15);
myShop.addItem(cd1);
Game game1 = new Game("Chess", 2, 39.95);
myShop.addItem(game1);
ElectronicGame eg1 = new ElectronicGame("Shrek", "PS2", 1, 79.50);
myShop.addItem(eg1);
ElectronicGame eg2 = new ElectronicGame("Doom", "PC", 2, 30.20);
myShop.addItem(eg2);
ElectronicGame eg3 = new ElectronicGame("AFL", "PS2", 2, 49.95);
myShop.addItem(eg3);
cd1.receiveStock(3);
game1.receiveStock(5);
eg1.receiveStock(10);
eg2.receiveStock(1);
cd1.receiveStock(7);
cd1.sellCopy(true);
cd1.sellCopy(true);
eg2.sellCopy(true);
myShop.listItems();
myShop.listLowStockToFile(8);
myShop.listGamesByPlatform("PS2");
myShop.calcTotalSales();
Game game2 = new Game("Chess", 2, 39.95);
myShop.addItem(game2);
eg2.sellCopy(false);
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("LowStock.txt"));
writer.write("Report dated" + new Date() + "\n");
writer.write(myShop.listLowStockToFile()); // This line.
writer.close();
System.out.println("Report finished");
} catch (Exception ex) {
System.out.println("File I/O error" + ex);
}
}
}
You need listLowStockToFile to return a String:
public String listLowStockToFile(int threshhold) {
String rtn = "****The Stock that is getting low is: " + " Minimum " +threshhold + " Report for Bob Shaw****\n";
for (Item nextItem : items) {
if(nextItem.getNuminStock() < threshhold) {
rtn += nextItem.toString() + "\n";
}
}
System.out.print(rtn);
return rtn;
}
The reason is that BufferedWritter.write takes a String as an argument.

Android internet speed test

I am developing a speed test app like OKLA app (http://www.speedtest.net/).
I've been trying to get bandwidth rate with the most common approach:
Get the time before downloading.
Download some file for some time X.
Get the time after downloading and the total size downloaded.
Calculate speed from TIME and BYTES RECEIVED.
Also, I execute this in two different threads at the same time because is required to saturate de connection to achieve good results.
This approach works very well on PC environment with this JAVA code:
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class TestVelocidad {
static long totalBytesReceived = 0; //
static long startSample;
static long endSample ;
private static final long TIME_FOR_DOWNLOAD_MILISECONDS = (long) 10000.0;
private static final long MILI_TO_NANO = 1000000;
public static void main(String[] args) throws InterruptedException, ExecutionException {
try{
final ExecutorService service;
String downloadFileUrl100MB = "http://cachefly.cachefly.net/100mb.test";
startSample = System.nanoTime();
service = Executors.newFixedThreadPool(6);
FutureTask futureTask_1 = new FutureTask(new SpeedTestThread(downloadFileUrl100MB));
service.execute(futureTask_1);
FutureTask futureTask_2 = new FutureTask(new SpeedTestThread(downloadFileUrl100MB));
service.execute(futureTask_2);
service.shutdownNow();
long result1 = (Long) futureTask_1.get();
long result2 = (Long) futureTask_2.get();
endSample = System.nanoTime();
long timeSpent = (long) endSample-startSample;
long totalBytesReceived = result1 + result2;
System.out.println("Time of threads: " + timeSpent/1000000000.0 + " seconds " + "\nbytes received: " + (totalBytesReceived) );
double calculatedSpeed;
// long finalTimeSpent ;
// finalTimeSpent = (long) ((TIME_FOR_DOWNLOAD_MILISECONDS * MILI_TO_NANO - diff));
calculatedSpeed = SpeedInfo.calculate(timeSpent, totalBytesReceived).megabits;
System.out.println("Velocidad calculada: " + calculatedSpeed + " mbps" );
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class SpeedTestThread implements Callable<Long> {
private String url = new String("");
private static final long TIME_FOR_DOWNLOAD_NANOSECONDS = (long) 10000000000.0;
private static final long MILI_TO_NANO = 1000000;
private long bytesThread;
public SpeedTestThread(String urlToDownload){
url = urlToDownload;
}
public void run() {
}
#Override
public Long call() throws Exception {
System.out.println("FileDownload " + " File to download: " + url );
InputStream stream = null;
long startCon = System.nanoTime();
URL urlToDownload = null;
try {
urlToDownload = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection con = null;
try {
con = urlToDownload.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
con.setUseCaches(false);
//Tiempo de acceso al archivo.
long connectionLatency = (System.nanoTime() - startCon)/MILI_TO_NANO;
System.out.println("Connection latency = " + connectionLatency + "");
con.setConnectTimeout(5000);
try {
stream = con.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
long startNano = System.nanoTime();
int currentByte = 0;
try {
while ((currentByte = stream.read()) != -1 ) {
bytesThread++;
if ((System.nanoTime() - startNano) > TIME_FOR_DOWNLOAD_NANOSECONDS){
System.out.println("Time");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Thread bytes received: " + bytesThread);
return bytesThread;
}
}
class SpeedInfo {
public double kilobits = 0;
public double megabits = 0;
public double downspeed = 0;
private static final double BYTE_TO_KILOBIT = 0.008;
private static final double KILOBIT_TO_MEGABIT = 0.001;
/**
* 1 byte = 0.0078125 kilobits
* 1 kilobits = 0.0009765625 megabit
*
* #param downloadTime in miliseconds
* #param bytesIn number of bytes downloaded
* #return SpeedInfo containing current testVelocidadThread
*/
public static SpeedInfo calculate(final long downloadTime, final long bytesIn) {
SpeedInfo info = new SpeedInfo();
//from mil to sec
System.out.println("Bytes transferidos: " + bytesIn + "Tiempo de descarga: " + downloadTime/1000000000);
double time = downloadTime;
double byteIn1 = bytesIn;
double division = (double)(byteIn1 / time);
double bytespersecond = ((division) * 1000000000);
double kilobits = bytespersecond * BYTE_TO_KILOBIT;
double megabits = kilobits * KILOBIT_TO_MEGABIT;
info.downspeed = bytespersecond;
info.kilobits = kilobits;
info.megabits = megabits;
return info;
}
}
The problem is when I run this on a Android application, I had good results on phones with more processing and memory capacity, but poor results on phones with lower capacity.
Any good ideas to achieve good results on most android's phones?.
try to download the file with java nio rather than java io
java io transfer the file first to memory which make the performance poor on low end devices
while java nio using channels you can transfer the file to storage which will make the performance same on all devices approximately
use this code :
len = out.getChannel().transferFrom(readableByteChannel , seekPos , Long.MAX_VALUE);

Categories