From fa02ba9c6965f055837aed513ea5f861aea3d024 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 26 Aug 2021 22:50:38 +0200 Subject: [PATCH] Voice announcements: if TTS is not available play a sound file. Fixes #862. --- .../opentracks/AbstractActivity.java | 5 +-- .../services/TrackRecordingService.java | 5 ++- .../services/tasks/VoiceAnnouncement.java | 42 ++++++++++++------ .../tasks/VoiceAnnouncementManager.java | 31 +++++++++---- .../opentracks/settings/SettingsActivity.java | 33 -------------- .../dennisguse/opentracks/util/TTSUtils.java | 13 ------ src/main/res/raw/tts_fallback.mp3 | Bin 0 -> 65954 bytes 7 files changed, 57 insertions(+), 72 deletions(-) delete mode 100644 src/main/java/de/dennisguse/opentracks/util/TTSUtils.java create mode 100644 src/main/res/raw/tts_fallback.mp3 diff --git a/src/main/java/de/dennisguse/opentracks/AbstractActivity.java b/src/main/java/de/dennisguse/opentracks/AbstractActivity.java index 33ec9310f..1f264bd79 100644 --- a/src/main/java/de/dennisguse/opentracks/AbstractActivity.java +++ b/src/main/java/de/dennisguse/opentracks/AbstractActivity.java @@ -22,8 +22,7 @@ import android.view.View; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; - -import de.dennisguse.opentracks.util.TTSUtils; +import de.dennisguse.opentracks.services.tasks.VoiceAnnouncement; /** * @author Jimmy Shih @@ -35,7 +34,7 @@ public abstract class AbstractActivity extends AppCompatActivity { super.onCreate(savedInstanceState); // Set volume control stream for text to speech - setVolumeControlStream(TTSUtils.getTTSStream()); + setVolumeControlStream(VoiceAnnouncement.AUDIO_STREAM); setContentView(getRootView()); diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index cdefbef8b..8d93da21b 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -431,7 +431,8 @@ public class TrackRecordingService extends Service implements TrackPointCreator. // Compute temporary track statistics using sensorData and update time. TrackPointCreator localHandlerServer = this.handlerServer; - if (localHandlerServer == null) { + VoiceAnnouncementManager localVoiceAnnouncementManager = this.voiceAnnouncementManager; + if (localHandlerServer == null || localVoiceAnnouncementManager == null) { // when this happens, no recording is running and we should not send any notifications. //TODO This implementation is not a good idea; rather solve the issue for this properly return; @@ -445,7 +446,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. TrackPoint trackPoint = data.second.first; egm2008CorrectionManager.correctAltitude(this, trackPoint); - voiceAnnouncementManager.update(data.first); + localVoiceAnnouncementManager.update(data.first); recordingDataObservable.postValue(new RecordingData(data.first, trackPoint, data.second.second)); } diff --git a/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncement.java b/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncement.java index c1aee351d..01d9130b8 100644 --- a/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncement.java +++ b/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncement.java @@ -19,6 +19,7 @@ package de.dennisguse.opentracks.services.tasks; import android.content.Context; import android.content.SharedPreferences; import android.media.AudioManager; +import android.media.MediaPlayer; import android.speech.tts.TextToSpeech; import android.speech.tts.UtteranceProgressListener; import android.util.Log; @@ -28,6 +29,7 @@ import androidx.annotation.NonNull; import java.util.Arrays; import java.util.Locale; +import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; @@ -44,6 +46,8 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatistics; */ public class VoiceAnnouncement { + public final static int AUDIO_STREAM = TextToSpeech.Engine.DEFAULT_STREAM; + private static final String TAG = VoiceAnnouncement.class.getSimpleName(); private final Context context; @@ -79,7 +83,7 @@ public class VoiceAnnouncement { private final UtteranceProgressListener utteranceListener = new UtteranceProgressListener() { @Override public void onStart(String utteranceId) { - int result = audioManager.requestAudioFocus(audioFocusChangeListener, TextToSpeech.Engine.DEFAULT_STREAM, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); + int result = audioManager.requestAudioFocus(audioFocusChangeListener, AUDIO_STREAM, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { Log.w(TAG, "Failed to request audio focus."); } @@ -107,11 +111,12 @@ public class VoiceAnnouncement { private boolean ttsReady = false; + private MediaPlayer ttsFallback; + VoiceAnnouncement(Context context) { this.context = context; audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); contentProviderUtils = new ContentProviderUtils(context); - } public void start() { @@ -125,6 +130,11 @@ public class VoiceAnnouncement { ttsInitStatus = status; }); } + if (ttsFallback == null) { + ttsFallback = MediaPlayer.create(context, R.raw.tts_fallback); + ttsFallback.setAudioStreamType(AUDIO_STREAM); + ttsFallback.setLooping(false); + } } public void announce(@NonNull Track track) { @@ -135,18 +145,22 @@ public class VoiceAnnouncement { onTtsReady(); } } - if (!ttsReady) { - Log.i(TAG, "TTS not ready."); - return; - } } if (Arrays.asList(AudioManager.MODE_IN_CALL, AudioManager.MODE_IN_COMMUNICATION) .contains(audioManager.getMode())) { - Log.i(TAG, "Speech is not allowed at this time."); + Log.i(TAG, "Announcement is not allowed at this time."); return; } + if (!ttsReady) { + Log.i(TAG, "TTS not ready/available, just generating a tone."); + ttsFallback.seekTo(0); + ttsFallback.start(); + return; + } + + boolean isMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context); boolean isReportSpeed = PreferencesUtils.isReportSpeed(sharedPreferences, context, track.getCategory()); Distance minGPSDistance = PreferencesUtils.getRecordingDistanceInterval(sharedPreferences, context); @@ -158,7 +172,9 @@ public class VoiceAnnouncement { IntervalStatistics.Interval lastInterval = intervalStatistics.getLastInterval(); String announcement = AnnouncementUtils.getAnnouncement(context, track.getTrackStatistics(), isMetricUnits, isReportSpeed, lastInterval); - speakAnnouncement(announcement); + + // We don't care about the utterance id. It is supplied here to force onUtteranceCompleted to be called. + tts.speak(announcement, TextToSpeech.QUEUE_FLUSH, null, "not used"); } public void shutdown() { @@ -167,6 +183,11 @@ public class VoiceAnnouncement { tts = null; } + if (ttsFallback != null) { + ttsFallback.release(); + ttsFallback = null; + } + sharedPreferences = null; } @@ -185,9 +206,4 @@ public class VoiceAnnouncement { tts.setSpeechRate(PreferencesUtils.getVoiceSpeedRate(PreferencesUtils.getSharedPreferences(context), context)); tts.setOnUtteranceProgressListener(utteranceListener); } - - private void speakAnnouncement(String announcement) { - // We don't care about the utterance id. It is supplied here to force onUtteranceCompleted to be called. - tts.speak(announcement, TextToSpeech.QUEUE_FLUSH, null, "not used"); - } } diff --git a/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncementManager.java index 3be013d0c..64e90ed30 100644 --- a/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/tasks/VoiceAnnouncementManager.java @@ -18,6 +18,7 @@ package de.dennisguse.opentracks.services.tasks; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import java.time.Duration; @@ -53,8 +54,12 @@ public class VoiceAnnouncementManager { private boolean metricUnits; private TrackStatistics trackStatistics; - private Distance nextTotalDistance = Distance.of(Double.MAX_VALUE); - private Duration nextTotalTime = Duration.ofSeconds(Long.MAX_VALUE); + + private static final Distance DISTANCE_OFF = Distance.of(Double.MAX_VALUE); + private Distance nextTotalDistance = DISTANCE_OFF; + + private static final Duration TOTALTIME_OFF = Duration.ofMillis(Long.MAX_VALUE); + private Duration nextTotalTime = TOTALTIME_OFF; public VoiceAnnouncementManager(@NonNull TrackRecordingService trackRecordingService) { this.trackRecordingService = trackRecordingService; @@ -63,7 +68,7 @@ public class VoiceAnnouncementManager { taskFrequency = TASK_FREQUENCY_OFF; } - public void restore(TrackStatistics trackStatistics) { + public void restore(@Nullable TrackStatistics trackStatistics) { if (taskFrequency == TASK_FREQUENCY_OFF) { Log.d(TAG, "Task frequency is off."); return; @@ -73,7 +78,7 @@ public class VoiceAnnouncementManager { voiceAnnouncement.start(); if (isTimeFrequency()) { - nextTotalTime = calculateNextDuration(trackStatistics); + nextTotalTime = trackStatistics != null ? calculateNextDuration(trackStatistics) : TOTALTIME_OFF; } else { // For distance periodic task updateNextTaskDistance(trackStatistics); @@ -81,6 +86,10 @@ public class VoiceAnnouncementManager { } public void update(@NonNull Track track) { + if (voiceAnnouncement == null) { + Log.e(TAG, "Cannot update when in status shutdown."); + return; + } boolean announce = false; this.trackStatistics = track.getTrackStatistics(); if (trackStatistics.getTotalDistance().greaterThan(nextTotalDistance)) { @@ -93,7 +102,6 @@ public class VoiceAnnouncementManager { } if (announce) { - this.trackStatistics = track.getTrackStatistics(); voiceAnnouncement.announce(track); } } @@ -117,7 +125,7 @@ public class VoiceAnnouncementManager { private void updateNextTaskDistance(TrackStatistics trackStatistics) { if (!isDistanceFrequency()) { - nextTotalDistance = Distance.of(Double.MAX_VALUE); + nextTotalDistance = DISTANCE_OFF; Log.d(TAG, "SplitManager: Distance splits disabled."); return; } @@ -138,12 +146,19 @@ public class VoiceAnnouncementManager { return announcementInterval.multipliedBy(index + 1); } - private Duration calculateNextDuration(@NonNull TrackStatistics trackStatistics) { + private Duration calculateNextDuration(@Nullable TrackStatistics trackStatistics) { + if (trackStatistics == null) { + return null; + } + if (!isTimeFrequency()) { throw new RuntimeException("Using distance frequency as time frequency is impossible."); } + Duration totalTime = trackStatistics.getTotalTime(); Duration interval = Duration.ofMinutes(taskFrequency); - return interval.minus(Duration.ofMillis(trackStatistics.getTotalTime().toMillis() % interval.toMillis())); + Duration intervalMod = Duration.ofMillis(trackStatistics.getTotalTime().toMillis() % interval.toMillis()); + + return totalTime.plus(interval.minus(intervalMod)); } private boolean isTimeFrequency() { diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java index 99c835205..df4311c88 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java +++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java @@ -98,9 +98,6 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity public static class PrefsFragment extends PreferenceFragmentCompat { - private TextToSpeech tts; - private int ttsInitStatus; - private SharedPreferences sharedPreferences; private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> { @@ -133,23 +130,6 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity // Used to forward update from ChooseActivityTypeDialogFragment; TODO Could be replaced with LiveData. private ActivityTypePreference.ActivityPreferenceDialog activityPreferenceDialog; - private Preference announcementsFrequency; - private Preference announcementsSpeed; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - ttsInitStatus = TextToSpeech.ERROR; - tts = new TextToSpeech(getContext(), status -> { - ttsInitStatus = status; - Log.i(TAG, "TextToSpeech initialized with status " + status); - - if (announcementsFrequency != null && announcementsSpeed != null) { - updateVoiceAnnouncements(); - } - }); - } - @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { sharedPreferences = PreferencesUtils.getSharedPreferences(getContext()); @@ -214,10 +194,6 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity startActivity(intent); return true; }); - - announcementsFrequency = findPreference(getString(R.string.voice_frequency_key)); - announcementsSpeed = findPreference(getString(R.string.voice_speed_rate_key)); - updateVoiceAnnouncements(); } @Override @@ -278,9 +254,6 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity super.onDestroy(); trackRecordingServiceConnection.unbind(getContext()); sharedPreferences = null; - announcementsFrequency = null; - announcementsSpeed = null; - tts = null; } public void setDefaultActivity(String iconValue) { @@ -374,12 +347,6 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity }); } - private void updateVoiceAnnouncements() { - boolean enabled = ttsInitStatus == TextToSpeech.SUCCESS; - announcementsFrequency.setEnabled(enabled); - announcementsSpeed.setEnabled(enabled); - } - private void onRecordingStatusChanged(TrackRecordingService.RecordingStatus status) { this.recordingStatus = status; if (!status.isRecording() && isAdded()) { diff --git a/src/main/java/de/dennisguse/opentracks/util/TTSUtils.java b/src/main/java/de/dennisguse/opentracks/util/TTSUtils.java deleted file mode 100644 index deb95b3e8..000000000 --- a/src/main/java/de/dennisguse/opentracks/util/TTSUtils.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.dennisguse.opentracks.util; - -import android.speech.tts.TextToSpeech; - -public class TTSUtils { - - private TTSUtils() { - } - - public static int getTTSStream() { - return TextToSpeech.Engine.DEFAULT_STREAM; - } -} diff --git a/src/main/res/raw/tts_fallback.mp3 b/src/main/res/raw/tts_fallback.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6a2f78c0070401bfa53865516f1692613742be3f GIT binary patch literal 65954 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 literal 0 HcmV?d00001