• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • lib
  • marble
  • routing
VoiceNavigationModel.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2012 Dennis Nienhüser <earthwings@gentoo.org>
9 //
10 
11 #include "VoiceNavigationModel.h"
12 
13 #include "MarbleDirs.h"
14 #include "MarbleDebug.h"
15 
16 namespace Marble
17 {
18 
19 class VoiceNavigationModelPrivate
20 {
21 public:
22  VoiceNavigationModel* m_parent;
23 
24  QString m_speaker;
25 
26  bool m_speakerEnabled;
27 
28  PositionProviderStatus m_gpsStatus;
29 
30  QMap<Maneuver::Direction, QString> m_turnTypeMap;
31 
32  QMap<Maneuver::Direction, QString> m_announceMap;
33 
34  qreal m_lastDistance;
35 
36  Maneuver::Direction m_lastTurnType;
37 
38  GeoDataCoordinates m_lastTurnPoint;
39 
40  QStringList m_queue;
41 
42  bool m_destinationReached;
43 
44  bool m_deviated;
45 
46  VoiceNavigationModelPrivate( VoiceNavigationModel* parent );
47 
48  void reset();
49 
50  QString audioFile(const QString &name);
51 
52  QString distanceAudioFile( qreal dest );
53 
54  QString turnTypeAudioFile( Maneuver::Direction turnType, qreal distance );
55 
56  void updateInstruction( qreal distance, Maneuver::Direction turnType );
57 
58  void updateInstruction( const QString &name );
59 
60  void initializeMaps();
61 };
62 
63 VoiceNavigationModelPrivate::VoiceNavigationModelPrivate( VoiceNavigationModel* parent ) :
64  m_parent( parent ),
65  m_speakerEnabled( true ),
66  m_gpsStatus( PositionProviderStatusUnavailable ),
67  m_lastDistance( 0.0 ),
68  m_lastTurnType( Maneuver::Unknown ),
69  m_destinationReached( false ),
70  m_deviated( false )
71 {
72  initializeMaps();
73 }
74 
75 void VoiceNavigationModelPrivate::reset()
76 {
77  m_lastDistance = 0.0;
78 }
79 
80 QString VoiceNavigationModelPrivate::audioFile( const QString &name )
81 {
82  QStringList const formats = QStringList() << "ogg" << "mp3" << "wav";
83  if ( m_speakerEnabled ) {
84  QString const audioTemplate = "%1/%2.%3";
85  foreach( const QString &format, formats ) {
86  QString const result = audioTemplate.arg( m_speaker ).arg( name ).arg( format );
87  QFileInfo audioFile( result );
88  if ( audioFile.exists() ) {
89  return result;
90  }
91  }
92  }
93 
94  QString const audioTemplate = "audio/%1.%2";
95  foreach( const QString &format, formats ) {
96  QString const result = MarbleDirs::path( audioTemplate.arg( name ).arg( format ) );
97  if ( !result.isEmpty() ) {
98  return result;
99  }
100  }
101 
102  return QString();
103 }
104 
105 QString VoiceNavigationModelPrivate::distanceAudioFile( qreal dest )
106 {
107  if ( dest > 0.0 && dest < 900.0 ) {
108  qreal minDistance = 0.0;
109  int targetDistance = 0;
110  QVector<int> distances;
111  distances << 50 << 80 << 100 << 200 << 300 << 400 << 500 << 600 << 700 << 800;
112  foreach( int distance, distances ) {
113  QString file = audioFile( QString::number( distance ) );
114  qreal currentDistance = qAbs( distance - dest );
115  if ( !file.isEmpty() && ( minDistance == 0.0 || currentDistance < minDistance ) ) {
116  minDistance = currentDistance;
117  targetDistance = distance;
118  }
119  }
120 
121  if ( targetDistance > 0 ) {
122  return audioFile( QString::number( targetDistance ) );
123  }
124  }
125 
126  return QString();
127 }
128 
129 QString VoiceNavigationModelPrivate::turnTypeAudioFile( Maneuver::Direction turnType, qreal distance )
130 {
131  bool const announce = distance >= 75;
132  QMap<Maneuver::Direction, QString> const & map = announce ? m_announceMap : m_turnTypeMap;
133  if ( m_speakerEnabled && map.contains( turnType ) ) {
134  return audioFile( map[turnType] );
135  }
136 
137  return audioFile( announce ? "KDE-Sys-List-End" : "KDE-Sys-App-Positive" );
138 }
139 
140 void VoiceNavigationModelPrivate::updateInstruction( qreal distance, Maneuver::Direction turnType )
141 {
142  //QString distanceAudio = distanceAudioFile( distance );
143  QString turnTypeAudio = turnTypeAudioFile( turnType, distance );
144  if ( turnTypeAudio.isEmpty() ) {
145  mDebug() << "Missing audio file for turn type " << turnType << " and speaker " << m_speaker;
146  return;
147  }
148 
149  m_queue.clear();
150  m_queue << turnTypeAudio;
151  emit m_parent->instructionChanged();
152 // if ( !distanceAudio.isEmpty() ) {
153 // m_output->enqueue( audioFile( "After" ) );
154 // m_output->enqueue( distanceAudio );
155 // m_output->enqueue( audioFile( "Meters" ) );
156  // }
157 }
158 
159 void VoiceNavigationModelPrivate::updateInstruction( const QString &name )
160 {
161  m_queue.clear();
162  m_queue << audioFile( name );
163  emit m_parent->instructionChanged();
164 }
165 
166 void VoiceNavigationModelPrivate::initializeMaps()
167 {
168  m_turnTypeMap.clear();
169  m_announceMap.clear();
170 
171  m_announceMap[Maneuver::Continue] = "Straight";
172  // none of our voice navigation commands fits, so leave out
173  // Maneuver::Merge here to have a sound play instead
174  m_announceMap[Maneuver::Straight] = "Straight";
175  m_announceMap[Maneuver::SlightRight] = "AhKeepRight";
176  m_announceMap[Maneuver::Right] = "AhRightTurn";
177  m_announceMap[Maneuver::SharpRight] = "AhRightTurn";
178  m_announceMap[Maneuver::TurnAround] = "AhUTurn";
179  m_announceMap[Maneuver::SharpLeft] = "AhLeftTurn";
180  m_announceMap[Maneuver::Left] = "AhLeftTurn";
181  m_announceMap[Maneuver::SlightLeft] = "AhKeepLeft";
182  m_announceMap[Maneuver::RoundaboutFirstExit] = "RbExit1";
183  m_announceMap[Maneuver::RoundaboutSecondExit] = "RbExit2";
184  m_announceMap[Maneuver::RoundaboutThirdExit] = "RbExit3";
185  m_announceMap[Maneuver::ExitLeft] = "AhExitLeft";
186  m_announceMap[Maneuver::ExitRight] = "AhExitRight";
187 
188  m_turnTypeMap[Maneuver::Continue] = "Straight";
189  // none of our voice navigation commands fits, so leave out
190  // Maneuver::Merge here to have a sound play instead
191  m_turnTypeMap[Maneuver::Straight] = "Straight";
192  m_turnTypeMap[Maneuver::SlightRight] = "BearRight";
193  m_turnTypeMap[Maneuver::Right] = "TurnRight";
194  m_turnTypeMap[Maneuver::SharpRight] = "SharpRight";
195  m_turnTypeMap[Maneuver::TurnAround] = "UTurn";
196  m_turnTypeMap[Maneuver::SharpLeft] = "SharpLeft";
197  m_turnTypeMap[Maneuver::Left] = "TurnLeft";
198  m_turnTypeMap[Maneuver::SlightLeft] = "BearLeft";
199  m_turnTypeMap[Maneuver::RoundaboutFirstExit] = "";
200  m_turnTypeMap[Maneuver::RoundaboutSecondExit] = "";
201  m_turnTypeMap[Maneuver::RoundaboutThirdExit] = "";
202  m_turnTypeMap[Maneuver::ExitLeft] = "TurnLeft";
203  m_turnTypeMap[Maneuver::ExitRight] = "TurnRight";
204 }
205 
206 VoiceNavigationModel::VoiceNavigationModel( QObject *parent ) :
207  QObject( parent ), d( new VoiceNavigationModelPrivate( this ) )
208 {
209  // nothing to do
210 }
211 
212 VoiceNavigationModel::~VoiceNavigationModel()
213 {
214  delete d;
215 }
216 
217 QString VoiceNavigationModel::speaker() const
218 {
219  return d->m_speaker;
220 }
221 
222 void VoiceNavigationModel::setSpeaker(const QString &speaker)
223 {
224  if ( speaker != d->m_speaker ) {
225  QFileInfo speakerDir = QFileInfo( speaker );
226  if ( !speakerDir.exists() ) {
227  d->m_speaker = MarbleDirs::path( "/audio/speakers/" + speaker );
228  } else {
229  d->m_speaker = speaker;
230  }
231 
232  emit speakerChanged();
233  emit previewChanged();
234  }
235 }
236 
237 bool VoiceNavigationModel::isSpeakerEnabled() const
238 {
239  return d->m_speakerEnabled;
240 }
241 
242 void VoiceNavigationModel::setSpeakerEnabled( bool enabled )
243 {
244  if ( enabled != d->m_speakerEnabled ) {
245  d->m_speakerEnabled = enabled;
246  emit isSpeakerEnabledChanged();
247  emit previewChanged();
248  }
249 }
250 
251 void VoiceNavigationModel::reset()
252 {
253  d->reset();
254 }
255 
256 void VoiceNavigationModel::handleTrackingStatusChange( PositionProviderStatus status )
257 {
258  if ( status != PositionProviderStatusAvailable && d->m_gpsStatus == PositionProviderStatusAvailable ) {
259  d->updateInstruction( d->m_speakerEnabled ? "GpsLost" : "KDE-Sys-List-End" );
260  }
261 
262  if ( status == PositionProviderStatusAvailable && d->m_gpsStatus != PositionProviderStatusAvailable ) {
263  d->updateInstruction( d->m_speakerEnabled ? "GpsFound" : "KDE-Sys-App-Positive" );
264  }
265 
266  d->m_gpsStatus = status;
267 }
268 
269 void VoiceNavigationModel::update(const Route &route, qreal distanceManuever, qreal distanceTarget, bool deviated )
270 {
271  if ( d->m_destinationReached && distanceTarget < 250 ) {
272  return;
273  }
274 
275  if ( !d->m_destinationReached && distanceTarget < 50 ) {
276  d->m_destinationReached = true;
277  d->updateInstruction( d->m_speakerEnabled ? "Arrive" : "KDE-Sys-App-Positive" );
278  return;
279  }
280 
281  if ( distanceTarget > 150 ) {
282  d->m_destinationReached = false;
283  }
284 
285  if ( deviated && !d->m_deviated ) {
286  d->updateInstruction( d->m_speakerEnabled ? "RouteDeviated" : "KDE-Sys-List-End" );
287  }
288  d->m_deviated = deviated;
289  if ( deviated ) {
290  return;
291  }
292 
293  Maneuver::Direction turnType = route.currentSegment().nextRouteSegment().maneuver().direction();
294  if ( !( d->m_lastTurnPoint == route.currentSegment().nextRouteSegment().maneuver().position() ) || turnType != d->m_lastTurnType ) {
295  d->m_lastTurnPoint = route.currentSegment().nextRouteSegment().maneuver().position();
296  d->reset();
297  }
298 
299  bool const announcement = ( d->m_lastDistance == 0 || d->m_lastDistance > 850 ) && distanceManuever <= 850;
300  bool const turn = ( d->m_lastDistance == 0 || d->m_lastDistance > 75 ) && distanceManuever <= 75;
301  if ( announcement || turn ) {
302  d->updateInstruction( distanceManuever, turnType );
303  }
304 
305  d->m_lastTurnType = turnType;
306  d->m_lastDistance = distanceManuever;
307 }
308 
309 QString VoiceNavigationModel::preview() const
310 {
311  return d->audioFile( d->m_speakerEnabled ? "Marble" : "KDE-Sys-App-Positive" );
312 }
313 
314 QString VoiceNavigationModel::instruction() const
315 {
316  return d->m_queue.isEmpty() ? QString() : d->m_queue.first();
317 }
318 
319 }
320 
321 #include "VoiceNavigationModel.moc"
Marble::Maneuver::TurnAround
Definition: Maneuver.h:34
Marble::VoiceNavigationModel::isSpeakerEnabledChanged
void isSpeakerEnabledChanged()
VoiceNavigationModel.h
Marble::Maneuver::SharpRight
Definition: Maneuver.h:33
Marble::MarbleDirs::path
static QString path(const QString &relativePath)
Definition: MarbleDirs.cpp:53
Marble::VoiceNavigationModel::VoiceNavigationModel
VoiceNavigationModel(QObject *parent=0)
Constructor.
Definition: VoiceNavigationModel.cpp:206
Marble::VoiceNavigationModel::speaker
QString speaker() const
Marble::VoiceNavigationModel::setSpeaker
void setSpeaker(const QString &speaker)
Definition: VoiceNavigationModel.cpp:222
Marble::Maneuver::Left
Definition: Maneuver.h:36
Marble::VoiceNavigationModel::preview
QString preview() const
QObject
Marble::Maneuver::ExitRight
Definition: Maneuver.h:43
MarbleDebug.h
Marble::Maneuver::Straight
Definition: Maneuver.h:30
Marble::VoiceNavigationModel::isSpeakerEnabled
bool isSpeakerEnabled() const
Marble::PositionProviderStatusUnavailable
Definition: PositionProviderPluginInterface.h:27
Marble::VoiceNavigationModel::~VoiceNavigationModel
~VoiceNavigationModel()
Destructor.
Definition: VoiceNavigationModel.cpp:212
Marble::Maneuver::Right
Definition: Maneuver.h:32
Marble::Maneuver::RoundaboutFirstExit
Definition: Maneuver.h:38
Marble::VoiceNavigationModel::speakerChanged
void speakerChanged()
MarbleDirs.h
Marble::Maneuver::SlightRight
Definition: Maneuver.h:31
Marble::VoiceNavigationModel::reset
void reset()
Definition: VoiceNavigationModel.cpp:251
Marble::PositionProviderStatus
PositionProviderStatus
Definition: PositionProviderPluginInterface.h:25
Marble::VoiceNavigationModel::previewChanged
void previewChanged()
Marble::Route::currentSegment
const RouteSegment & currentSegment() const
Definition: Route.cpp:128
Marble::RouteSegment::nextRouteSegment
const RouteSegment & nextRouteSegment() const
Definition: RouteSegment.cpp:72
Marble::Maneuver::Continue
Definition: Maneuver.h:28
Marble::VoiceNavigationModel::handleTrackingStatusChange
void handleTrackingStatusChange(PositionProviderStatus status)
Definition: VoiceNavigationModel.cpp:256
Marble::Maneuver::direction
Direction direction() const
Definition: Maneuver.cpp:42
Marble::VoiceNavigationModel::instruction
QString instruction() const
Marble::Maneuver::RoundaboutThirdExit
Definition: Maneuver.h:40
Marble::VoiceNavigationModel::update
void update(const Route &route, qreal distanceManuever, qreal distanceTarget, bool deviated)
Definition: VoiceNavigationModel.cpp:269
Marble::Route
Definition: Route.h:20
Marble::PositionProviderStatusAvailable
Definition: PositionProviderPluginInterface.h:29
Marble::VoiceNavigationModel::setSpeakerEnabled
void setSpeakerEnabled(bool enabled)
Definition: VoiceNavigationModel.cpp:242
Marble::Maneuver::SlightLeft
Definition: Maneuver.h:37
Marble::Maneuver::SharpLeft
Definition: Maneuver.h:35
Marble::Maneuver::RoundaboutSecondExit
Definition: Maneuver.h:39
Marble::Maneuver::position
GeoDataCoordinates position() const
Definition: Maneuver.cpp:71
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
Marble::RouteSegment::maneuver
const Maneuver & maneuver() const
Definition: RouteSegment.cpp:32
Marble::Maneuver::Direction
Direction
Definition: Maneuver.h:26
Marble::Maneuver::ExitLeft
Definition: Maneuver.h:42
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal