2323
2424package com .iluwatar .event .queue ;
2525
26+ import org .slf4j .Logger ;
27+ import org .slf4j .LoggerFactory ;
28+
2629import java .io .File ;
2730import java .io .IOException ;
2831
3841 *
3942 */
4043public class Audio {
44+ private static final Logger LOGGER = LoggerFactory .getLogger (Audio .class );
45+ private static final Audio INSTANCE = new Audio ();
4146
4247 private static final int MAX_PENDING = 16 ;
4348
44- private static int headIndex ;
49+ private int headIndex ;
50+
51+ private int tailIndex ;
4552
46- private static int tailIndex ;
53+ private volatile Thread updateThread = null ;
4754
48- private static Thread updateThread = null ;
55+ private PlayMessage [] pendingAudio = new PlayMessage [ MAX_PENDING ] ;
4956
50- private static PlayMessage [] pendingAudio = new PlayMessage [MAX_PENDING ];
57+ // Visible only for testing purposes
58+ Audio () {
59+
60+ }
61+
62+ public static Audio getInstance () {
63+ return INSTANCE ;
64+ }
5165
5266 /**
53- * This method stops the Update Method's thread.
67+ * This method stops the Update Method's thread and waits till service stops.
5468 */
55- public static synchronized void stopService () {
69+ public synchronized void stopService () throws InterruptedException {
5670 if (updateThread != null ) {
5771 updateThread .interrupt ();
5872 }
73+ updateThread .join ();
74+ updateThread = null ;
5975 }
6076
6177 /**
6278 * This method check the Update Method's thread is started.
6379 * @return boolean
6480 */
65- public static synchronized boolean isServiceRunning () {
66- if (updateThread != null && updateThread .isAlive () ) {
67- return true ;
68- } else {
69- return false ;
70- }
81+ public synchronized boolean isServiceRunning () {
82+ return updateThread != null && updateThread .isAlive ();
7183 }
7284
7385 /**
7486 * Starts the thread for the Update Method pattern if it was not started previously.
7587 * Also when the thread is is ready initializes the indexes of the queue
7688 */
77- public static void init () {
89+ public void init () {
7890 if (updateThread == null ) {
79- updateThread = new Thread (new Runnable () {
80- public void run () {
81- while (!Thread .currentThread ().isInterrupted ()) {
82- Audio .update ();
83- }
91+ updateThread = new Thread (() -> {
92+ while (!Thread .currentThread ().isInterrupted ()) {
93+ update ();
8494 }
8595 });
8696 }
@@ -90,7 +100,7 @@ public void run() {
90100 /**
91101 * This is a synchronized thread starter
92102 */
93- public static synchronized void startThread () {
103+ private synchronized void startThread () {
94104 if (!updateThread .isAlive ()) {
95105 updateThread .start ();
96106 headIndex = 0 ;
@@ -103,7 +113,7 @@ public static synchronized void startThread() {
103113 * @param stream is the AudioInputStream for the method
104114 * @param volume is the level of the audio's volume
105115 */
106- public static void playSound (AudioInputStream stream , float volume ) {
116+ public void playSound (AudioInputStream stream , float volume ) {
107117 init ();
108118 // Walk the pending requests.
109119 for (int i = headIndex ; i != tailIndex ; i = (i + 1 ) % MAX_PENDING ) {
@@ -123,7 +133,7 @@ public static void playSound(AudioInputStream stream, float volume) {
123133 * This method uses the Update Method pattern.
124134 * It takes the audio from the queue and plays it
125135 */
126- public static void update () {
136+ private void update () {
127137 // If there are no pending requests, do nothing.
128138 if (headIndex == tailIndex ) {
129139 return ;
@@ -136,13 +146,11 @@ public static void update() {
136146 clip .open (audioStream );
137147 clip .start ();
138148 } catch (LineUnavailableException e ) {
139- System .err .println ("Error occoured while loading the audio: The line is unavailable" );
140- e .printStackTrace ();
149+ LOGGER .trace ("Error occoured while loading the audio: The line is unavailable" , e );
141150 } catch (IOException e ) {
142- System .err .println ("Input/Output error while loading the audio" );
143- e .printStackTrace ();
151+ LOGGER .trace ("Input/Output error while loading the audio" , e );
144152 } catch (IllegalArgumentException e ) {
145- System . err . println ("The system doesn't support the sound: " + e .getMessage ());
153+ LOGGER . trace ("The system doesn't support the sound: " + e .getMessage (), e );
146154 }
147155 }
148156
@@ -153,7 +161,7 @@ public static void update() {
153161 * @throws UnsupportedAudioFileException when the audio file is not supported
154162 * @throws IOException when the file is not readable
155163 */
156- public static AudioInputStream getAudioStream (String filePath )
164+ public AudioInputStream getAudioStream (String filePath )
157165 throws UnsupportedAudioFileException , IOException {
158166 return AudioSystem .getAudioInputStream (new File (filePath ).getAbsoluteFile ());
159167 }
@@ -162,7 +170,7 @@ public static AudioInputStream getAudioStream(String filePath)
162170 * Returns with the message array of the queue
163171 * @return PlayMessage[]
164172 */
165- public static PlayMessage [] getPendingAudio () {
173+ public PlayMessage [] getPendingAudio () {
166174 return pendingAudio ;
167175 }
168176
0 commit comments