I'm currently reading in MIDI messages in real-time from my midi keyboard using a class that implements Receiver, and outputting the notes played.
The only information i receive when I press a note is the MidiMessage and a timeStamp.
I am trying to paint the notes as actual piano sheet music and currently the user has to set the bpm beforehand.
Therefore if I know the tempo is 120bpm (for example), how can I use the timeStamps to determine the length of the note pressed?
I'm assuming if I can convert the timeStamps into ticks (ppq), then I can use that to work out the timings.
Any help is greatly appreciated. Below is my "send" method in my Receiver class.
The 'firstStamp' and 'secondStamp' variables are just to output the length of a note. I took the timeStamp when a note was released and subtracted the timeStamp when it was pressed.
#Override
public void send(MidiMessage message, long timeStamp) {
String strMessage = null;
if (firstStamp == 0) {
firstStamp = timeStamp;
secondStamp = timeStamp;
}
firstStamp = secondStamp;
secondStamp = timeStamp;
stampDif = (secondStamp - firstStamp);
if (message instanceof ShortMessage) {
strMessage = decodeMessage((ShortMessage) message, timeStamp);
} else if (message instanceof MetaMessage) {
strMessage = decodeMessage((MetaMessage) message);
} else if (message instanceof SysexMessage) {
strMessage = decodeMessage((SysexMessage) message);
} else {
strMessage = "other message" + message.getStatus();
}
r_out.println("Timestamp: " + timeStamp + " " + strMessage);
r_printStream.println("Timestamp: " + timeStamp + " " + strMessage);
}
If the timestamp is in milliseconds then you can convert it to ticks like this:
long ticks = timestamp * bpm / (1000 * 60);
Bit you will get a high start tick since the timestamp is probably since Jan 1 1970. So if you want to have your first "tick" as 0 you need to keep track of if this is your first seen event.
if (tickOffset == -1) { // Using -1 as not initialized
tickOffset = ticks;
}
ticks = ticks - tickOffset;
Related
I use UsageStats feature of Android, but the smallest interval is DAILY INTERVAL.
long time = System.currentTimeMillis();
List<UsageStats> appList = manager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - DAY_IN_MILLI_SECONDS, time);
How can I get UsageStats in an hourly interval?
All credit goes to this answer. I have learned from that one.
How can we collect app usage data for customized time range (e.g. for per 1 hour)?
We have to call queryEvents(long begin_time, long end_time) method as it will provide us all data starting from begin_time to end_time. It give us each app data through foreground and background events instead of total spent time like queryUsageStats() method. So, using foreground and background events time stamp, we can count the number of times an app has been launched and also can find out the usage duration for each app.
Implementation to Collect Last 1 Hour App Usage Data
At first, add the following line in the AndroidManifest.xml file and also request user to get permission of usage access.
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
Add the following lines inside any method
long hour_in_mil = 1000*60*60; // In Milliseconds
long end_time = System.currentTimeMillis();
long start_time = end_time - hour_in_mil;
Then, call the method getUsageStatistics()
getUsageStatistics(start_time, end_time);
getUsageStatistics methiod
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void getUsageStatistics(long start_time, long end_time) {
UsageEvents.Event currentEvent;
// List<UsageEvents.Event> allEvents = new ArrayList<>();
HashMap<String, AppUsageInfo> map = new HashMap<>();
HashMap<String, List<UsageEvents.Event>> sameEvents = new HashMap<>();
UsageStatsManager mUsageStatsManager = (UsageStatsManager)
context.getSystemService(Context.USAGE_STATS_SERVICE);
if (mUsageStatsManager != null) {
// Get all apps data from starting time to end time
UsageEvents usageEvents = mUsageStatsManager.queryEvents(start_time, end_time);
// Put these data into the map
while (usageEvents.hasNextEvent()) {
currentEvent = new UsageEvents.Event();
usageEvents.getNextEvent(currentEvent);
if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED ||
currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED) {
// allEvents.add(currentEvent);
String key = currentEvent.getPackageName();
if (map.get(key) == null) {
map.put(key, new AppUsageInfo(key));
sameEvents.put(key,new ArrayList<UsageEvents.Event>());
}
sameEvents.get(key).add(currentEvent);
}
}
// Traverse through each app data which is grouped together and count launch, calculate duration
for (Map.Entry<String,List<UsageEvents.Event>> entry : sameEvents.entrySet()) {
int totalEvents = entry.getValue().size();
if (totalEvents > 1) {
for (int i = 0; i < totalEvents - 1; i++) {
UsageEvents.Event E0 = entry.getValue().get(i);
UsageEvents.Event E1 = entry.getValue().get(i + 1);
if (E1.getEventType() == 1 || E0.getEventType() == 1) {
map.get(E1.getPackageName()).launchCount++;
}
if (E0.getEventType() == 1 && E1.getEventType() == 2) {
long diff = E1.getTimeStamp() - E0.getTimeStamp();
map.get(E0.getPackageName()).timeInForeground += diff;
}
}
}
// If First eventtype is ACTIVITY_PAUSED then added the difference of start_time and Event occuring time because the application is already running.
if (entry.getValue().get(0).getEventType() == 2) {
long diff = entry.getValue().get(0).getTimeStamp() - start_time;
map.get(entry.getValue().get(0).getPackageName()).timeInForeground += diff;
}
// If Last eventtype is ACTIVITY_RESUMED then added the difference of end_time and Event occuring time because the application is still running .
if (entry.getValue().get(totalEvents - 1).getEventType() == 1) {
long diff = end_time - entry.getValue().get(totalEvents - 1).getTimeStamp();
map.get(entry.getValue().get(totalEvents - 1).getPackageName()).timeInForeground += diff;
}
}
smallInfoList = new ArrayList<>(map.values());
// Concatenating data to show in a text view. You may do according to your requirement
for (AppUsageInfo appUsageInfo : smallInfoList)
{
// Do according to your requirement
strMsg = strMsg.concat(appUsageInfo.packageName + " : " + appUsageInfo.launchCount + "\n\n");
}
TextView tvMsg = findViewById(R.id.MA_TvMsg);
tvMsg.setText(strMsg);
} else {
Toast.makeText(context, "Sorry...", Toast.LENGTH_SHORT).show();
}
}
AppUsageInfo.class
import android.graphics.drawable.Drawable;
class AppUsageInfo {
Drawable appIcon; // You may add get this usage data also, if you wish.
String appName, packageName;
long timeInForeground;
int launchCount;
AppUsageInfo(String pName) {
this.packageName=pName;
}
}
How can I customize these codes to collect per 1 hour data?
As you want to get per hour data, please change the end_time and start_time value for every hour data. For instance: If I would try to collect past per hour data (for past 2 hour data). I would do the following thing.
long end_time = System.currentTimeMillis();
long start_time = end_time - (1000*60*60);
getUsageStatistics(start_time, end_time);
end_time = start_time;
start_time = start_time - hour_in_mil;
getUsageStatistics(start_time, end_time);
However, you may use a Handler to skip repeatedly writing start_time and end_time to change value of these variables. Each time data will be collected for one hour, a task will be completed and after automatically changing the values of the variables, you will again call the getUsageStatistics method.
Note: Maybe, you will not be able to retrieve data for more than past 7.5 days as events are only kept by the system for a few days.
Calendar cal = (Calendar) Calendar.getInstance().clone();
//I used this and it worked, only for 7 days and a half ago
if (daysAgo == 0) {
//Today - I only count from 00h00m00s today to present
end = cal.getTimeInMillis();
start = LocalDate.now().toDateTimeAtStartOfDay().toInstant().getMillis();
} else {
long todayStartOfDayTimeStamp = LocalDate.now().toDateTimeAtStartOfDay().toInstant().getMillis();
if (mDaysAgo == -6) {
//6 days ago, only get events in time -7 days to -7.5 days
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.DATE, daysAgo + 1);
end = cal .getTimeInMillis();
start = end - 43200000;
} else {
//get events from 00h00m00s to 23h59m59s
//Current calendar point to 0h0m today
cal.setTimeInMillis(todayStartOfDayTimeStamp);
cal.add(Calendar.DATE, daysAgo + 1);
end = calendar.getTimeInMillis();
cal.add(Calendar.DATE, -1);
start = calendar.getTimeInMillis();
}
}
I don't think it's possible, even if you ask for data in the middle of an interval, it looks like the data is stored in buckets and the minimum bucket is a day.
In UsageStatsManager documentation, it says:
A request for data in the middle of a time interval will include that interval.
Also, INTERVAL_BEST is not a real interval, it just selects one of the available intervals for the given time range. In
UsageStatsManager.java source code, it says:
/**
* The number of available intervals. Does not include {#link #INTERVAL_BEST}, since it
* is a pseudo interval (it actually selects a real interval).
* {#hide}
*/
public static final int INTERVAL_COUNT = 4;
Yes, Android is providing minimum INTERVAL_DAILY. But for the best result, you can use INTERVAL_BEST. Android is giving the best interval timer for the given time range in queryUsageStats(int, long, long).
Happy coding...
So I'm editing a source code for a game, and I have an event reading the game's chat. I need the game to read the chat, copy some words from the chat, enter a chat message with the first word, wait a bit, enter a chat message with the second word etc.
Right now, the code looks like that:
private final long PERIOD = 4000L; //timer
private long lastTime = System.currentTimeMillis() - PERIOD;
#SubscribeEvent
public void onChat(final ClientChatReceivedEvent e) { //look at the chat
final String chat = e.message.getUnformattedText();
if(chat.startsWith("Something")) { //if the chat message starts with "Something"
//Create the string chatp1 being "Something 123"
String click = chatp1.replace("Something ", ""); //Creates a string "click", which is chatp1 without the "Something ", so it's "123"
//After it basically does the same thing multiple times, but instead of "Something" it's "Something1" and instead of "123" it's "124" etc.
//Then I need to run the commands
MyGame.getMyGame().thePlayer.sendChatMessage("/Command " + click); //runs the command "/Command 123"
long thisTime12 = System.currentTimeMillis();
if ((thisTime12 - lastTime) >= PERIOD) { //waits
lastTime = thisTime12;
MyGame.getMyGame().thePlayer.sendChatMessage("/Command " + click2); //Runs the command "/Command 124"
//etc.
Now there's a problem: "click" and "click2" can not be found, which is obvious: these are local variables, not global ones. My question is: what is the easiest way of changing the code so "click" and "click2" can be found in the code? Should I claim them as global variables at the beginning (if so, how?) or something else?
Here is the Answer:
private final long PERIOD = 4000L; //timer
private long lastTime = System.currentTimeMillis() - PERIOD;
String click = "";
String click2 = "";
#SubscribeEvent
public void onChat(final ClientChatReceivedEvent e) { //look at the chat
final String chat = e.message.getUnformattedText();
if(chat.startsWith("Something")) { //if the chat message starts with "Something"
//Create the string chatp1 being "Something 123"
click = chatp1.replace("Something ", ""); //Creates a string "click", which is chatp1 without the "Something ", so it's "123"
//After it basically does the same thing multiple times, but instead of "Something" it's "Something1" and instead of "123" it's "124" etc.
//Then I need to run the commands
MyGame.getMyGame().thePlayer.sendChatMessage("/Command " + click); //runs the command "/Command 123"
long thisTime12 = System.currentTimeMillis();
if ((thisTime12 - lastTime) >= PERIOD) { //waits
lastTime = thisTime12;
MyGame.getMyGame().thePlayer.sendChatMessage("/Command " + click2); //Runs the command "/Command 124"
//etc.
Move their declaration into the class, so they become fields.
Hi Guys First of all I must say thanks to all of you guys for helping me :). I was a silent member before this query and benefited a lot from other members question.
But now I'm stuck in my code. See I'm developing a software that will help EVENT MANAGEMENT. I have done all that basics of creating and saving events in the database - i'm using sqlite db.
I'm stuck for code of pop-up and alarm when event time is started.
I saved date as String in db which is in this format "26-04-2015".
I saved time as String in db which is in this format "17:00:00".
What I've tried uptil now is this - I was comparing current time with that on db but failed to make it work)
Any suggestion or help will be highly appreciated.
private void checkAlarm() {
new Thread() {
Calendar cal = new GregorianCalendar();
int hour = cal.get(Calendar.HOUR);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
String time = hour + ":" + min + ":" + sec;
String[] data = connect.readData1("Select e_sdate, e_stime,e_title from tbl_event order by e_sdate ASC limit 1", "e_stime", "e_title");
String sTime = data[0];
String title = data[1];
public void run() {
while (true) {
try {
Thread.sleep(1000);
System.out.println("time from db : " + sTime);
System.out.println("time current : " + time);
} catch (Exception e) {
}
if (time.equals("sTime")) {
try {
TrayIcon icon = new TrayIcon(getIconImage(), "Event Management System", createPopupMenu());
playSound();
icon.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "This event has been started now.");
}
});
SystemTray.getSystemTray().add(icon);
Thread.sleep(3000);
icon.displayMessage("Event : " +title, "Event Time : " +sTime, TrayIcon.MessageType.INFO);
} catch (Exception e) {
System.out.println("Tray Icon Error : " +e);
}
}
}
}
}.start();
}
Ok, so I was building a clock that would give out times in the form of Log10(hour) and also minute and second in the same format, but I keep getting strange outputs when this runs. I get mostly NANs and sometimes infinity(or its negative). I have a feeling that something is wrong with the numbers that I am using(like maybe they are too large or something like that) NOTE: currentTime is a long, calendar is a Calendar, and hour, minute, and second are doubles. Also the clock variable is a JLabel. After the program goes through two iterations it always switches over to NANs.
this.timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
currentTime = System.currentTimeMillis();
calendar.setTime(new Date(currentTime));
hour = Math.log10(hour);
minute = Math.log10(minute);
second = Math.log10(second);
System.out.println(hour + " " + minute + " " + second);
return null;
}
#Override
protected void done() {
clock.setText("<html><body><p>Log Time: "
+ "Log<sub>10</sub>(" + hour + ") || "
+ "Log<sub>10</sub>(" + minute + ") || "
+ "Log<sub>10</sub>(" + second + ")</p></body></html>");
}
}.execute();
}
}, 0, 200);
This code doesn't make a lot of sense:
currentTime = System.currentTimeMillis();
calendar.setTime(new Date(currentTime));
hour = Math.log10(hour);
minute = Math.log10(minute);
second = Math.log10(second);
You're setting the time in calendar - but then completely ignoring it. I would expect you'd want something like:
currentTime = System.currentTimeMillis();
calendar.setTime(new Date(currentTime));
hour = Math.log10(calendar.get(Calendar.HOUR_OF_DAY));
minute = Math.log10(calendar.get(Calendar.MINUTE));
second = Math.log10(calendar.get(Calendar.SECOND));
EDIT: As noted on comments, you also need to consider what you'll do when the hour, minute or second is 0. (It's very unclear why you'd want to use a log-based clock to start with, to be honest.)
I am making a ping program using Java sockets. One bug in my program is that sometimes it will not connect and will just sit there for ever. So I am trying to add a timeout (after twenty seconds) and the ping will fail. But I have no idea how to.
Here is part of my ping program:
boolean result = false;
long before1 = System.nanoTime();
out.println(new byte[64]);
System.out.println("(1) Sent 64 bytes of data to " + address
+ "...");
try {
if ((in.readLine()) != null) {
int size = in.readLine().toString().getBytes().length;
long after = System.nanoTime();
long s = ((after - before1) / 1000000L) / 1000;
System.out.println("(1) Recieved reply from " + address
+ " (" + size + " bytes), time = " + s
+ " seconds...");
result = true;
} else if ((in.readLine()) == null) {
long after = System.nanoTime();
long s = ((after - before1) / 1000000L) / 1000;
System.out.println("(1) Failed to recieve reply from "
+ address + ", time = " + s + " seconds...");
result = false;
}
} catch (IOException exc) {
long after = System.nanoTime();
long s = ((after - before1) / 1000000L) / 1000;
System.err.println("(1) Failed to recieve reply from "
+ address + ", time = " + s + " seconds...\nReason: "
+ exc);
result = false;
}
But I would like to measure time elapsed any where in my code, instead of:
long time = System.nanoTime();
If one part of my code is stuck doing something it will time out after 20 seconds.
Any suggestions on how to measure if twenty seconds has passed at the start of a try/catch block or anywhere else in my code so it doesn't get stuck during the ping?
As "jsn" and "jahory" said you need to do this with threads. Here's 2 useful links, you can check them ;)
How to implement timeout using threads
Adding a thread timeout to methods in Java
You can use Future and FutureTask:
ExecutorService pingExecutor = ... // executor service to run the ping in other thread
void showPing(final String target) throws InterruptedException {
Future<String> ping = executor.submit(new Callable<String>() {
public String call() {
String pingResult = ... // do your Ping stuff
return pingResult;
}});
System.out.println("Pinging..."); // do other things while searching
try {
System.out.println(future.get(20, TimeUnit.SECONDS)); // use future, waits 20 seconds for the task to complete
} catch (ExecutionException ex) {
} catch (TimeoutException tex) {
// Ping timed out
}
}
You can find some hints here: How do I call some blocking method with a timeout in Java?
Future interface looks like a good solution to your problem. Remember, however, that depending on what your task is doing, you probably would be not able to really cancel it. Additional info:
tutorial (see, in particular, Non-blocking algorithms section)