Java 线程,具有视觉和音频

标签 java multithreading audio lwjgl

我正在创建一个小型Java应用程序,它需要一致地连接到外围设备,A Leap Motion,然后还显示视觉反馈。我还尝试根据用户输入通过 Leap Motion 播放一系列声音...基本上只是当某个值大于最小值时,播放声音..

我特别需要帮助的是如何正确处理Java中的线程,以及如果我需要手动关闭它们......

要使用 LWJGL 启动视觉显示,我启动一个线程,如下所示:

Runnable newWindow = new ThreadedWindow();
new Thread(newWindow).start();

线程窗口类包含一个运行函数:

CreateWindow mainWindow = new CreateWindow();
mainWindow.startWindow();

startWindow 函数只是执行非常基本的 OpenGL 操作来创建一个空白窗口。我只是想知道这是否是为窗口创建和使用线程的正确方法,或者是否有其他更有效的方法来执行此操作。

public class CreateWindow {

private int windowW = 1280;
private int windowH = 720;
private int windowCentreX = windowW/2;
private int windowCentreY = windowH/2;

public void startWindow()
{
    try {
        Display.setDisplayMode(new DisplayMode(1280,720));
        Display.create();
    } catch (LWJGLException e) {
        e.printStackTrace();
        System.exit(0);
    }

    //Init OpenGL Stuff
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, 1280, 0, 720, 1, -1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

    while(!Display.isCloseRequested()) {
        //Render the OpenGL Stuff
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); 

        // set the color of the quad (R,G,B,A)
        GL11.glColor3f(0.5f,0.5f,1.0f);

        float circleRadius = 50;
        float circleX = FingerInfo.averageFingerX;
        float circleY = FingerInfo.averageFingerY;

        // draw quad
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(circleX + windowCentreX,circleY + windowCentreY);
            GL11.glVertex2f(circleX + windowCentreX + circleRadius,circleY + windowCentreY);
            GL11.glVertex2f(circleX + windowCentreX + circleRadius, circleY + windowCentreY + circleRadius);
            GL11.glVertex2f(circleX + windowCentreX,circleY + windowCentreY + circleRadius);
        GL11.glEnd();

        Display.update();
    }
    Display.destroy();
}

}

-

我创建的音频声音使用JavaX.sound.midi。使用基本的 Synth 和 MidiChannel 创建基本音调。

public static void GenerateTone(int newNote)
{
    note = newNote;
    try
    {
        Synthesizer synth = MidiSystem.getSynthesizer();
        synth.open();
        MidiChannel channel = synth.getChannels()[0];
        for(int i=0; i < 1; i++)
        {
            channel.noteOn(note, 50);
            System.out.println("Generating new tone!");

        }
    } catch (MidiUnavailableException e) { 
        e.printStackTrace();
    }
}

我确实在运行函数中调用了这个函数,该函数用于以与窗口类似的方式启动线程,但是重复播放大量声音(例如每秒 10 次)会导致声音暂停并发出大量声音嗡嗡声。这可能是一个与线程完全无关的问题,但我只是想问是否有一个在线程中播放声音的好方法。而如果我需要在声音播放后处理线程的销毁。

谢谢:D

最佳答案

developers of LWJGL themselves have specifically mentioned LWJGL 仅限于单个图形上下文,即一次不超过 1 个 OpenGL 窗口或显示器。因此,如果您启动一个线程并创建第二个 Display,则可能会发生非常不幸的事情。否则,假设您只创建该窗口线程一次,它应该完全没问题。

但是,如果您使用声音并且想要一次播放多个声音,那么既然您使用的是 LWJGL,为什么不使用 LWJGL 的 OpenAL 绑定(bind)呢? OpenAL 完全能够同时播放多个声音,无需多线程,尽管您需要录制声音才能做到这一点,但您可以在用于播放声音的函数中修改音高。

关于Java 线程,具有视觉和音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22572572/

相关文章:

javascript - 当您将鼠标悬停在javascript中的div上时如何只发出一次声音

c# - 如何使用 ContentPushStream 在 C# 中播放 block 音频?

java - 哪些操作保持顺序

java - 一些消息在 log4j 多线程应用程序中被多次记录

java - 当 JPA 中字段为 LocalDateTime 时,如何查找今天创建的每个实例?

python - 告诉消费者停止等待队列元素

java - 高负载下 Groovy Shell 解释器中的锁争用

Android MediaStore.Audio 不加载所有 MetaTags

java - 执行代码N次和其他代码N+1次

java - 无法读取 JSON : Current token (VALUE_STRING) not numeric, 无法使用数值访问器