CatalystCode / cordova-plugin-cogsvcsspeech

Cordova plugin for Microsoft Cognitive Services speech services.
MIT License
2 stars 3 forks source link

Stop Speaking #11

Open esgraham opened 4 years ago

esgraham commented 4 years ago

Description

As an application user, I'd like to have stop speaking code on the iOS and Android platform, in order to have an event that stops the speaker from speaking.

Acceptance Criteria

rozele commented 4 years ago

FYI - confirmed that the following does not work on Android:

SpeechSynthesizer synthesizer;
...
SpeechConfig config = SpeechConfig.fromSubscription(...);
synthesizer = new SpeechSynthesizer(config);
...
Future<SpeechSynthesisResult> future = synthesizer.SpeakTextAsync(...);
...
future.cancel(true);
rozele commented 4 years ago

Here is an example where I was playing audio from a PullAudioInputStream for Direct Line Speech:

    private void playAudio(PullAudioOutputStream stream, Runnable callback) {
        final int SAMPLE_RATE = 16000;

        final int BUFFER_SIZE = AudioTrack.getMinBufferSize(
                SAMPLE_RATE,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT);

        LinkedList<byte[]> buffer = new LinkedList<>();
        AtomicInteger doneFlag = new AtomicInteger(0);

        AsyncTask.execute(() -> {
            byte[] data = new byte[BUFFER_SIZE];
            while (stream.read(data) > 0) {
                synchronized (buffer) {
                    buffer.add(data);
                }
                data = new byte[BUFFER_SIZE];
            }
            doneFlag.getAndIncrement();
        });

        AsyncTask.execute(() -> {
            AudioTrack audioTrack = new AudioTrack(
                    AudioManager.STREAM_MUSIC,
                    SAMPLE_RATE,
                    AudioFormat.CHANNEL_OUT_MONO,
                    AudioFormat.ENCODING_PCM_16BIT,
                    BUFFER_SIZE,
                    AudioTrack.MODE_STREAM);

            if (audioTrack.getState() == AudioTrack.STATE_INITIALIZED) {
                audioTrack.play();
                byte[] sound = new byte[BUFFER_SIZE];
                while (buffer.size() > 0 || doneFlag.get() == 0) {
                    if (buffer.size() > 0) {
                        audioTrack.write(buffer.peek(), 0, sound.length);
                        synchronized (buffer) {
                            buffer.pop();
                        }
                    }
                }
                audioTrack.stop();
                audioTrack.release();
            }

            if (callback != null) {
                callback.run();
            }
        });
    }

We could add something similar but we'll need to support cancellation.