Xamarin Forms Text To Speech Wont Play On Device Without Headphones
Asked Answered
L

2

0

I have a Xamarin Forms app that uses text to speech. The code in the iOS project is exactly the same as on the official Xamarin Implementing Text To Speech guide

    var speechSynthesizer = new AVSpeechSynthesizer ();
    var speechUtterance = new AVSpeechUtterance (text) {
        Rate = AVSpeechUtterance.MaximumSpeechRate/4,
        Voice = AVSpeechSynthesisVoice.FromLanguage ("en-US"),
        Volume = 0.5f,
        PitchMultiplier = 1.0f
    };

    speechSynthesizer.SpeakUtterance (speechUtterance);

This works great in the iOS emulator but when I deploy to my iPad running iOS 10.2.1 I only hear any sound if I put headphones on. I've turned the volume right up and still nothing without headphones, if I do use headphones though it's very loud so implies it's not just too quiet. Other apps play audio fine through my iPad speaker so I don't think it's a hardware issue.

I've also tried using this plugin (https://github.com/jamesmontemagno/TextToSpeechPlugin) for text to speech but it has the exact same issue when I deploy to the device.

Is there any reason this would work with headphones but fail when no headphones are plugged in?

Latchstring answered 22/2, 2017 at 8:58 Comment(5)
Did you flip the switch at the side of the iOS device to get it off silent mode?Garling
It's an air 2 so there is no switch. Other apps will play audio though so I'm assuming it can't be a silent mode issueLatchstring
Oh that is right! How about in the panel when you swipe up? The bell sign? That is how you turn on and off silent mode. As a developer you can choose to ignore the silent mode switch, but by default it will adhere to that setting. So it is possible that this is the issue, while other apps play sound.Garling
I had no idea other apps could ignore silent mode and that headphones also ignore it. That was exactly the issue. If you want to post an answer I'll accept it.Latchstring
At least you've learned a thing or two ;) Posted it as an answer, thank you!Garling
G
3

I see no apparent reason why your code should not work. The only explanation I have is that 'silent mode' is activated on your iDevice. To switch this off, either use the switch on the left side, or for newer devices to into the control center by swiping up from the bottom of the screen and pressing the bell icon.

iOS control center

You also note that other apps do produce sound. As a developer, you may choose to ignore the silent mode and play sound anyway, while this should be considered bad practice, it is allowed by Apple. However, it is not enabled by default, so with the code you have sound will be muted by silent mode.

Garling answered 22/2, 2017 at 10:54 Comment(0)
B
0

It seems impossible to circumvent the silent mode but you can detect it and notify the user about text-to-speech not working when the silent switch is on.

Here's a solution inspired by the SoundSwitch library. On iPhone 8, the await takes 160-250ms for a 50ms-long mute.caf but only 3-8ms when the silent switch is on. You can download the 50ms mute.caf from this Gist.

using System;
using Foundation;
using AudioToolbox;
using System.Threading.Tasks;

public class SilentSwitch
{
    readonly SystemSound _sound;

    public SilentSwitch()
    {
        var url = NSBundle.MainBundle.GetUrlForResource("mute", "caf");
        _sound = new SystemSound(url);
        _sound.IsUISound = true;
    }

    public async Task<bool> IsEnabled()
    {
        var startTime = DateTime.Now;

        await _sound.PlaySystemSoundAsync();

        var elapsedTime = DateTime.Now - startTime;
        return elapsedTime.TotalMilliseconds < 50;
    }
}
Barrator answered 30/4, 2021 at 0:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.