Replace speech services

Cruzr provides various system services, including speech services. When the speech service function provided by Cruzr cannot meet your requirements, developers can use the services they have implemented to replace the original services by overriding it.

The speech services include three services: speech recognition, natural language processing, and speech synthesis. Each module can be overridden separately.

Add library dependencies

Introduce the Cruzr SDK

To download and introduce the Cruzr SDK, please refer to build your first app

Introduce Cruzr_speech_override.aar

Replacing speech services requires an additional SDK (Cruzr_speech_override.aar). Put the downloaded dependency package into the app/libs/ directory and add the following dependencies in app/build.gradle:

dependencies {
    implementation(name: 'cruzr_speech_override', ext: aar')//Speech service override SDK
}

Finally, find the Sync Project with Gradle Files button on the Android Studio tool bar, and click it to perform the synchronization operation.

Note: Overriding speech services requires both Cruzr.jar and Cruzr_speech_override.aar. There is a difference between the two dependency methods.

Configure overriding rules

The replaced voice service supports automatic switching in the specified languages. Create a decision_list.xml file in the app/src/main/res/xml directory and add the overriding configuration. When the system language is switched to the specified language, the specified module of the system's speech service is overridden, and the speech service module developed by the developer will be used.

<?xml version="1.0" encoding="utf-8"?>
<decision-list>
    <decision>
        <if>
            <!-- choose the languages to replace the speech service -->
            <language name="en-rUS" />
        </if>
        <then>
            <route-service>
                <!-- Overriding speech synthesis -->
                <parameter-group
                    package="name of your application package"
                    service="speech.synthesis" />
                <!-- Overriding speech recognition -->
                 <parameter-group
                    package="name of your application package"
                    service="speech.recognition" />
                <!-- Overriding speech understanding -->
                <parameter-group
                    package="name of your application package"
                    service="speech.understanding" />
            </route-service>
        </then>

        <if>
            <!-- choose the languages to replace the speech service -->
            <language name="zh-rCN" />
        </if>
        <then>
            <route-service>
                <!-- Overriding speech synthesis -->
                <parameter-group
                    package="name of your application package"
                    service="speech.synthesis" />
            </route-service>
        </then>
    </decision>
</decision-list>

Note: The three modules of the speech service can be overridden independently or in multiples. In the example, the English environment overrode four modules at the same time, and the Chinese environment only overrode the speech synthesis module. The language configuration must be configured according to the Android resource's standard language format.

Develop customized speech service

Implement the service

Since you want to replace the original speech service, it is necessary to implement a customized speech service. After configuring the service replacing rules, the services in the configuration need to be implemented concretely. The following code takes Text-to-sound(TTS) service as an example:

public class YourSynthesisServices extends AbstractSynthesizer {

    private GoogleSpeaker googleSpeaker;

    public YourSynthesisServices() {
        googleSpeaker = new GoogleSpeaker();
    }

    @Override
    protected void startSynthesizing(SynthesisOption synthesisOption) {
        // the new speech broadcast is realized
        googleSpeaker.speak(synthesisOption.getInputText(), new TtsCallBack() {
            @Override
            public void onSpeakStart() {
                // the broadcast is started, the progress change will be notified
                reportSynthesizingProgress(new SynthesisProgress.Builder(SynthesisProgress.PROGRESS_BEGAN).build());
            }

            @Override
            public void onSpeaking() {
                // broadcasting, the broadcast is started, the progress change will be notified
                reportSynthesizingProgress(new SynthesisProgress.Builder(SynthesisProgress.PROGRESS_PLAYING)// broadcast status
                        .setRemainingTimeMillis(3000)// time remaining of the broadcast
                        .setPlayProgress(50)// current progress of the broadcast
                        .build());
            }

            @Override
            public void onSpeakError(Exception e) {
                // broadcast error
                rejectSynthesizing(new SynthesisException(SynthesisException.CODE_INTERNAL_ERROR));
            }

            @Override
            public void onSpeakCompleted() {
                // broadcast completed
                reportSynthesizingProgress(new SynthesisProgress.Builder(SynthesisProgress.PROGRESS_ENDED).build());

                resolveSynthesizing();
            }
        });
    }

    @Override
    protected void stopSynthesizing() {
        // cancel the broadcast
        googleSpeaker.stop();
    }

    @Override
    public List<SpeakingVoice> getSpeakingVoiceList() {
        // get the speaker's information
        SpeakingVoice speaker = new SpeakingVoice.Builder("google")
                .setLanguage("en")
                .build();
        return Collections.singletonList(speaker);
    }
}

Declare service

After implementing the speech service, we need one more step, which is declarative Services. Declare the service we implemented in the onCreate() method of Application class of the project.

public class FooApplication extends Application {

    @Override
    public void onCreate() {
        //TODO Initialization service
        ServiceModules.initialize(this);

        //TODO Declare speech recognition service
        ServiceModules.declare(
                Synthesizer.class,
                new ModuleCreator<Synthesizer>() {
                    @Override
                    public void createModule(Class<Synthesizer> aClass,
                                ModuleCreatedNotifier<Synthesizer> notifier) {
                        notifier.notifyModuleCreated(new FooServices());//Provide an example of the service
                    }
                }
        );
    }
}

Finally, restart the system to use the overriding speech service.