@@ -41,46 +41,51 @@ public class Audio {
4141
4242 private static final int MAX_PENDING = 16 ;
4343
44- private static int headIndex ;
44+ private int headIndex ;
4545
46- private static int tailIndex ;
46+ private int tailIndex ;
4747
48- private static Thread updateThread = null ;
48+ private volatile Thread updateThread = null ;
4949
50- private static PlayMessage [] pendingAudio = new PlayMessage [MAX_PENDING ];
50+ private PlayMessage [] pendingAudio = new PlayMessage [MAX_PENDING ];
51+
52+ // Visible only for testing purposes
53+ Audio () {
54+
55+ }
56+
57+ public static Audio getInstance () {
58+ return SingletonHolder .getAudioInstance ();
59+ }
5160
5261 /**
53- * This method stops the Update Method's thread.
62+ * This method stops the Update Method's thread and waits till service stops.
5463 */
55- public static synchronized void stopService () {
64+ public synchronized void stopService () throws InterruptedException {
5665 if (updateThread != null ) {
5766 updateThread .interrupt ();
5867 }
68+ updateThread .join ();
69+ updateThread = null ;
5970 }
6071
6172 /**
6273 * This method check the Update Method's thread is started.
6374 * @return boolean
6475 */
65- public static synchronized boolean isServiceRunning () {
66- if (updateThread != null && updateThread .isAlive () ) {
67- return true ;
68- } else {
69- return false ;
70- }
76+ public synchronized boolean isServiceRunning () {
77+ return updateThread != null && updateThread .isAlive ();
7178 }
7279
7380 /**
7481 * Starts the thread for the Update Method pattern if it was not started previously.
7582 * Also when the thread is is ready initializes the indexes of the queue
7683 */
77- public static void init () {
84+ public void init () {
7885 if (updateThread == null ) {
79- updateThread = new Thread (new Runnable () {
80- public void run () {
81- while (!Thread .currentThread ().isInterrupted ()) {
82- Audio .update ();
83- }
86+ updateThread = new Thread (() -> {
87+ while (!Thread .currentThread ().isInterrupted ()) {
88+ update ();
8489 }
8590 });
8691 }
@@ -90,7 +95,7 @@ public void run() {
9095 /**
9196 * This is a synchronized thread starter
9297 */
93- public static synchronized void startThread () {
98+ private synchronized void startThread () {
9499 if (!updateThread .isAlive ()) {
95100 updateThread .start ();
96101 headIndex = 0 ;
@@ -103,7 +108,7 @@ public static synchronized void startThread() {
103108 * @param stream is the AudioInputStream for the method
104109 * @param volume is the level of the audio's volume
105110 */
106- public static void playSound (AudioInputStream stream , float volume ) {
111+ public void playSound (AudioInputStream stream , float volume ) {
107112 init ();
108113 // Walk the pending requests.
109114 for (int i = headIndex ; i != tailIndex ; i = (i + 1 ) % MAX_PENDING ) {
@@ -123,7 +128,7 @@ public static void playSound(AudioInputStream stream, float volume) {
123128 * This method uses the Update Method pattern.
124129 * It takes the audio from the queue and plays it
125130 */
126- public static void update () {
131+ private void update () {
127132 // If there are no pending requests, do nothing.
128133 if (headIndex == tailIndex ) {
129134 return ;
@@ -143,6 +148,7 @@ public static void update() {
143148 e .printStackTrace ();
144149 } catch (IllegalArgumentException e ) {
145150 System .err .println ("The system doesn't support the sound: " + e .getMessage ());
151+ e .printStackTrace ();
146152 }
147153 }
148154
@@ -153,7 +159,7 @@ public static void update() {
153159 * @throws UnsupportedAudioFileException when the audio file is not supported
154160 * @throws IOException when the file is not readable
155161 */
156- public static AudioInputStream getAudioStream (String filePath )
162+ public AudioInputStream getAudioStream (String filePath )
157163 throws UnsupportedAudioFileException , IOException {
158164 return AudioSystem .getAudioInputStream (new File (filePath ).getAbsoluteFile ());
159165 }
@@ -162,8 +168,15 @@ public static AudioInputStream getAudioStream(String filePath)
162168 * Returns with the message array of the queue
163169 * @return PlayMessage[]
164170 */
165- public static PlayMessage [] getPendingAudio () {
171+ public PlayMessage [] getPendingAudio () {
166172 return pendingAudio ;
167173 }
168174
175+ private static class SingletonHolder {
176+ private static final Audio INSTANCE = new Audio ();
177+
178+ static Audio getAudioInstance () {
179+ return INSTANCE ;
180+ }
181+ }
169182}
0 commit comments