爪哇岛。LineUnavailableException、狮身人面像 API、Maven

Java. LineUnavailableException, Sphinx API, Maven

提问人:Коля 提问时间:6/14/2023 最后编辑:mzjnКоля 更新时间:6/14/2023 访问量:28

问:

当我运行应用程序时,它最初在 InitForm 上,一切正常。当我移动到另一个选项卡时,一切都很好,但是一旦我使用 InitForm 单击选项卡,一切都会挂起,然后在一段时间后挂起并抛出异常(下面的文本)。我一定搞砸了流或狮身人面像的侦听器创建,但我不知道如何解决它,我尝试了不同的组合,但没有任何帮助,我按主题发送代码: 异常文本:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported.
    at edu.cmu.sphinx.api.Microphone.<init>(Microphone.java:38)
    at edu.cmu.sphinx.api.SpeechSourceProvider.getMicrophone(SpeechSourceProvider.java:18)
    at edu.cmu.sphinx.api.LiveSpeechRecognizer.<init>(LiveSpeechRecognizer.java:35)
    at com.nickmegistone.ai.VoiceAssistant.<init>(VoiceAssistant.java:42)
    at com.nickmegistone.form.InitForm.<init>(InitForm.java:21)
    at com.nickmegistone.vocaliamaven.VocaliaMaven.lambda$new$0(VocaliaMaven.java:24)
    at com.nickmegistone.component.Menu.lambda$addMenu$0(Menu.java:48)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6620)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3398)
    at java.desktop/java.awt.Component.processEvent(Component.java:6385)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4995)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported.
    at java.desktop/com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:484)
    at java.desktop/com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:115)
    at java.desktop/com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:357)
    at edu.cmu.sphinx.api.Microphone.<init>(Microphone.java:36)
    ... 42 more

initForm 类:

package com.nickmegistone.form;

import com.nickmegistone.ai.MCNPLNN;
import com.nickmegistone.ai.VoiceAssistant;

import javax.swing.*;
import java.awt.event.KeyEvent;

public class InitForm extends javax.swing.JPanel {

    private final VoiceAssistant va;
    private final MCNPLNN MCModel;
    private boolean label3IsEnabled;
    private Thread recognitionThread;

    public InitForm() {
        label3IsEnabled = false;
        initComponents();
        MCModel = new MCNPLNN("mctext.txt", 4);
        setOpaque(false);
        va = new VoiceAssistant("dict.dic", "language-model.lm");
        recognitionThread = new Thread(() -> {
            synchronized (va) {
                va.startRecognizing();
                while (!recognitionThread.isInterrupted()) {
                    if (!label3IsEnabled) {
                        try {
                            va.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    handleCommand(va.getCommand());
                }
            }
        });
        recognitionThread.start();
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        ... Maven auto-generated code like colors, jpanels etc ...
    }// </editor-fold>//GEN-END:initComponents

    private void searchMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_searchMouseClicked
        System.out.println(evt);
        search.setEnabled(true);
        search.setText("");
    }//GEN-LAST:event_searchMouseClicked

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
        System.out.println(evt);
        search.setEnabled(false);
    }//GEN-LAST:event_formMouseClicked

    private void searchKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_searchKeyPressed
        System.out.println(evt);
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            handleCommand(search.getText());
        }
    }//GEN-LAST:event_searchKeyPressed

    private void jLabel4MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel4MouseClicked
        System.out.println(evt);
        handleCommand(search.getText());
    }//GEN-LAST:event_jLabel4MouseClicked

    private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel3MouseClicked
        System.out.println(evt);
        label3IsEnabled = !label3IsEnabled;
         {
            synchronized (va) {
                if (label3IsEnabled) va.notify();
            }
        }
    }//GEN-LAST:event_jLabel3MouseClicked

    private void handleCommand(String searchQuery) {
        int code = va.getCode(searchQuery);
        if (code != -1) {
            search.setText(searchQuery);
        } else {
            search.setText("I don't understand your command!");
            va.playMP3("farewell.mp3");
        }
        switch (code) {
            case 0 -> handlePlayMusicCommand();
            case 1 -> handleTellJokeCommand();
            case 2 -> handleWeatherForecastCommand();
            case 3 -> handleSearchCommand(searchQuery);
            case 4 -> handleTranslationCommand(searchQuery);
            case 5 -> handleGreetingsCommand();
            case 6 -> handleExitCommand();
            default -> handleUnknownCommand(searchQuery);
        }
    }

    public void handlePlayMusicCommand() {
        ...cmd execution...
    }

    public void handleTellJokeCommand() {
        System.out.println(MCModel.getSentence(5, "okay heres the joke"));
    }

    public void handleWeatherForecastCommand() {
        ...cmd execution...
    }

    public void handleSearchCommand(String searchQuery) {
        ...cmd execution...
    }

    public void handleTranslationCommand(String searchQuery) {
       ...cmd execution...
    }

    public void handleGreetingsCommand() {
        va.startRecognizing();
    }

    public void handleExitCommand() {
        if (va.isRecognizing()) {
            va.stopRecognizing();
        }
        recognitionThread.interrupt();
        System.exit(0);
    }

    public void handleUnknownCommand(String searchQuery) {
        System.err.printf("Command not found: %s...%n", searchQuery);
        search.setEnabled(false);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JTextField search;
    // End of variables declaration//GEN-END:variables
}

VoiceAssistant 类:

/*
 * Click nbfs:\\nbhost\\SystemFileSystem\\Templates\\Licenses\\license-default.txt to change this license
 * Click nbfs:\\nbhost\\SystemFileSystem\\Templates\\Classes\\Class.java to edit this template
 */
package com.nickmegistone.ai;

import edu.cmu.sphinx.api.Configuration;
import edu.cmu.sphinx.api.LiveSpeechRecognizer;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.advanced.AdvancedPlayer;
import org.jetbrains.annotations.NotNull;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * This class represents a voice assistant that can perform various tasks based on voice commands.
 *
 * @author Mykyta Kyselov - <a href="https://github.com/TheMegistone4Ever">Github</a>
 */
public class VoiceAssistant {

    private final LiveSpeechRecognizer lsr;
    private boolean isRecognizing;

    /**
     * Constructs a VoiceAssistant object with the specified parameters.
     *
     * @param dictFilename   A string representing the filename of the dictionary for speech recognition.
     * @param LMFilename     A string representing the filename of the language model for speech recognition.
     */
    public VoiceAssistant(String dictFilename, String LMFilename) {
        isRecognizing = false;
        Configuration config = new Configuration();
        config.setAcousticModelPath(
                String.format("resource:%s", "/edu/cmu/sphinx/models/en-us/en-us"));
        config.setDictionaryPath(
                String.format("file:%s/src/main/java/com/nickmegistone/resources/%s", System.getProperty("user.dir"), dictFilename));
        config.setLanguageModelPath(
                String.format("file:%s/src/main/java/com/nickmegistone/resources/%s", System.getProperty("user.dir"), LMFilename));
        try {
            lsr = new LiveSpeechRecognizer(config);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Retrieves the command from the voice recognition result.
     *
     * @return The command extracted from the voice recognition result, converted to lowercase.
     */
    public String getCommand() {
        return lsr.getResult().getHypothesis().toLowerCase();
    }

    /**
     * Retrieves the code corresponding to the given voice command.
     *
     * @param voiceCommand The voice command to be checked for code mapping.
     * @return The code associated with the voice command. Returns -1 if no matching code is found.
     */
    public int getCode(String voiceCommand) {
        if (voiceCommand.contains("play music")) {
            return 0;
        } else if (voiceCommand.contains("tell me a joke")) {
            return 1;
        } else if (voiceCommand.contains("weather forecast")) {
            return 2;
        } else if (voiceCommand.contains("search for")) {
            return 3;
        } else if (voiceCommand.contains("translate")) {
            return 4;
        } else if (voiceCommand.contains("hey vocalia")) {
            return 5;
        } else if (voiceCommand.contains("bye vocalia")) {
            return 6;
        }
        return -1;
    }

    /**
     * Checks if the voice recognition system is currently in the process of recognizing speech.
     *
     * @return true if the voice recognition system is currently recognizing speech, false otherwise.
     */
    public boolean isRecognizing() {
        return isRecognizing;
    }

    /**
     * Starts the speech recognition process.
     */
    public void startRecognizing() {
        isRecognizing = true;
        lsr.startRecognition(true);
        playMP3("greetings.mp3");
    }

    /**
     * Stops the speech recognition process.
     */
    public void stopRecognizing() {
        isRecognizing = false;
        lsr.stopRecognition();
        playMP3("farewell.mp3");
    }

    /**
     * Executes a command in the command prompt.
     *
     * @param command       A string representing the command to be executed.
     */
    public void cmdExec(String command) {
        try {
            Runtime.getRuntime().exec(new String[]{"cmd", "/c", command});
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Retrieves the substring after a specified search term in a given input string.
     *
     * @param input         The input string to search within.
     * @param searchTerm    The search term to find the substring after.
     * @return              The substring after the search term.
     */
    public @NotNull String getSubstringAfter(@NotNull String input, String searchTerm) {
        if (input.length() <= searchTerm.length()) return input;
        return input
                .substring(input.indexOf(searchTerm) + searchTerm.length())
                .trim()
                .replaceAll("\\s", "%20");
    }

    /**
     * Plays an MP3 file.
     *
     * @param filename   A string representing the filename of the MP3 file to be played.
     */
    public void playMP3(String filename) {
        try (FileInputStream in = new FileInputStream(String.format("%s/src/main/java/com/nickmegistone/resources/%s", System.getProperty("user.dir"), filename))) {
            new AdvancedPlayer(in).play();
        } catch (IOException | JavaLayerException e) {
            throw new RuntimeException(e);
        }
    }
}

主类:

package com.nickmegistone.vocaliamaven;

import com.nickmegistone.event.EventMenu;
import com.nickmegistone.form.Form;
import com.nickmegistone.form.InitForm;
import javazoom.jl.decoder.JavaLayerException;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.IOException;

public class VocaliaMaven extends javax.swing.JFrame {

    private int mouseX, mouseY;
    private boolean isFullScreen = false;
    
    public VocaliaMaven() throws IOException, JavaLayerException {
        initComponents();
        setBackground(new Color(0, 0, 0, 0));
        EventMenu event = index -> {
            if (index == 0) {
                showForm(new InitForm());
            } else {
                showForm(new Form(index));
            }
        };
        menu1.initMenu(event);
        showForm(new InitForm());
    }

    private void showForm(Component com) {
        body.removeAll();
        body.add(com);
        body.revalidate();
        body.repaint();
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
              ... Maven auto-generated code like colors, jpanels etc ...
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jButton1ActionPerformed

    private void roundPanel1MouseDragged(@NotNull MouseEvent evt) {//GEN-FIRST:event_roundPanel1MouseDragged
        this.setLocation(evt.getXOnScreen() - mouseX, evt.getYOnScreen() - mouseY);
    }//GEN-LAST:event_roundPanel1MouseDragged

    private void roundPanel1MousePressed(@NotNull MouseEvent evt) {//GEN-FIRST:event_roundPanel1MousePressed
        mouseX = evt.getX();
        mouseY = evt.getY();
    }//GEN-LAST:event_roundPanel1MousePressed

    private void roundPanel1MouseClicked(@NotNull MouseEvent evt) {//GEN-FIRST:event_roundPanel1MouseClicked
        if (evt.getClickCount() > 1) {
            GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
            if (isFullScreen) {
                // Exit full screen mode
                device.setFullScreenWindow(null);
                isFullScreen = false;
            } else {
                // Enter full screen mode
                device.setFullScreenWindow(this);
                isFullScreen = true;
            }
        }
    }//GEN-LAST:event_roundPanel1MouseClicked

    public static void main(String[] args) {
        /* Set the Nimbus look and feel */
        //<edit

or-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException |
                 UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(VocaliaMaven.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(() -> {
            VocaliaMaven vocalia;
            try {
                vocalia = new VocaliaMaven();
            } catch (IOException | JavaLayerException e) {
                throw new RuntimeException(e);
            }
            vocalia.setIconImage(new ImageIcon(System.getProperty("user.dir") + "/src/main/java/com/nickmegistone/resources/logo.png").getImage());
            vocalia.setVisible(true);
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel body;
    private com.nickmegistone.component.Menu menu1;
    // End of variables declaration//GEN-END:variables
}

在此处输入图像描述[在此处输入图像描述](https://i.stack.imgur.com/RDI[在此处输入图像描述](https://i.stack.imgur.com/fwTqZ.png)g8.png)

我试图从代码中删除并行线程,但一切都没有呈现并挂起,因为整个程序现在正忙于语音识别。 接下来,我尝试删除同步,一切正常,但只抛出该异常,然后再次恢复工作,但始终识别出我不需要的内容。

当您单击按钮时,我需要它,如果识别已经开始(如果是第一次)或结束,相反,如果已经打开,则结束。我想过简单地使用等待通知技术来做到这一点,但出了点问题。

Java 多线程 异常 cmusphinx

评论


答: 暂无答案