adding sfx on Clip object in java - java

I'm working on a project where I will have one 24-hours long sound clip which has different phases based on local daytime (morning phase has one sound, transition phases, evening phase, etc.)
so here is what i got now, and it's ok
method that plays the clip (turns current local time in microseconds and sets starting point to match current time - if i start program 13:35 it will start playing mid-day phase of sound which is on that position, and it's ok
void playMusic(String musicLocation){
try{
File musicPath = new File(musicLocation);
if(musicPath.exists())
{
Calendar calendar = Calendar.getInstance();
//Returns current time in millis
long timeMilli2 = calendar.getTimeInMillis();
System.out.println("Time in milliseconds using Calendar: " + (timeMilli2 * 1000)) ;
AudioInputStream audioInput = AudioSystem.getAudioInputStream(musicPath);
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.setMicrosecondPosition(12345678);
clip.start();
clip.loop(Clip.LOOP_CONTINUOUSLY);
System.out.println(clip.getMicrosecondLength());
//setFramePosition
JOptionPane.showMessageDialog(null, "Press OK to stop playung");
}
else
{
System.out.println("no file");
}
}catch(Exception ex){
ex.printStackTrace();
}
}
main method that just calls this method
public static void main(String[] args) {
String filepath = "src/sounds/test_file.wav";
PyramidMethods pyra = new PyramidMethods();
pyra.playMusic(filepath);
}
now this is pretty simple and straightforward, and also what I need, but now what i wonder is the following -> can I and if can, how, add sound effects based on the temperature outside?
so what I was thinking is to open separate thread in main which would regularly check some wheather API and when temperature changes add sound effects like echo, distortion or something else based on temperature change (if it's colder then x it would put echo sound effect on running clip, etc.)
it this even possible in Java? it's my first time using sounds with Java so I am even inexperienced with the search terms here, would someone suggest some other programming language for it?
thanks for your answers in advance.

That must be a huge file!
Yes, Java works quite well for creating and managing soundscapes.
It is possible to play and hear different Clips at the same time. When you play them, Java automatically creates a Thread for that playback, and most operating systems will mix together all the playing threads. At one time there were Linux systems that only allowed a single output. IDK if that is still a limitation or if you are even targeting Linux systems. Also, there is going to be a ceiling on the total number of sound playbacks that an OS will be able to handle cleanly. (Usually what happens is you get dropouts if you overstress the system in this way.)
To manage the sounds, I'd consider using a util.Timer (not the Swing.Timer), and check the time and date (and weather if you have an API for that) with each iteration before deciding what to do with the constituent cues of your mix. Or maybe use an util.concurrent.ExecutorService. If your GUI is JavaFX, an AnimationTimer is also a reasonable choice.
If you do prefer to mix the sound files down to a single output line, this can most easily be done by using a library such as TinySound or AudioCue. With AudioCue (which I wrote) you can both mix down to a single output, and have guaranteed volume, panning and even playback speed management for each sound cue that is part of your "soundscape".
This could help with lowering the total amount of RAM needed to run program. As I show in a demo, one can take a single cue (e.g. a frog croak) and play it multiple times as different volumes, pans, and speeds to create the illusion of a whole pond of frogs croaking. Thus, a single .wav, only a second in length can be used to simulate a .wav that is hours in length.
I think if you want to add effects like echo or distortion, you will have to use a library or write your own. Java supports Processing Audio with Controls, but this is highly dependent upon the OS of the computer being used. Echo and Distortion are not terribly difficult to write though, and could be added to the AudioCue library code if you have incorporated that into your program. (Echo involves adding a time delay, usually using an array to hold sound data until it is time for it to play, and Distortion involves running the PCM sound data through a transform function, such as Math.tanh and a max and min to keep the results within the [-1, 1] range.)
For other possible libraries or languages, I believe both Unity (C#) and Unreal (C++) game engines/environments have extensive array of audio effects implemented, including 3D handling.

Related

How to make volume up down animation in Java

I am developing a music player and I am almost done. But I need to try something because I have seen there are more commercial music applications use different types of animations for volume up and down while playing the music.
I need something like this,
.
How can I do this? Can anybody help me? Thank you in advance.
If you are outputting your audio via a SourceDataLine, it is possible to inspect the audio data as it is being processed. There is a useful code example of this presented in the Oracle Sound Trail tutorials, on the page Using Files and Format Converters, in the section "Reading Sound Files". The important point in the code is marked with a comment "// Here, do something useful"
At that point you would convert the bytes to audio values, and use the values as part of an RMS calculation. Details for the coversion and the RMS calculation should be searchable--I know I've seen explanations for both on stackoverflow.
Once you have an RMS value calculated, it can be sent to an independent thread that handles the graphics visualization. A loose-coupling pattern should be employed so that you minimize the amount of work being done on the audio thread, and so that you avoid any blocking that might hang up the audio.
For example, the visualization thread can have a setRMSValue method that simply updates an instance variable, without synchronization or blocking of any sort. The audio processing thread can call this method freely as it generates new RMS data points. The visualizer can simultaneously read the current instance variable at your animation rate. No synchronization needed. If the visualization thread skips a few RMS data points, it should not a problem.

Most accurate Timer in Scala for MIDI sequencer

I am working on a music application, in Scala, to generate MIDI sequences in real time. The MIDI messages are being sent to another application (Ableton DAW) and possibly even external hardware. Accurate timing is very important for this use case, otherwise the resulting music will sound off-time.
I tried using java.util.Timer to schedule notes on different sequences but apparently that timer can drift by hundreds of milliseconds.
What is the most accurate Timer to use in Scala (or Java) is this even a reasonable task to try to accomplish on the JVM? or maybe I'm going about this all wrong?
Usual timer implementations are based on the scheduler.
If you need accuracy, you can roll your own:
def after(when: Duration)(f: => Unit) {
val deadline = when.fromNow
while(! deadline.isOverdue) ()
f
}
This will burn your cpu like crazy, but it doesn't get any more accurate than that.

Generate audiotrack as separate thread and make manipulations during playing

I am trying to build an app in java with android studio, and what I want to do is to generate a AudioTrack (right now basically a sine wave), but I want this to run as a separate thread (so multiple tracks can be started simultaneous, and also the rest of the app is not locked while playing), and I want to make it stop on demand (for example pushing a stop button). However I also want to be able to make changes in parameters such as frequency while the track is playing and get these changes in more or less realtime (a small delay is definitely acceptable)
This must be pretty standard, but I can't get my head around how to do it, because if the class generating the audio is a separate class I seem to loose access to the built in functions (if they are not native to Thread class), and also I can't make changes to internal variables (like frequency), while the audio is being generated.
Below is the code right now producing the sound, basically building a buffer in a loop and then writing to the audio track. Any ideas how I can do this?
for (int i = 0; i < mSound.length; i++) {
double beatFreq = Math.sin((2.0*Math.PI * i/(44100/this.beat)));
mSound[i] = beatFreq*Math.sin((2.0*Math.PI * i/(44100/this.pitch)));
mBuffer[i] = (short) (mSound[i]*Short.MAX_VALUE);
}
mAudioTrack.setStereoVolume(AudioTrack.getMaxVolume(), AudioTrack.getMaxVolume());
mAudioTrack.play();
mAudioTrack.write(mBuffer, 0, mSound.length);
mAudioTrack.stop();
mAudioTrack.release();

Using multiple timers in a Java application with animation

I'm writing a Java Application that will side scroll sheet music across the screen and then when it crosses a middle line, it will play the note(s).
It will have a variable speed based on the beats per minute.
Every quarter of a beat I need to have a "tick" function that will get the next note (if any) and start its animation. To calculate this tick I have a function 60000ms/bpm/4. This will be separate from the animation timer, because the repaint should probably be called at some constant rate.
So I'm thinking I need Util Timer for the "ticks" and a swing timer for the JPanel and drawing in the paintComponent() method.
My question is: What would be the best practice for accomplishing this? I've done a fair amount of Java programming, but no Swing or animations so I would like to learn the best way to do this.
Thanks
Nate
There is no reason to use Timer or TimerTask to solve this problem.
In this case, you have a series of notes, and when you start playing, you can calculate ahead of time, the exact time that each and every note should play. I am assuming that you already have some sort of loop that is updating the display at a steady rate. (e.g. 30 refreshes per second, or something like that). Given such a loop, all you need is an event oriented class that can tell you whether it is time to play a note.
long noteTime[] = new long[numberOfNotes];
long startTime = System.currentTimeMillis();
Declare the above array. Then walk through all the notes in the song, and calculate the time that each note is expected to play. Say you have qurter notes, the first note will play at startTime, the second one beat after startTime, the third two beats after start time, etc. This is where you calculate the time for a beat and use it. Just calculate the actual time values for each note to play.
Then, in the middle of your event loop that is refreshing the display, include the following code:
int nextNote = 0;
while (event_loop_condition) {
.
.
.
if (System.currentTimeMillis()>noteTime[nextNote]) {
playNote(nextNote++);
}
.
.
.
}
The point is that you already have an event loop, all you need to know is whether it it time yet to play the note, and this will do that for you.
On the other hand, if you are not handling the refresh, and you really do want to do this on a thread, the follow method can be called on a thread, and it will play all the notes at the correct times:
playAllNotes() {
for (int i=0; i<numberOfNotes; i++) {
Thread.sleep(noteTime[i]-System.currentTimeMillis());
playNote(i);
}
}
The sleep statement will delay until the time that the note should be played, and will play it at that time. Then it will sleep until the time for the next note to be played.
The important thing to notice about both methods, is that any delay in playing a note is NOT compounded for the next note. Say some system utility kicks in and delays one note by 50ms. The next note will not be delayed by this, because you calculated all the times for all the notes to be played up front. Given that threads are competing for CPU time, you will have thread/process contention, and there will be small variances in the time that notes are played, but they will never compound!
A lot of programmers inappropriately use timers (See discussion of Timers) on my website if you want to know more.

How to rewind application state?

I'm developing a Java desktop flight simulation. I need to record all the pilot actions as they occur in the cockpit, such as throttle controls, steering, weapon deployment, etc. so that I can view these events at a later time (or stream them live).
I'd like to add a visual replay feature on the playback of the events so I can visually see the cockpit as I move forward and backward in time. There's no problem with the replay as long as I play back the event in chronological order, but the rewind is a little trickier.
How would you implement the rewind feature?
I would use a modified Memento pattern.
The difference would be that I would have the Memento object store a list of all of the pilot actions.
The Memento pattern is typically used for rolling back (undo), however in your case I could see it applying as well. You would need to have the pilot actions be store-able states as well.
You could use a variant of the Command Pattern and have each one of your pilot actions implement an undo operation.
For example if your pilot made the action steer left (simple, i know) the inverse of it would be steer right.
public interface IPilotAction {
void doAction(CockpitState state);
void undoAction(CockpitState state);
}
public class ThrottleControl implement IPilotAction {
private boolean increase;
private int speedAmount;
public ThrottleControl(boolean increase, int speedAmount) {
this.increase = increase;
this.speedAmount = speedAmount;
}
public void doAction(CockpitState state) {
if (increase) {
state.speed += speedAmount;
} else {
state.speed -= speedAmount;
}
}
public void undoAction(CockpitState state) {
if (increase {
state.speed -= speedAmount;
} else {
state.speed += speedAmount;
}
}
What you're looking for is actually a blend of the Command and Memento patterns. Every pilot action should be a command that you can log. Every logged command has, if req'd, a memento recording any additional state that (A) is not in the command, and (B) cannot reliably be reconstructed. The "B" is important, there's some of this state in pretty much any non-trivial domain. It needs to be stored to recover an accurate reconstruction.
If you merge these concepts, essentially attaching a memento to each command, you'll have a fully logged series of deterministic events.
I discussed this at more length in a different answer. Don't be afraid to substantially adapt the design patterns to your specific needs. :)
RE Performance Concerns:
If you expect jumping a number of minutes to be a frequent case, and after implementation you show that it's an unworkable performance bottleneck, I would suggest implementing an occasional "snapshot" along with the logging mechanism. Essentially save the entire application state once every few minutes to minimize the amount of log-rolling that you need to perform. You can then access the desired timeframe from the nearest saved state. This is analogous to key frames in animation and media.
Not a direct answer, but check out discussion of implementing undo. Mostly they will be about text editors, but the same principles should apply.
It helps if you prefer immutability. Undoing complex changes is difficult. Even automated systems have performance problems (Software Transaction Memory, STM).
Make sure that you've implemented the simulation in such a way that the simulation's "state" is a function. That is, a function of time.
Given an initial state at time T0, you should be able to construct the simulation frame at time Tn for any n. For example, an initial stationary state and no events (yet) might equal the identity function, so Tn == Tn+1.
Given some pilot action event at time Ta, you should be able to construct a frame Ta+n for any n. So you think of events as modifying a function that takes a time value as argument and returns the frame of the simulation for that time.
I would implement the history of events as a Zipper of (time, function) pairs representing the control state of the simulation. The "current" state would be in focus, with a list of future states on the right, and past states on the left. Like so:
([past], present, [future])
Every time the simulation state changes, record a new state function in the future. Running the simulation then becomes a matter of taking functions out of the future list and passing the current time into them. Running it backwards is exactly the same except that you take events out of the past list instead.
So if you're at time Tn and you want to rewind to time Tn-1, look into the past list for the latest state whose time attribute is less than n-1. Pass n-1 into its function attribute, and you have the state of simulation at time Tn-1.
I've implemented a Zipper datastructure in Java, here.
you can just store the state at every instance. 1kb for state (wind speed, object speeds + orientation / control input states, x 30fps x 20 min ~ 36megs. 1kb of state would let you record about 16 objects (pos / speed / angular speed / orientation / and 5 axis of control / effect)
that may be too much for you, but it will be easiest to implement. there will have to be no work done at all to recreate state (instant acecss), and you can interpolate between states pretty easy (for faster / slower playback). for disk space you can just zip it, and that can be done while recording, so while playing that memory is not being hogged.
a quick way to save space would be to paginate the recording file, and compress each bin separately. ie one zip stream for each minute. that way you would only have to decompress the current bin, saving a bunch on memory, but that depends how well your state data zips.
recording commands and having your class files implement multiple directions of playback would require a lot of debugging work. slowing / speeding up playback would also be more computationally intensive. and the only thing you save on is space.
if thats a premium, there are other ways to save on that too.

Categories

Resources