首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用JAVA控制soundCard

用JAVA控制soundCard
EN

Stack Overflow用户
提问于 2015-12-20 10:13:44
回答 2查看 726关注 0票数 0

我正试图用JAVA构建一个“混合控制台”。在这个混合器中,每个“滑块”都是一条线,就好像它是一个物理混合控制台。但是,在我搜索Goo*并阅读了oracle文档之后,我并没有真正找到任何可以帮助我的东西。

首先,我列出了可用的混音器(参见末尾的代码),并高兴地列出了我的所有声卡,并找到了行和行。但我该怎么做?

我的目标是创建“虚拟线”,将捕捉声音从任何线(麦克风)或线外(捕捉声音播放的VLC),允许我“工作”,然后,再弹出它在另一行。当然,我必须为每一行设置"in“和"out”的用法:

  • (麦克风)中的3条物理线将被捕捉,然后“水平调整”然后再注入到一条被称为“合唱”的虚拟线中,而这条虚拟线将在我的主物理线中重新注入,称为“主电平”。
  • 由VLC (例如歌曲的旋律)播放的歌曲通常直接发送到主"out“,就像”截取“一样,然后我决定在将其弹回我的主人并与麦克风混合之前设置这个级别,这样我就可以根据音乐水平来调整歌手的级别了。

那么,谁能帮我开始和进步呢?谢谢你的帮助。

下面是列出我的混频器的代码:

代码语言:javascript
复制
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Control;
import javax.sound.sampled.Line;
import javax.sound.sampled.Mixer;

public class Mixers {

Mixers() {      
    try {
        //List of the mixers from the system
        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
        //Characteristics of each mixer
        for (Mixer.Info info : mixerInfo) {
            System.out.println("\n"+info+ " - Description : "+info.getDescription());
            Mixer mix=AudioSystem.getMixer(info);

            //Controles available for this mixer
            for (Control c:mix.getControls()) {
                System.out.println ("\t Control supported by this mixer : "+c);
            }
            //Sources available for this mixer
            for (Line.Info i : mix.getSourceLineInfo()) {
                System.out.println("\t Source line available : "+i);

                //Controls available for this Source
                for (Control c : AudioSystem.getLine(i).getControls()) {
                    System.out.println ("\t\t ==> Controls supported by this source : "+c);
                }
            }
            // TargeLines available for this mixer
            for (Line.Info i : mix.getTargetLineInfo()) {
                System.out.println("\t Target line available : "+i);

                //Controls available for this Target
                for (Control c : AudioSystem.getLine(i).getControls()) {
                    System.out.println ("\t\t Controls supported by this target : "+c);
                }
            }               
        }
    } catch (Exception e) {
        e.printStackTrace();
    }               
}

}

再次感谢任何人阅读我的帖子,直到结束,并给我一个解决方案的开始。

尼古拉斯

EN

回答 2

Stack Overflow用户

发布于 2015-12-20 21:48:18

如果可以这样做,我认为下一步您想要的是能够从不同的混频器中读取数据,并在“每帧”的基础上执行操作。Java教程捕捉音频是指从外部行读取数据。教程使用文件和格式转换器有示例代码,演示如何获取各个框架。在标题“读取声音文件”下是这方面的示例代码。最重要的一点是以下评论:

代码语言:javascript
复制
// Here, do something useful with the audio data that's 
// now in the audioBytes array...

在您的示例中,您将有多个auiodBytes数组,每个输入行都有一个。

为了混合,可以将来自不同行的PCM帧数据相加在一起。行之间的音量控制可以通过使用乘法器来完成,例如,从0(沉默)到1(全音量)之间的因子。

必须注意不要在单个帧中过多地改变乘数,否则数据中引入的不连续性会导致单击。因此,将任何更改分散到多个帧上。线性变化的乘法器不完全匹配听到的音频水平。我认为三次指数分布通常用于线性值和等效乘数之间的转换,这听起来像那些值。您可能需要添加min和max函数,以确保PCM数据不会超出范围-1和1。这一段的大部分内容是关于细微的混合点,对于什么是最佳实践有不同的意见。

还有其他关于堆栈溢出的文章,它们告诉我们如何将字节流格式转换为PCM和back。据我所知,javax.sound.sampled是这段代码的源代码,非常依赖于本地代码,而且级别很低。尽管我依赖于自己的数据源,而不是像您试图做的那样依赖于外部行,但我仍然能够以这种方式进行大量的混合。我不知道这些外线是如何管理的,特别是如果你想让你的电脑不播放它们,而你正在播放你的结果组合。

票数 1
EN

Stack Overflow用户

发布于 2015-12-20 11:14:11

我不确定java声音API是否能做到这一点。您可能应该查看一个低得多的API,例如OpenAL (Java有绑定),它提供了对声音流的更多控制。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34379912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档