Skip to content

Commit

Permalink
Implemented almost everything on the sound control interface.
Browse files Browse the repository at this point in the history
The only thing that needs further investigation is the music control, that doesn't work as intended (for some reason, the first time the mouse is pressed over it, it does nothing; but the rest of the time it works well...).
  • Loading branch information
Foo-Manroot committed Jun 19, 2016
1 parent 6c95155 commit 38a5e49
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 71 deletions.
95 changes: 67 additions & 28 deletions Time-Wanderer/src/sound/Jukebox.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* sound are specified at Playlist. */
package sound;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
Expand All @@ -18,18 +18,18 @@ public class Jukebox {
* This attribute stores the current state of the music (ON or OFF).
* If it's true, the music is playing.
*/
private boolean musicON;
private boolean musicON = true;

/**
* This attribute stores the current state of the sound effects (ON or OFF).
* If it's true, the effects are playing.
*/
private boolean effectsON;
private boolean effectsON = true;

/**
* A pool whose threads will play a sound (finite or in a loop). */
private final ThreadPoolExecutor pool;
private final ArrayList<Playable> playables;
private final ConcurrentLinkedDeque<Playable> playables;
private final AtomicBoolean mustWait;

/* -------------------------------------- */
Expand All @@ -42,11 +42,8 @@ public class Jukebox {
public Jukebox() {

pool = (ThreadPoolExecutor) Executors.newCachedThreadPool();
playables = new ArrayList<>();
playables = new ConcurrentLinkedDeque<>();
mustWait = new AtomicBoolean(false);

musicON = true;
effectsON = true;
}

private synchronized void waitUntilClearIfStopped() {
Expand Down Expand Up @@ -611,23 +608,13 @@ public void play(Playlist sound, int start, int end, float decibels) {
private boolean check (Playlist sound) {

/* Checks if it's a music clip and can be played */
if (musicON && (
sound.equals(Playlist.GAME_OVER) ||
sound.equals(Playlist.GUITAR_CONCERT) ||
sound.equals(Playlist.MEMORIES) ||
sound.equals(Playlist.THE_LURKING_BEAST)
)) {
if (musicON && isMusicClip(sound)) {

return true;
}

/* Checks if it's an effect clip and can be played */
return effectsON && !(
sound.equals(Playlist.GAME_OVER) &&
sound.equals(Playlist.GUITAR_CONCERT) &&
sound.equals(Playlist.MEMORIES) &&
sound.equals(Playlist.THE_LURKING_BEAST)
);
return effectsON && !(isMusicClip(sound));
}

/**
Expand All @@ -654,14 +641,55 @@ public void awaitTermination(int time, TimeUnit timeUnit) {
public synchronized void stop() {
mustWait.set(true);

for (Playable p : playables)
p.stop();
for (Playable p : playables) {

p.end();
}

playables.clear();
mustWait.set(false);
notifyAll();
}

/**
* Mute all sounds of the selected group.
*
* @param muteMusic
* If this parameter is <i>true</i>, only the music will be
* muted. If it's <i>false</i>, only sound effects will be muted.
*/
public synchronized void mute (boolean muteMusic) {

/* If it's the music the sound that will be muted, stops its
reproduction */
if (muteMusic) {

for (Playable p : playables) {

if (isMusicClip(p.getClipName())) {

p.stopPlaying();
}
}

}

/* The sound effects are finite and doesn't long very much, so they
will end by themselves and don't have to be stopped */
}

/**
* Returns <i>true</i> if the clip is a music clip. If it's a sound effect,
* returns <i>false</i>.
*/
private boolean isMusicClip (Playlist clip) {

return (clip.equals(Playlist.GAME_OVER) ||
clip.equals(Playlist.GUITAR_CONCERT) ||
clip.equals(Playlist.MEMORIES) ||
clip.equals(Playlist.THE_LURKING_BEAST));
}

/**
* This method will be called when a playable ends its task, so it can be
* removed from the list.
Expand Down Expand Up @@ -736,12 +764,21 @@ public boolean changeMusicState () {

musicON = (!musicON);

// /* If the music is playing, stops it. If it's stopped, restarts it */
// if (musicON) {
//
//
// }

if (musicON) {

mute (true);
} else {

/* Restarts the music that was being played */
for (Playable p : playables) {

if (isMusicClip(p.getClipName())) {

p.restartClip();
}
}
}

return musicON;
}

Expand All @@ -755,6 +792,8 @@ public boolean changeEffectsState () {

effectsON = (!effectsON);

mute (false);

return effectsON;
}
}
90 changes: 47 additions & 43 deletions Time-Wanderer/src/sound/Playable.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ public class Playable implements Runnable {
/**
* The path of the sound file to be played. */
private final String path;
/**
* The boolean flag that indicates if the sound must stop or continue. */
private final AtomicBoolean stopped;

/**
* The boolean flag that indicates if the sound must finish or not. */
private final boolean finite;
Expand Down Expand Up @@ -66,7 +64,6 @@ public Playable(String path, boolean finite, Playlist clipName) {

sound = clip;
this.path = path;
stopped = new AtomicBoolean(false);
this.finite = finite;
start = 0;
end = -1;
Expand Down Expand Up @@ -95,7 +92,6 @@ public Playable(String path, boolean finite, float decibels, Playlist clipName)

sound = clip;
this.path = path;
stopped = new AtomicBoolean(false);
this.finite = finite;
start = 0;
end = -1;
Expand Down Expand Up @@ -124,7 +120,6 @@ public Playable(String path, int start, int end, Playlist clipName) {

sound = clip;
this.path = path;
stopped = new AtomicBoolean(false);
this.finite = false;
this.start = start;
this.end = end;
Expand Down Expand Up @@ -154,20 +149,13 @@ public Playable(String path, int start, int end, float decibels, Playlist clipNa

sound = clip;
this.path = path;
stopped = new AtomicBoolean(false);
this.finite = false;
this.start = start;
this.end = end;
this.decibels = decibels;
this.clipName = clipName;
}

/**
* @return True if the clip is stopped. False if not. */
public boolean isStopped() {
return stopped.get();
}

/**
* @param decibels - the number of decibels to deduct from the volume. */
public void reduceVolume(float decibels) {
Expand All @@ -177,13 +165,7 @@ public void reduceVolume(float decibels) {
}

}

/**
* Stops the playback of the sound. */
public void stop() {
stopped.compareAndSet(false, true);
}


/**
* @param milliseconds - the time (in milliseconds) to sleep. */
private void sleep(int milliseconds) {
Expand All @@ -195,12 +177,15 @@ private void sleep(int milliseconds) {
}

}

/**
* The method which plays the selected sound. */
@Override
public void run() {
public void run() {
AudioInputStream audioStream;
/* Stores the length of the audio clip and waits until it ends, so
it can be closed properly */
long microsecondsLength;
//InputStream inputStream;

if (sound == null) {
Expand All @@ -215,6 +200,9 @@ public void run() {
//audioStream = AudioSystem.getAudioInputStream(inputStream);
sound.open(audioStream);
sound.setLoopPoints(start, end);

/* Gets the length of the clip */
microsecondsLength = sound.getMicrosecondLength();

if (decibels > 0) {
if(sound.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
Expand All @@ -226,29 +214,16 @@ public void run() {

if (finite) {
sound.start();

do {
sleep(100);
} while (sound.isRunning() && !stopped.get());

if (stopped.get()) {
sound.stop();
}


/* Converts the microseconds into milliseconds and sleeps that
amount of time */
sleep((int) (microsecondsLength / 100));
/* Closes the clip and notifies the Jukebox */
end();

} else {
sound.loop(Clip.LOOP_CONTINUOUSLY);

do {
sleep(100);
} while (!stopped.get());

sound.stop();
}

sound.close();

/* Notifies the player that this clip finished its reproduction */
MainClass.JUKEBOX.clipEnded(this);

} catch (IOException exception) {
System.out.println("The music clip couldn't be imported. See:");
Expand All @@ -260,7 +235,36 @@ public void run() {
System.out.println("The music clip format is not supported. See:");
System.out.println(exception.getMessage());
}

}

/**
* Ends the playback of the sound and notifies the JUKEBOX to remove this
* playable from its list.
*/
public void end() {

sound.stop();
sound.close();
/* Notifies that this clip finished its reproduction */
MainClass.JUKEBOX.clipEnded(this);
}

/**
* Stops the sound being played.
*/
public synchronized void stopPlaying () {

/* Stops the clip's reproduction */
sound.stop();
}

/**
* Continues the reproduction of the clip.
*/
public synchronized void restartClip () {

/* Restarts the clip's reproduction */
sound.start();
}

/**
Expand Down

0 comments on commit 38a5e49

Please sign in to comment.