Text to Speech
<div class="standards">
<p class="must">Must Not</p>
<p>Section 508:</p>
<ul>
<li>§1194.21(b)</li>
<li>§1194.31(a)</li>
</ul>
<p>WCAG 2.0:</p>
<ul>
<li>1.4.2</li>
</ul>
</div>
<h3>Audio must not disrupt text to speech functionality of assistive technologies.</h3>
<p>When audio and text to speech based assistive technologies are operating simultaneously they may disrupt one another without careful consideration.</p>
<p class="environment">iOS</p>
<p>In iOS, text to speech will lower the volume of any playing media in order to allow the speech to be clearly heard over any audio output currently playing. This may prove problematic for controls that interface with audio such as playback controls when users are unable to hear the audio due to text to speech covering it or text to speech being cut off by audio playback.</p>
<p class="environment">iOS Example</p>
<pre class="brush:xml">// Controls that interact with audio playback with
UIAccessibilityTraitPlaysSound</pre>
<p class="environment">iOS Failure</p>
<pre class="brush:xml">// Controls that interact with audio playback without
UIAccessibilityTraitPlaysSound</pre>
<p class="environment">Android</p>
<p> In Android audio is managed cooperatively between applications and the system by way of the Audio Focus.</p>
<p class="environment">Android Example</p>
<pre class="brush:xml">//Application/Media Playback that is polite and respects OS/Speech
synthesis priority
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mMediaPlayer == null) initMediaPlayer();
else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback
and release media player
if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because
playback
// is likely to resume
if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f,
0.1f);
break;
}
}</pre>
<p class="environment">Android Failure</p>
<pre class="brush:xml">//Application/Media Playback that is not polite and attempts to maintain
audio priority
public void onAudioFocusChange(int focusChange) {
//attempt to resume playback
if (mMediaPlayer == null) {
initMediaPlayer();
} else if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
}
}</pre>
<p class="environment">Remediating</p>
<p>iOS: Controls that interact with audio playback should have theUIAccessibilityTraitPlaysSound trait applied. This trait informs VoiceOver and other assistive technologies that the control plays sound when activated. This allows assistive technologies to be aware of controls with their own audio playback and take appropriate action such as not speaking when the control is activated to avoid conflicting with the audio playback of the control.</p>
<p>Android: Developers should use the Audio focus Manager to control audio levels to ensure that speech is not disrupted by the playing audio.</p>
<p class="environment">Testing</p>
<p class="tool">Recommended tool/method: Manual</p>
<h5>Ensure audio controls do not disrupt speech (Global)</h5>
<ol>
<li>Open the app using voice recognition software</li>
<li>Activate the controls that start audio</li>
<li>Verify the following:
<ol>
<li>Controls that start audio do not speak when actuated</li>
<li>Audio playback volume is lowered when text to speech is speaking</li>
</ol>
</li>
</ol>