I have been trying to generate a tone (444 hz, 1000 hz, etc) and then play it in Android. My first searches gave me this stack overflow question. While this works great given a duration, I would prefer to make the duration infinite (loop-able).
First I used only use integer values for the tone, because this would mean that I could use 1 second and it should loop properly. However there are still some frequencies that don't loop right.
Second I thought I could only calculate 1 period of the sine wave, and then loop that. However I found out that is not a viable approach
How can I, given any frequency, generate a tone that I can loop?
You can create a thread that will run your tone every period of time(for example 2sec.):
private Runnable startSoundRunnable = new Runnable() {
#Override
public void run() {
while (true) {
try {
toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE, 2000);
sleep(2000);
} catch (Exception ex) {}
}
}
};
// Run thread
new Thread(startSoundRunnable).start();
Related
I have been trying to create a way to recreate the pokemon's "Rolling text" where one letter appears at a time. The problem is being able to create a timer short enough to make it reasonable.
This is what i have tried:
public static void roll(String text) {
int i = 0;
while(i < text.length()) {
try {
Thread.sleep(200); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.out.print(text.charAt(i));
i++;
}
}
This will work fine if i set the value in Thread.sleep to anything above 250. The problem is, if i set seconds below 250 then it will wait the entire length of time (If i tell it to wait 100 millisends 100 times, it will wait 10 seconds) before outputting anything.
Im not sure if this is a problem with the type of timer itself or if there is something else at play here.
You can use System.out.flush(); to force the buffer to be written out.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
So I was digging around in some old java projects that I never finished and I pulled out this little number that is of my best projects ever built.
It's a desktop clock widget coded in java and it works perfectly fine except for one thing. The way I have it check the current time to stay updated is in a loop and the loop "crashes" in a matter of seconds so the widget no longer gets the current time.
This is how the loop is constructed (reduced in size):
public class getCurrentTime {
public static void getTime() throws InterruptedException {
int hour = global.calendar.get(Calendar.HOUR);
int minute = global.calendar2.get(Calendar.MINUTE);
if(hour == 0) {
global.hour.setIcon(new ImageIcon("resources/hours/12.png"));
}else if(hour == 23) {
global.hour.setIcon(new ImageIcon("resources/hours/11.png"));
}else {
global.hour.setText("?");
}
if(minute == 0) {
global.minute.setIcon(new ImageIcon("resources/minutes/00.png"));
}else if(minute == 59) {
global.minute.setIcon(new ImageIcon("resources/minutes/59.png"));
}else {
global.minute.setText("?");
}
Thread.sleep(1000);
getTime();
}
}
global is a class where I keep most of my variables (I know it's weird, this was like 3 years ago, it's how I used to write my programs).
So my main question is, is there a way that I can prevent the loop from "crashing"?
Thanks in advance!
This is not a loop, really. It is a recursive call. In each recursion, some more memory will be allocated, so it will after some time go out of memory. I wonder why this is a matter of seconds here, but anyway.
Try using a Timer to schedule the gui update.
Edit : you are creating a new ImageIcon in each recursion. They can be rather large in memory. Maybe they are the reason for the rapid "crash".
Apart from that I suggest sticking to java naming conventions. Class names should start with a capital letter.
Thread.sleep(1000); is not going to be a good option. You can use Timer. By using a Timer you schedule a task at regular intervals.
Timer timer = new Timer();
long interval = (1000) ; // 1 sec
timer.schedule( new TimerTask() {
public void run() {
//do your work;
}
}, 0, interval);
If you want to stop the scheduling, you can use timer.cancel();
EDIT: as Fildor said I think memory is your problem. Use timer this way, it should solve your problem.
This is first solution
class clockUpdater implements Runnable {
#Override
public void run() {
Thread.sleep(WAIT_TILL_NEW_MINUTE);
while(true){ //a infinite loop
// the Swing call below must be queued onto the Swing event thread
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
//your clock updating code here
}
});
try {
Thread.sleep(1000*60);//you only need to update once after a minute
} catch (InterruptedException e) {
// ....
}
}
}
}
This is second
class clockUpdater extends Thread{
#Override
public void run(){
Thread.sleep(WAIT_TILL_NEW_MINUTE);
while(true){
try{
//your update code here
Thread.sleep(60*1000)//
}
catch(Exception e){
//..
}
}
}
}
Note: You need to start this as soon as the minute changes in system time. Or clock time will lag behind. Calculate WAIT_TILL_NEW_MINUTE as soon as your program starts. Better to update only when it is needed.
The answer for your question is
use set timeout function for the function
which you want to avoid loop crashing.
Like:
setTimeout(function() {
// write the logic
},1000);
I am writing Ukelele Simulator, and I want to play a note on each string with a short delay in between. Currently, I have a method that returns an AudioClip containing the sound of the currently pressed note on each string, and I am attempting to play those AudioClips in succession with a 500 millisecond delay using Thread.sleep().
public static void main(String[] args){
//test it
UkeString stringG = new UkeString('G');
UkeString stringC = new UkeString('C');
UkeString stringE = new UkeString('E');
UkeString stringA = new UkeString('A');
try{
AudioClip G = stringG.getNoteAudio();
AudioClip C = stringC.getNoteAudio();
AudioClip E = stringE.getNoteAudio();
AudioClip A = stringA.getNoteAudio();
G.play();
Thread.sleep(500);
C.play();
Thread.sleep(500);
E.play();
Thread.sleep(500);
A.play();
Thread.sleep(500);
}
catch(Exception e){
System.out.println(e);
}
return;
}
However, I am encountering some odd irregular behavior from Thread.sleep(). Normally, when I execute the above code the first Thread.sleep() following G.play() either does not execute for the full 500 milliseconds or not at all, because the 'G' and 'C' notes are played in rapid succession. After that, the 'E' and 'A' notes will play as expected in 500 millisecond intervals.
The really weird thing is that if I run the program again before the other instance has ended (i.e. the notes in the old instance are still playing), then the new instance executes as expected with all the notes playing in 500 millisecond intervals. What's going on here?
See http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
Your answer is here (in bold):
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers.
In other words, you can't have that much of a fine control with time using Thread.sleep()
I need to simulate in Java N sensors that send to me an obsvertation at random time. Where an observation contain more value like:
timestamp - temperature - umiditiy - ...
When i receive an observation from anyone (the time of observation is random for all sensor) of the N sensors i need to call a rutine R that refresh a data structure (in common between all sensors) with some counting.
I need to syncronyze the R call, if i call R first time for call R second time i need R first time to finish his work.
All my observation are actually stored in a CSV file, one file for sensor. But i need to simulate a "online streaming".
How i can make that in Java? If i make N threads (one for sensor) that read his CSV file, i can't read the observation in right temporal order over all CSV.
For example, if i have this 2 csv:
Csv1:
18:00 - low - low
19:00 - low - high
Csv2
18:03 - high - low
I need first to refresh my counting with obsvervation at time 18:00 in csv1, then with obsvervation at time 18:0 in csv2 and finally with observation at time 19:00 in csv2.
EDIT1: I have make a test with SynchronousQueue because I need to syncronyze my N thread, my problem is when one thread do something on counting structure other thread can't access to it.
I have find this example:
package threadTest;
import java.util.concurrent.SynchronousQueue;
public class SynchronousQueueTest
{
private SynchronousQueue sq = new SynchronousQueue(true);
class PutThread implements Runnable
{
public void run()
{
for(int i=0; i <1000; i++)
{
try {
System.out.println("PUT");
//sq.put("A");
sq.put("A");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TakeThread implements Runnable
{
public void run()
{
for(int i=0; i <1000; i++)
{
try {
System.out.println("TAKE");
System.out.println(sq.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
new Thread((new SynchronousQueueTest()).new PutThread()).start();
new Thread((new SynchronousQueueTest()).new TakeThread()).start();
}
}
But i have not the expected result. The output is only this:
PUT
TAKE
But i'm expected 1000 PUT and 1000 TAKE alternate. What is the problem?
Ha. That sounds so much like what I do usually when preparing stock tick data for back test.
Normally you massage the CSV files to be at least internally time ordered. Then you can either read them and combine at beginning - or if you have multiple readers you need to put the data into a PriorityQueue based structure, say, DelayQueue. Have your simulation data structure wrap the actual data and implement Delayed interface so you know how much delay you need. This is all you need from reading side.
From publishing side, use just 1 thread and publish to the time you needed - then schedule the next round with delay like 1ms or so. That's usually enough.
From subscriber side, the subscriber is blind and just take the data as if it's from real.
BTW, if you are really doing back testing or so, you might want to write up your own time service class which can simulate a faster tick of the data.
I was just wondering how i would let my java program continue running, but always be ready to take input.
Right now i am using a bufferreader and reading in a line, but that makes my program halt and wait for input. I want the program to continue running but be ready to take input whenever needed, is there a way to do this?
I would expect that you're going to have to look into multithreading your application in order to get this working as you desire.
Edit: Of course, while this functionality can be achieved by a purely CLI interface, you would probably be better off exploring other options (i.e. GUI options) if you intend on having a full response/event-driven system running in a multithreaded fashion.
Here is a quick example of how a multi-threaded command line interface application may work. This will not require polling for input, nor a GUI interface in order to perform tasks in the background while waiting for input from a user in a console.
In this example, a Thread is running in the background, which can be told to output a greeting in a specified number of seconds later.
public class CommandLineMultiThread
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
// Makes and runs the background thread.
MyThread myThread = new MyThread();
Thread t = new Thread(myThread);
t.start();
// Get the number of seconds to wait from the console.
// Exit when "0" is entered.
int waitDuration;
do
{
waitDuration = s.nextInt();
myThread.setGreetIn(waitDuration);
} while (waitDuration != 0);
myThread.quit();
}
static class MyThread implements Runnable
{
boolean running = true; // Boolean to keep thread alive.
long greetingTime = Long.MAX_VALUE; // Time to greet at.
public void setGreetIn(int i)
{
greetingTime = System.currentTimeMillis() + (i * 1000);
}
public void quit()
{
running = false;
}
public void run()
{
while (running)
{
if (System.currentTimeMillis() > greetingTime)
{
System.out.println("Hello!");
greetingTime = Long.MAX_VALUE;
}
try
{
Thread.sleep(100);
}
catch (InterruptedException e) {}
}
}
}
}
The Scanner class can be used to accept user input from the command line interface by routing the input from the System.in object.
Then, while the background thread myThread is running, the main thread is waiting for an input from System.in via the Scanner.nextInt method. Once the seconds to wait has been accepted, the background thread is told to wait until a certain time, and once that time arrives, the greeting Hello! is output to the console.
I think your program will have to occasionally poll for user input.
Give it a nice multi-threaded GUI instead of a CLI :)
I agree with James, another alternative is "faking" continuous program running. This won't work with all scenarios, but you can set a timer right before you display the user input, then calculate the time between stop and "start" again when the user inputs something.
Use that time to perform a repeated function a certain number of times. This is only helpful if you've got something on a timer itself already, like a constantly draining integer every few seconds.
An example:
You ask the user a question but only want to give them 5 seconds to answer. When the user answers (hits enter) the program will compute the time it took them to enter, if too long, throw one message, if under the time limit throw another.
I'm only suggesting this method because threading, which is what you really want to get into, is quite advanced.