1515import org .phoebus .applications .alarm .ui .annunciator .AnnunciatorMessage ;
1616
1717import java .util .List ;
18+ import java .util .logging .Level ;
19+ import java .util .logging .Logger ;
1820
1921/**
2022 * Annunciator class. Uses Audio files to annunciate passed messages.
2325 */
2426@ SuppressWarnings ("nls" )
2527public class AudioAnnunciator implements Annunciator {
28+ private static final Logger logger = Logger .getLogger (AudioAnnunciator .class .getName ());
2629 private final MediaPlayer alarmSound ;
2730 private final MediaPlayer minorAlarmSound ;
2831 private final MediaPlayer majorAlarmSound ;
@@ -33,26 +36,63 @@ public class AudioAnnunciator implements Annunciator {
3336 * Constructor
3437 */
3538 public AudioAnnunciator () {
36- alarmSound = new MediaPlayer ( new Media ( Preferences .alarm_sound_url ) );
37- minorAlarmSound = new MediaPlayer ( new Media ( Preferences .minor_alarm_sound_url ) );
38- majorAlarmSound = new MediaPlayer ( new Media ( Preferences .major_alarm_sound_url ) );
39- invalidAlarmSound = new MediaPlayer ( new Media ( Preferences .invalid_alarm_sound_url ) );
40- undefinedAlarmSound = new MediaPlayer ( new Media ( Preferences .undefined_alarm_sound_url ) );
39+ alarmSound = createMediaPlayer ( Preferences .alarm_sound_url );
40+ minorAlarmSound = createMediaPlayer ( Preferences .minor_alarm_sound_url );
41+ majorAlarmSound = createMediaPlayer ( Preferences .major_alarm_sound_url );
42+ invalidAlarmSound = createMediaPlayer ( Preferences .invalid_alarm_sound_url );
43+ undefinedAlarmSound = createMediaPlayer ( Preferences .undefined_alarm_sound_url );
4144 // configure the media players for the different alarm sounds
4245 List .of (alarmSound , minorAlarmSound , majorAlarmSound , invalidAlarmSound , undefinedAlarmSound )
4346 .forEach (sound -> {
44- sound .setStopTime (Duration .seconds (Preferences .max_alarm_duration ));
45- sound .setVolume (Preferences .volume );
47+ if (sound != null ) {
48+ sound .setStopTime (Duration .seconds (Preferences .max_alarm_duration ));
49+ sound .setVolume (Preferences .volume );
50+ }
4651 });
4752 }
4853
54+ /**
55+ * Create a MediaPlayer for the given URL
56+ *
57+ * @param url URL of the audio file
58+ * @return MediaPlayer
59+ */
60+ private MediaPlayer createMediaPlayer (String url ) {
61+ try {
62+ MediaPlayer player = new MediaPlayer (new Media (url ));
63+ if (player .getError () == null ) {
64+ player .setOnError (() -> logger .log (Level .SEVERE , "Error playing alarm sound: " + url , player .getError ()));
65+ player .setOnPlaying (() -> logger .log (Level .FINE , "Playing alarm sound: " + url ));
66+ player .setOnStopped (() -> logger .log (Level .FINE , "Alarm sound stopped: " + url ));
67+ player .setOnEndOfMedia (() -> logger .log (Level .FINE , "Alarm sound finished: " + url ));
68+ return player ;
69+ }
70+ else {
71+ logger .log (Level .SEVERE , "Error creating MediaPlayer for URL: " + url , player .getError ());
72+ return null ;
73+ }
74+ } catch (Exception e ) {
75+ logger .log (Level .SEVERE , "Failed to create MediaPlayer for URL: " + url , e );
76+ return null ;
77+ }
78+ }
79+
4980 /**
5081 * Annunciate the message.
5182 *
5283 * @param message Message text
5384 */
5485 @ Override
5586 public void speak (final AnnunciatorMessage message ) {
87+ if (message == null ) {
88+ logger .log (Level .WARNING , "Received null AnnunciatorMessage" );
89+ return ;
90+ }
91+ if (message .severity == null ) {
92+ logger .log (Level .WARNING , "Received AnnunciatorMessage with null severity. Playing default alarm sound" );
93+ speakAlone (alarmSound ); // Play the default alarm sound
94+ return ;
95+ }
5696 switch (message .severity ) {
5797 case MINOR -> speakAlone (minorAlarmSound );
5898 case MAJOR -> speakAlone (majorAlarmSound );
@@ -62,12 +102,27 @@ public void speak(final AnnunciatorMessage message) {
62102 }
63103 }
64104
105+ /**
106+ * Play the alarm sound alone by first stopping any alarm sounds.
107+ *
108+ * @param alarm Alarm sound
109+ */
65110 synchronized private void speakAlone (MediaPlayer alarm ) {
111+ if (alarm == null ) {
112+ logger .log (Level .WARNING , "Alarm sound is null, cannot play sound" );
113+ return ;
114+ }
66115 List .of (alarmSound , minorAlarmSound , majorAlarmSound , invalidAlarmSound , undefinedAlarmSound )
67116 .forEach (sound -> {
68- sound .stop ();
117+ if (sound != null ) {
118+ sound .stop ();
119+ }
69120 });
70- alarm .play ();
121+ try {
122+ alarm .play ();
123+ } catch (Exception e ) {
124+ logger .log (Level .SEVERE , "Failed to play alarm sound" , e );
125+ }
71126 }
72127
73128 /**
@@ -77,8 +132,14 @@ synchronized private void speakAlone(MediaPlayer alarm) {
77132 public void shutdown () {
78133 List .of (alarmSound , minorAlarmSound , majorAlarmSound , invalidAlarmSound , undefinedAlarmSound )
79134 .forEach (sound -> {
80- sound .stop ();
81- sound .dispose ();
135+ if (sound != null ) {
136+ try {
137+ sound .stop ();
138+ sound .dispose ();
139+ } catch (Exception e ) {
140+ logger .log (Level .WARNING , "Failed to stop and dispose alarm sound" , e );
141+ }
142+ }
82143 });
83144 }
84145}
0 commit comments