同时进行语音转文本和文本转语音

2024-03-13

介绍

我正在开发一个应用程序,我需要在其中使用 Booth SpeechRecognizer 和 TTS。但我在尝试这个时遇到了一些问题。主要的一个问题是,如果我初始化 TTS,SpeechRecgonizer 似乎无法工作,而如果我禁用 TTS,则 SpeechRecognizer 可以正常工作。接下来是带有相关代码的代码片段:

CODE

public class GameActivity extends Activity implements OnInitListener {

    private static TextToSpeech tts;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.game);

        /*SPEECH RECOGNIZER INSTANT*/
        Log.d("SPEECH", "speech recognition available: " + SpeechRecognizer.isRecognitionAvailable(this));
        mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        mSpeechRecognizer.setRecognitionListener(new SpeechListener());

        mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
            this.getPackageName());

        /*START LISTENING*/
        mSpeechRecognizer.startListening(mSpeechRecognizerIntent);

        /*CHECK TTS AVAILABLE*/
        Intent checkIntent = new Intent();
        checkIntent.setAction( TextToSpeech.Engine.ACTION_CHECK_TTS_DATA );
        startActivityForResult(checkIntent, CHECK_TTS_DATA);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case CHECK_TTS_DATA: {
                /*IF OK, INITIALIZES TTS*/
                if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                    Log.d("TTS", "TTS available");
                    tts = new TextToSpeech(this, this);
                }
                else {
                    Log.d("TTS", "TTS NOT available");
                    Intent promptInstall = new Intent();
                    promptInstall.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                    startActivity(promptInstall);
                }
                break;
            }
        }
    }


    /**OnInitListener implementation*/
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            /*set Language*/
            tts.setLanguage(Locale.getDefault());
            /*STARTS MAIN METHOD*/
            Log.d("SPEECH", "Initialized, starting main method");
            SpeechWhenMotion();
        } else {
            Log.e("TTS", "Initilization Failed");
        }
    }


    /**INNER LISTENER CLASS*/
    private class SpeechListener implements RecognitionListener {
        @Override
        public void onBufferReceived(byte[] buffer) {
            Log.d("SR_LISTENER", "onBufferReceived");
        }
        @Override
        public void onError(int error) {
            Log.d("SR_LISTENER", "onError: " + error);
            mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
        }
        @Override
        public void onEvent(int eventType, Bundle params) {
            Log.d("SR_LISTENER", "onEvent");
        }
        @Override
        public void onPartialResults(Bundle partialResults) {
            Log.d("SR_LISTENER", "onPartialResults");
        }
        @Override
        public void onReadyForSpeech(Bundle params) {
            Log.d("SR_LISTENER", "onReadyForSpeech");
        }
        @Override
        public void onResults(Bundle results) {
            Log.d("SR_LISTENER", "onResult");

        matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        }
        @Override
        public void onRmsChanged(float rmsdB) {
            Log.d("SR_LISTENER", "onRmsChanged");
        }
        @Override
        public void onBeginningOfSpeech() {
            Log.d("SR_LISTENER", "onBeginningOfSpeech");
        }
        @Override
        public void onEndOfSpeech() {
            Log.d("SR_LISTENER", "onEndOfSpeech");
        }
    }

所以基本上我面临的就是简介中解释的内容。如果我不这样做tts = new TextToSpeech(this, this);,然后我在 LogCat 中看到引用语音侦听器的日志,但如果我初始化 TTS,则看不到此日志。

另外,我想当我能够让它们工作时,我应该在 TTS 说话时停止听。

更新——完整的简单项目代码

主要活动:

public class MainActivity extends Activity implements OnInitListener {

    /*Voice and speech variables*/
    private static TextToSpeech tts;

    public static final int CHECK_TTS_DATA = 1;

    public static boolean fase0 = true;
    public static boolean fase1 = false;

    /*Service*/
    private int mBindFlag;
    public static Messenger mActivityMessenger;

    static int result;
    private final boolean mFinished = false;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivityMessenger = new Messenger(new IncomingHandler());

        Intent serviceIntent = new Intent(this, SpeechRecognitionService.class);
        serviceIntent.putExtra("Messenger", mActivityMessenger);
        startService(serviceIntent);
        mBindFlag = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH ? 0 : Context.BIND_ABOVE_CLIENT;

        Intent checkIntent = new Intent();
        checkIntent.setAction( TextToSpeech.Engine.ACTION_CHECK_TTS_DATA );
        startActivityForResult(checkIntent, CHECK_TTS_DATA);
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case CHECK_TTS_DATA: {
                if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                    Log.d("TTS", "TTS available");
                    tts = new TextToSpeech(this, this);
                }
                else {
                    Log.d("TTS", "TTS NOT available");
                    Intent promptInstall = new Intent();
                    promptInstall.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                    startActivity(promptInstall);
                }
                break;
            }
        }
    }



    /******************
     * 
     * MAIN METHOD
     * 
     ******************/

    public void SpeechWhenMotion() {
        while (!mFinished) {
            if (fase0) {
                tts.speak("Initializing", TextToSpeech.QUEUE_FLUSH, null);
                fase0 = false;
            }
            else if (fase1) {
                if (result == SpeechRecognitionService.CONTINUE) {
                    tts.speak("Correct", TextToSpeech.QUEUE_FLUSH, null);
                    mFinished = true;
                }
                else if (result == SpeechRecognitionService.NO_MATCH) {
                    tts.speak("No matching", TextToSpeech.QUEUE_FLUSH, null);
                }
                else {
                    Log.d("RESULT", String.valueOf(result));
                }
            }
        }
    }



    /******************
     * 
     * SERVICE LINK
     * 
     ******************/

    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("SERVICE", "onServiceConnected"); //$NON-NLS-1$

            SpeechRecognitionService.mServiceMessenger = new Messenger(service);
            Message msg = new Message();
            msg.what = SpeechRecognitionService.MSG_RECOGNIZER_START_LISTENING;
            try {
                SpeechRecognitionService.mServiceMessenger.send(msg);
            }
            catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("SERVICE", "onServiceDisconnected");
            SpeechRecognitionService.mServiceMessenger = null;
        }
    };


    private static class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SpeechRecognitionService.MSG_SPEECH_RESULT:
                    Log.d("MESSENGER", "Message received");
                    result = msg.arg1;
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }



    /******************
     * 
     * IMPLEMENTED METHODS
     * 
     ******************/

    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            /*set Language*/
            tts.setLanguage(Locale.getDefault());
            // tts.setPitch(5); // set pitch level
            // tts.setSpeechRate(2); // set speech speed rate
            /*Start main method*/
            Log.d("TTS", "Initialized, starting main method");
            SpeechWhenMotion();
        } else {
            Log.e("TTS", "Initilization Failed");
        }

    }



    /******************
     * 
     * LIFE CYCLE
     * 
     ******************/

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (tts != null) {
            tts.stop();
            tts.shutdown();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        /*Bind SpeechRecognition service*/
        bindService(new Intent(this, SpeechRecognitionService.class), mServiceConnection, mBindFlag);
    }

    @Override
    protected void onStop() {
        super.onStop();

        /*Unbind SpeechRecognition service*/
        if (mActivityMessenger != null) {
            unbindService(mServiceConnection);
            mActivityMessenger = null;
        }
    }
}

Service:

public class SpeechRecognitionService extends Service {

    protected static AudioManager mAudioManager;
    protected SpeechRecognizer mSpeechRecognizer;
    protected Intent mSpeechRecognizerIntent;
    public static Messenger mServiceMessenger;

    protected boolean mIsListening;
    protected volatile boolean mIsCountDownOn;
    private static boolean mIsStreamSolo;

    static final int MSG_RECOGNIZER_START_LISTENING = 1;
    static final int MSG_RECOGNIZER_CANCEL = 2;
    static final int MSG_SPEECH_RESULT = 3;

    static ArrayList<String> matches;
    static final int CONTINUE = 11;
    static final int NO_MATCH = 12;



    /******************
     * 
     * ONCREATE
     * 
     ******************/

    @Override
    public void onCreate() {
        super.onCreate();

        mServiceMessenger = new Messenger(new IncomingHandler(this));

        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());

        mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                this.getPackageName());
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("SERVICE", "onStartCommand");
        MainActivity.mActivityMessenger = intent.getParcelableExtra("Messenger");
        return super.onStartCommand(intent, flags, startId);
    }



    /******************
     * 
     * METHODS
     * 
     ******************/

    @Override
    public IBinder onBind(Intent intent) {
        Log.d("BIND", "onBind");
        return mServiceMessenger.getBinder();
    }


    /**Count down timer for Jelly Bean work around*/
    protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000) {
        @Override
        public void onTick(long millisUntilFinished) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onFinish() {
            mIsCountDownOn = false;
            Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
            try {
                mServiceMessenger.send(message);
                message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
                mServiceMessenger.send(message);
            }
            catch (RemoteException e) {
            }
        }
    };



    public void sendMessageToUI(int result) {
        Message msg = new Message();
        msg = Message.obtain(null, MSG_SPEECH_RESULT);
        msg.arg1 = result;
        try {
            MainActivity.mActivityMessenger.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }



    /******************
     * 
     * INNER CLASSES/LISTENERS
     * 
     ******************/

    protected static class IncomingHandler extends Handler {
        private final WeakReference<SpeechRecognitionService> mtarget;

        IncomingHandler(SpeechRecognitionService target) {
            mtarget = new WeakReference<SpeechRecognitionService>(target);
        }

        @Override
        public void handleMessage(Message msg) {
            final SpeechRecognitionService target = mtarget.get();

            switch (msg.what) {
                case MSG_RECOGNIZER_START_LISTENING:

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        /*turn off beep sound*/
                        if (!mIsStreamSolo) {
                            mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
                            mIsStreamSolo = true;
                        }
                    }
                    if (!target.mIsListening) {
                        target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
                        target.mIsListening = true;
                        Log.d("SERVICE", "message start listening"); //$NON-NLS-1$
                    }
                    break;

                case MSG_RECOGNIZER_CANCEL:
                    if (mIsStreamSolo) {
                        mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, false);
                        mIsStreamSolo = false;
                    }
                    target.mSpeechRecognizer.cancel();
                    target.mIsListening = false;
                    Log.d(TAG, "message canceled recognizer"); //$NON-NLS-1$
                    break;
            }
        }
    }


    protected class SpeechRecognitionListener implements RecognitionListener {

        @Override
        public void onBeginningOfSpeech() {
            /*speech input will be processed, so there is no need for count down anymore*/
            if (mIsCountDownOn) {
                mIsCountDownOn = false;
                mNoSpeechCountDown.cancel();
            }
            Log.d("SR_LISTENER", "onBeginingOfSpeech"); //$NON-NLS-1$
        }

        @Override
        public void onBufferReceived(byte[] buffer) {

        }

        @Override
        public void onEndOfSpeech() {
            Log.d("SR_LISTENER", "onEndOfSpeech"); //$NON-NLS-1$
        }

        @Override
        public void onError(int error) {
            if (mIsCountDownOn) {
                mIsCountDownOn = false;
                mNoSpeechCountDown.cancel();
            }
            mIsListening = false;
            Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
            try {
                mServiceMessenger.send(message);
            }
            catch (RemoteException e) {

            }
            String issue = null;
            if (error == 1) {
                issue = "ERROR_NETWORK_TIMEOUT";
            }
            if (error == 2) {
                issue = "ERROR_NETWORK";
            }
            if (error == 3) {
                issue = "ERROR_AUDIO";
            }
            if (error == 4) {
                issue = "ERROR_SERVER";
            }
            if (error == 5) {
                issue = "ERROR_CLIENT";
            }
            if (error == 6) {
                issue = "ERROR_SPEECH_TIMEOUT";
            }
            if (error == 7) {
                issue = "ERROR_NO_MATCH";
            }
            if (error == 8) {
                issue = "ERROR_RECOGNIZER_BUSY";
            }
            if (error == 9) {
                issue = "ERROR_INSUFFICIENT_PERMISSIONS";
            }
            Log.d("SR_LISTENER", "error = " + issue); //$NON-NLS-1$
        }

        @Override
        public void onEvent(int eventType, Bundle params) {

        }

        @Override
        public void onPartialResults(Bundle partialResults) {

        }

        @Override
        public void onReadyForSpeech(Bundle params) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                mIsCountDownOn = true;
                mNoSpeechCountDown.start();
            }
            Log.d("SR_LISTENER", "onReadyForSpeech"); //$NON-NLS-1$
        }

        @Override
        public void onResults(Bundle results) {
            Log.d("SR_LISTENER", "onResults"); //$NON-NLS-1$

            matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

            if (matches.contains("continue")) {
                MainActivity.fase1 = true;
                sendMessageToUI(CONTINUE);
            }
            else {
                sendMessageToUI(NO_MATCH);
            }
        }

        @Override
        public void onRmsChanged(float rmsdB) {

        }
    }



    /******************
     * 
     * LIFE CYCLE
     * 
     ******************/

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (mIsCountDownOn) {
            mNoSpeechCountDown.cancel();
        }
        if (mSpeechRecognizer != null) {
            mSpeechRecognizer.destroy();
        }
    }
}

来自节点调试器的日志:

如图所示,服务侦听器启动并显示 onReadyForSpeech,但接下来 TTS 已初始化,即使我说话,侦听器也会停止显示日志,然后应该显示 onBeginingOfSpeech


你应该实施onUtteranceCompletedListener并发送 MSG_RECOGNIZER_START_LISTENINGonUtteranceCompleted.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同时进行语音转文本和文本转语音 的相关文章

随机推荐

  • Tensorflow unsorted_segment_sum 维度

    我正在使用tf unsorted segment sumTensorFlow 的方法 当我作为数据给出的张量只有一行时 它工作得很好 例如 tf unsorted segment sum tf constant 0 2 0 1 0 5 0
  • Bootstrap 3 导航栏折叠

    有什么方法可以增加 Bootstrap 3 导航栏折叠的点 即 使其在纵向平板电脑上折叠成下拉菜单 这两个适用于 bootstrap 2 但现在不行了 如何使用 Twitter bootstrap responsive 更改导航栏折叠阈值
  • Maven:带有 Groovy 2.3.5 的 Groovy-Eclipse 编译器插件

    Since GMaven http gmaven codehaus org 已经停产了 我一直在用Groovy Eclipse 编译器插件 http groovy codehaus org Groovy Eclipse compiler p
  • 程序员对Vista Windows任务管理器中内存的理解

    我对 XP 中的 Windows 任务管理器有一定的了解 但我想在 Vista 中更好地了解它 工作集 内存 和 内存 私有工作集 有什么区别 什么是Paged Pool 什么是NP Pool Non Paged 如何使用这些来确定内存使用
  • 比质心更好的“中心点”

    我正在使用多边形的质心在地图应用程序中附加标记 这对于凸多边形来说绝对有效 对于许多凹多边形来说也非常好 但是 某些多边形 香蕉 甜甜圈 显然不会产生所需的结果 在这些情况下 质心位于outside多边形区域 有谁知道更好的方法来找到合适的
  • List 的 Last() 扩展方法的性能如何?

    我很喜欢Last 并会一直使用它List
  • Rstudio 速度慢得令人痛苦

    突然间 Rstudio 慢得令人痛苦 现在无法使用 这意味着 我打开它 如果我输入任何内容 就会有几秒钟的延迟 我已经探索了我能想到的所有选项 1 重新安装 R 和 Rstudio 尽管我不能 100 确定我可以删除所有组件 2 尝试重置设
  • if 语句不起作用?

    我用调试器看了又看 似乎无法弄清楚为什么 IF 语句总是打印消息 IF 语句检查是否 yesno Y or N 但无论我输入 y 或 Y 或 n N 或 H B 它都会显示 我不知道该采取什么行动了 我似乎找不到哪里出了问题 if yesn
  • Neo4j cypher - 导入 CSV 并根据 csv 值添加节点之间的关系

    是否可以在 cypher 中使用导入功能根据 csv 的值在节点之间创建不同的关系 例如 对于给定的 csv 数据 product id user id action 1 1 VIEW 1 2 PURCHASE 我需要创建产品节点 prod
  • 在 MySQL 中插入/更新随机日期

    如何使用 MySQL 更新过去 2 周内随机日期的列 例如 代码实际上不起作用 UPDATE mytable SET col sysdate rand 1 14 您可以使用以下表达式获得一个随机整数 获取随机整数R 范围 i FLOOR i
  • 检查 Oracle 数据库有多少年了?

    因此 我们有一个生产数据库的经过处理的版本的镜像 无论如何 您知道 是否可以查明数据库的年龄 即当数据库放置在 Oracle 服务器上时 谢谢你的帮助 选择从 dba users 创建 其中用户名 SYS 在我的网站上有 16 秒的差异 从
  • 如何在Spark 1.6集群上运行用Spark 2.1组装的Spark应用程序?

    有人告诉我 我可以使用 Spark 的一个版本构建 Spark 应用程序 只要我使用sbt assembly为了构建它 我可以在任何 Spark 集群上使用 Spark Submit 运行它 因此 我使用 Spark 2 1 1 构建了简单
  • 为什么 Base64.decode 为不同的字符串生成相同的字节数组?

    我使用 URL 安全 Base64 编码来对随机生成的字节数组进行编码 但我在解码时遇到问题 当我解码两个不同的字符串 除了最后一个字符之外的所有字符都是相同的 时 它会生成相同的字节数组 例如 对于两者 dGVzdCBzdHJpbmr a
  • C# 3.0 自动属性 ​​- 是否可以添加自定义行为?

    我想知道是否有任何方法可以将自定义行为添加到自动属性获取 设置方法中 我能想到的一个明显的例子是希望每个设置属性方法都可以调用任何PropertyChanged事件处理程序作为System ComponentModel INotifyPro
  • 用户在 Python 中输入后出现“NameError:name ''未定义”[重复]

    这个问题在这里已经有答案了 我完全不明白为什么这不起作用 应该可以精确地工作 对吗 UserName input Please enter your name print Hello Mr UserName raw input
  • 设置限制的 PayloadTooLargeError

    您好 我在 Express js 方面遇到问题 我需要将 base64 文件发送到 node js 我的 configuraizone 如下所示 但是当我发送文件时 出现此错误 PayloadTooLargeError 请求实体太大 我读过
  • 现有命名空间类型的使用声明与创建类型别名

    这不是关于两者之间差异的问题using and typedef用于创建类型别名 我想提供从代码块或函数内的命名空间对现有类型的访问 我发现了两种不同的方法 我可以使用 using 声明 包含 该类型 using typename mynam
  • 如何使用 angular.js 在 DOM 中移动视图?

    如何使用 Angular JS 将元素移动到 DOM 中的不同位置 我有一个像这样的元素列表 ul li div content div li li div content div li li div content div li li d
  • 不带 http://www 的 url 正则表达式 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我需要一个 url 正则表达式来验证
  • 同时进行语音转文本和文本转语音

    介绍 我正在开发一个应用程序 我需要在其中使用 Booth SpeechRecognizer 和 TTS 但我在尝试这个时遇到了一些问题 主要的一个问题是 如果我初始化 TTS SpeechRecgonizer 似乎无法工作 而如果我禁用