Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/src/main/cpp/AudioBeacon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ PositionedAudio::PositionedAudio(AudioEngine *engine,
m_Eof(false),
m_Dimmable(dimmable)
{
static std::atomic<uint64_t> s_nextHandle{1};
m_Handle = s_nextHandle.fetch_add(1);
m_pEngine = engine;
m_UtteranceId = std::move(utterance_id);
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/AudioBeacon.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <atomic>
#include <utility>

#include "AudioBeaconBuffer.h"
Expand Down Expand Up @@ -47,6 +48,7 @@ namespace soundscape {

AudioEngine *m_pEngine;
std::string m_UtteranceId;
uint64_t m_Handle;

protected:
void Init(double degrees_off_axis,
Expand Down
40 changes: 35 additions & 5 deletions app/src/main/cpp/AudioEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,17 @@ const BeaconDescriptor AudioEngine::msc_BeaconDescriptors[] =
return m_QueuedBeacons.size();
}

bool AudioEngine::IsHandleActive(uint64_t handle) {
std::lock_guard<std::recursive_mutex> guard(m_BeaconsMutex);
for (const auto &queued : m_QueuedBeacons) {
if (queued->m_Handle == handle) return true;
}
for (const auto &beacon : m_Beacons) {
if (beacon->m_Handle == handle) return true;
}
return false;
}

void AudioEngine::UpdateAudioConfig(std::string &utterance_id,
int sample_rate,
int audio_format,
Expand All @@ -399,7 +410,7 @@ const BeaconDescriptor AudioEngine::msc_BeaconDescriptors[] =
}
}

void AudioEngine::AddBeacon(PositionedAudio *beacon, bool queued)
uint64_t AudioEngine::AddBeacon(PositionedAudio *beacon, bool queued)
{
std::lock_guard<std::recursive_mutex> guard(m_BeaconsMutex);
if(queued)
Expand All @@ -418,6 +429,7 @@ const BeaconDescriptor AudioEngine::msc_BeaconDescriptors[] =
m_Beacons.insert(beacon);
TRACE("AddBeacon -> %zu beacons", m_Beacons.size());
}
return beacon->m_Handle;
}

void AudioEngine::RemoveBeacon(PositionedAudio *beacon)
Expand Down Expand Up @@ -586,6 +598,20 @@ Java_org_scottishtecharmy_soundscape_audio_NativeAudioEngine_getQueueDepth(JNIEn
}
return 0L;
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_org_scottishtecharmy_soundscape_audio_NativeAudioEngine_isHandleActive(JNIEnv *env MAYBE_UNUSED,
jobject thiz MAYBE_UNUSED,
jlong engine_handle,
jlong handle) {
auto* ae = reinterpret_cast<soundscape::AudioEngine*>(engine_handle);
if(ae) {
return ae->IsHandleActive(static_cast<uint64_t>(handle)) ? JNI_TRUE : JNI_FALSE;
}
return JNI_FALSE;
}

extern "C"
JNIEXPORT void JNICALL
Java_org_scottishtecharmy_soundscape_audio_NativeAudioEngine_destroyNativeBeacon(JNIEnv *env MAYBE_UNUSED,
Expand Down Expand Up @@ -643,9 +669,11 @@ Java_org_scottishtecharmy_soundscape_audio_NativeAudioEngine_createNativeTextToS
if (not tts) {
TRACE("Failed to create text to speech");
tts.reset(nullptr);
return 0L;
}
auto ret = reinterpret_cast<jlong>(tts.release());
return ret;
auto handle = tts->m_Handle;
tts.release();
return static_cast<jlong>(handle);
}
return 0L;
}
Expand Down Expand Up @@ -692,9 +720,11 @@ Java_org_scottishtecharmy_soundscape_audio_NativeAudioEngine_createNativeEarcon(
if (not earcon) {
TRACE("Failed to create Earcon");
earcon.reset(nullptr);
return 0L;
}
auto ret = reinterpret_cast<jlong>(earcon.release());
return ret;
auto handle = earcon->m_Handle;
earcon.release();
return static_cast<jlong>(handle);
}
return 0L;
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/AudioEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace soundscape {
void SetBeaconType(int beaconType);
const BeaconDescriptor *GetBeaconDescriptor() const;

void AddBeacon(PositionedAudio *beacon, bool queued = false);
uint64_t AddBeacon(PositionedAudio *beacon, bool queued = false);
void RemoveBeacon(PositionedAudio *beacon);
bool ToggleBeaconMute();

Expand All @@ -91,6 +91,7 @@ namespace soundscape {

void ClearQueue();
unsigned int GetQueueDepth();
bool IsHandleActive(uint64_t handle);

void SetUseHrtf(bool use) { if (m_pMixer) m_pMixer->setUseHrtf(use); }
void SetSuppressRestart(bool suppress) { if (m_pMixer) m_pMixer->setSuppressRestart(suppress); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface AudioEngine {
fun createEarcon(asset: String, type: AudioType, latitude: Double = Double.NaN, longitude: Double = Double.NaN, heading: Double = Double.NaN) : Long
fun clearTextToSpeechQueue()
fun getQueueDepth() : Long
fun isHandleActive(handle: Long) : Boolean
fun updateGeometry(listenerLatitude: Double, listenerLongitude: Double, listenerHeading: Double?, focusGained: Boolean, duckingAllowed: Boolean, proximityNear: Double)
fun setBeaconType(beaconType: String)
fun getListOfBeaconTypes() : Array<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class NativeAudioEngine @Inject constructor(val service: SoundscapeService? = nu
private external fun createNativeEarcon(engineHandle: Long, asset:String, mode: Int, latitude: Double, longitude: Double, heading: Double) : Long
private external fun clearNativeTextToSpeechQueue(engineHandle: Long)
private external fun getQueueDepth(engineHandle: Long) : Long
private external fun isHandleActive(engineHandle: Long, handle: Long) : Boolean
private external fun updateGeometry(engineHandle: Long, latitude: Double, longitude: Double, heading: Double, focusGained: Boolean, duckingAllowed: Boolean, proximityNear: Double)
private external fun setBeaconType(engineHandle: Long, beaconType: String)
private external fun getListOfBeacons() : Array<String>
Expand Down Expand Up @@ -338,6 +339,15 @@ class NativeAudioEngine @Inject constructor(val service: SoundscapeService? = nu
return 0
}

override fun isHandleActive(handle: Long) : Boolean {
synchronized(engineMutex) {
if (engineHandle != 0L) {
return isHandleActive(engineHandle, handle)
}
}
return false
}

override fun getAvailableSpeechEngines() : List<TextToSpeech.EngineInfo> {
return ttsEngine.getAvailableEngines()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,8 +848,15 @@ class GeoEngine {
val gridFinishTime = timeSource.markNow()
Log.e(GridState.TAG, "Time to calculate NearbyMarkers: ${gridFinishTime - gridStartTime}")

if(results.isEmpty())
return null
if(results.isEmpty()) {
results.add(
PositionedString(
text = localizedContext.getString(R.string.callouts_no_nearby_markers),
type = AudioType.STANDARD
)
)
}


return TrackedCallout(
userGeometry = userGeometry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class RoutePlayer(val service: SoundscapeService, context: Context) {
if ((currentMarker + 1) < route.markers.size) {
// We're within 12m of the marker, move on to the next one
Log.d(TAG, "Moving to next waypoint ${coroutineContext[Job]}")
moveToNext()
moveToNext(false)
} else {
// We've reached the end of the route
// Announce the end of the route
Expand All @@ -179,7 +179,7 @@ class RoutePlayer(val service: SoundscapeService, context: Context) {
}
}

private fun createBeaconAtWaypoint(index: Int) {
private fun createBeaconAtWaypoint(index: Int, userInitiated: Boolean) {
currentRouteData?.let { route ->
if (index < route.markers.size) {
val location = route.markers[index].getLngLatAlt()
Expand All @@ -206,7 +206,7 @@ class RoutePlayer(val service: SoundscapeService, context: Context) {
route.markers[index].name,
formatDistanceAndDirection(distance, null, localizedContext))
}

if(userInitiated) service.audioEngine.clearTextToSpeechQueue()
service.speakText(
beaconSetText,
AudioType.LOCALIZED, location.latitude, location.longitude, 0.0
Expand All @@ -229,18 +229,18 @@ class RoutePlayer(val service: SoundscapeService, context: Context) {
}

fun play() {
createBeaconAtWaypoint(currentMarker)
createBeaconAtWaypoint(currentMarker, true)
Log.d(TAG, toString())
}

fun moveToNext() : Boolean {
fun moveToNext(userInitiated: Boolean) : Boolean {
currentRouteData?.let { route ->
if(route.markers.size > 1) {
if ((currentMarker + 1) < route.markers.size) {
currentMarker++
_currentRouteFlow.update { it.copy(currentWaypoint = currentMarker) }

createBeaconAtWaypoint(currentMarker)
createBeaconAtWaypoint(currentMarker, userInitiated)
}
return true
}
Expand All @@ -249,13 +249,13 @@ class RoutePlayer(val service: SoundscapeService, context: Context) {
return false
}

fun moveToPrevious() : Boolean{
fun moveToPrevious(userInitiated: Boolean) : Boolean{
currentRouteData?.let { route ->
if(route.markers.size > 1) {
if (currentMarker > 0) {
currentMarker--
_currentRouteFlow.update { it.copy(currentWaypoint = currentMarker) }
createBeaconAtWaypoint(currentMarker)
createBeaconAtWaypoint(currentMarker, userInitiated)
return true
}
}
Expand Down
Loading