Implementing Voice Recognition and Text-to-Speech in Flutter

Voice recognition and text-to-speech (TTS) capabilities are essential features in modern mobile applications, enhancing user accessibility and engagement. Flutter, Google’s UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase, makes implementing these features relatively straightforward. This blog post will guide you through implementing voice recognition and text-to-speech in your Flutter applications.

Why Voice Recognition and Text-to-Speech?

  • Accessibility: Provides an alternative way for users to interact with the app, benefiting users with disabilities.
  • Convenience: Enables hands-free operation, improving user experience in various scenarios like driving or cooking.
  • Engagement: Adds an interactive element that can make apps more engaging and enjoyable.

Prerequisites

  • Basic knowledge of Flutter and Dart.
  • Flutter SDK installed and configured on your machine.
  • Android Studio or Xcode set up for platform-specific configurations if needed.

Setting up a Flutter Project

First, create a new Flutter project:

flutter create voice_text_app
cd voice_text_app

Voice Recognition Implementation

To implement voice recognition in Flutter, we will use the speech_to_text package. This package provides a simple and effective way to convert speech to text.

Step 1: Add the speech_to_text Package

Add the speech_to_text package to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  speech_to_text: ^6.3.0

Run flutter pub get to install the package.

Step 2: Import the Package in Your Dart File

In your Dart file (e.g., main.dart), import the speech_to_text package:

import 'package:speech_to_text/speech_to_text.dart' as stt;

Step 3: Initialize the Speech-to-Text Engine

Create a class to manage the speech-to-text functionality. Initialize the speech-to-text engine and define methods to start and stop listening.

import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;

class VoiceRecognitionService {
  late stt.SpeechToText _speech;
  bool _isListening = false;
  String _text = 'Press the button and start speaking';

  String get text => _text;
  bool get isListening => _isListening;

  void initializeSpeech() async {
    _speech = stt.SpeechToText();
    bool available = await _speech.initialize(
      onStatus: (status) => print('Status: $status'),
      onError: (errorNotification) => print('Error: $errorNotification'),
    );
    if (available) {
      print('Speech recognition available');
    } else {
      print('Speech recognition not available');
    }
  }

  void startListening() async {
    _isListening = true;
    _speech.listen(
      onResult: (result) {
        _text = result.recognizedWords;
        print('Recognized words: $_text');
      },
      listenFor: const Duration(seconds: 10),
      pauseFor: const Duration(seconds: 5),
      localeId: 'en_US',
      onSoundLevelChange: (level) => print('Sound level $level'),
      cancelOnError: true,
      listenMode: stt.ListenMode.confirmation,
    );
  }

  void stopListening() {
    _isListening = false;
    _speech.stop();
  }
}

Step 4: Update the UI to Control Voice Recognition

Integrate the voice recognition service into your UI. Add a button to start and stop voice recognition, and display the recognized text.

import 'package:flutter/material.dart';
import 'voice_recognition_service.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State {
  final VoiceRecognitionService _voiceRecognitionService = VoiceRecognitionService();

  @override
  void initState() {
    super.initState();
    _voiceRecognitionService.initializeSpeech();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Voice Recognition'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                _voiceRecognitionService.text,
                style: const TextStyle(fontSize: 20),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  setState(() {
                    if (_voiceRecognitionService.isListening) {
                      _voiceRecognitionService.stopListening();
                    } else {
                      _voiceRecognitionService.startListening();
                    }
                  });
                },
                child: Text(
                  _voiceRecognitionService.isListening ? 'Stop Listening' : 'Start Listening',
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Text-to-Speech Implementation

To implement text-to-speech functionality, we will use the flutter_tts package. This package allows your Flutter app to speak text.

Step 1: Add the flutter_tts Package

Add the flutter_tts package to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  flutter_tts: ^3.8.5

Run flutter pub get to install the package.

Step 2: Import the Package

In your Dart file, import the flutter_tts package:

import 'package:flutter_tts/flutter_tts.dart';

Step 3: Initialize and Use FlutterTts

Create a FlutterTts instance and use its methods to configure and speak text.

import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';

class TextToSpeechService {
  late FlutterTts flutterTts;
  double volume = 0.5;
  double pitch = 1.0;
  double rate = 0.5;

  TextToSpeechService() {
    flutterTts = FlutterTts();
    _setAwaitOptions();
  }

  Future _setAwaitOptions() async {
    await flutterTts.awaitSpeakCompletion(true);
  }

  Future speak(String text) async {
    await flutterTts.setVolume(volume);
    await flutterTts.setSpeechRate(rate);
    await flutterTts.setPitch(pitch);

    await flutterTts.speak(text);
  }

  Future stop() async {
    await flutterTts.stop();
  }
}

Step 4: Integrate Text-to-Speech into Your UI

Add a text field where the user can enter text, and a button to trigger the text-to-speech functionality.

import 'package:flutter/material.dart';
import 'text_to_speech_service.dart';

class TTSExample extends StatefulWidget {
  const TTSExample({Key? key}) : super(key: key);

  @override
  _TTSExampleState createState() => _TTSExampleState();
}

class _TTSExampleState extends State {
  final TextEditingController _textEditingController = TextEditingController();
  final TextToSpeechService _textToSpeechService = TextToSpeechService();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Text-to-Speech'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _textEditingController,
              decoration: const InputDecoration(
                hintText: 'Enter text to speak',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                _textToSpeechService.speak(_textEditingController.text);
              },
              child: const Text('Speak Text'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                _textToSpeechService.stop();
              },
              child: const Text('Stop'),
            ),
          ],
        ),
      ),
    );
  }
}

Combining Voice Recognition and Text-to-Speech

You can combine both features to create a more interactive app.

import 'package:flutter/material.dart';
import 'voice_recognition_service.dart';
import 'text_to_speech_service.dart';

class CombinedExample extends StatefulWidget {
  const CombinedExample({Key? key}) : super(key: key);

  @override
  _CombinedExampleState createState() => _CombinedExampleState();
}

class _CombinedExampleState extends State {
  final VoiceRecognitionService _voiceRecognitionService = VoiceRecognitionService();
  final TextToSpeechService _textToSpeechService = TextToSpeechService();

  @override
  void initState() {
    super.initState();
    _voiceRecognitionService.initializeSpeech();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Combined Voice and TTS'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              _voiceRecognitionService.text,
              style: const TextStyle(fontSize: 20),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  if (_voiceRecognitionService.isListening) {
                    _voiceRecognitionService.stopListening();
                    _textToSpeechService.speak(_voiceRecognitionService.text);
                  } else {
                    _voiceRecognitionService.startListening();
                  }
                });
              },
              child: Text(
                _voiceRecognitionService.isListening ? 'Stop Listening and Speak' : 'Start Listening',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Platform-Specific Configurations

Some platforms require specific permissions and configurations. Make sure to configure your app properly for Android and iOS.

Android

Add the necessary permissions to your AndroidManifest.xml file:



iOS

Add the necessary descriptions in your Info.plist file:

NSMicrophoneUsageDescription
This app needs microphone access to record your speech.

Conclusion

Implementing voice recognition and text-to-speech in Flutter enhances user experience and accessibility. The speech_to_text and flutter_tts packages provide easy-to-use APIs for integrating these features into your applications. With proper configuration and UI integration, you can create interactive and user-friendly Flutter apps that leverage the power of voice and speech technologies.