Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将音乐淡入新的轨道?_Java_Audio_Javasound - Fatal编程技术网

Java 将音乐淡入新的轨道?

Java 将音乐淡入新的轨道?,java,audio,javasound,Java,Audio,Javasound,我已经开始用Java做一个基本的游戏 一切都进行得很顺利,我有地图加载,绘图工作很好等 我让它为地图播放音乐,为碰撞之类的东西播放音效 然而,我觉得来自地图A(我要离开的那个)的音乐应该淡入地图B(我要进入的地图)的音乐,这可能吗 我用来播放音乐的代码如下: try { if(clip != null) { clip.stop(); clip.close(); } c

我已经开始用Java做一个基本的游戏

一切都进行得很顺利,我有地图加载,绘图工作很好等

我让它为地图播放音乐,为碰撞之类的东西播放音效

然而,我觉得来自地图A(我要离开的那个)的音乐应该淡入地图B(我要进入的地图)的音乐,这可能吗

我用来播放音乐的代码如下:

    try
    {
        if(clip != null)
        {
            clip.stop();
            clip.close();
        }

        clip = AudioSystem.getClip();

        URL a = this.getClass().getResource("/resource/sound/"+Filename + ".mid");

        ais = AudioSystem.getAudioInputStream(a);

        clip.open(ais);
        clip.loop(999);
        clip.start();
    }
    catch(Exception e)
    {

    }
private Boolean _SwapMusic = false;
private String _Filename;
Thread soundThread;

    Runnable r1 = new Runnable() {
      public void run() {
        while(true)
        {
            if(_SwapMusic)
            {
                _SwapMusic = false;
                try
                {
                    //Try to lower volume
                    for (int i = 0; i < 80; i ++) {
                        FloatControl gainControlA = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                           gainControlA.setValue(i * -1f);
                        Thread.sleep(10);
                    }
                }
                catch(Exception e){ System.out.print("Lower volume error: " + e + " ");}


                try{
                    clip.stop();
                    clip.close();
                }
                catch (Exception e) { System.out.print("clip.stop/close error: " + e + " ");}
                try
                {
                    clip = AudioSystem.getClip();

                    URL a = this.getClass().getResource("/resource/sound/"+ _Filename + ".mid");

                    ais = AudioSystem.getAudioInputStream(a);

                    clip.open(ais);

                    FloatControl gainControlB = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                    gainControlB.setValue(-80f);

                    clip.loop(999);
                    clip.start();
                }
                catch(Exception e){ System.out.print("Play error: " + e + " ");}


                try
                {
                    //Try to higher volume
                    for (int i = -80; i < 0; i ++) {
                        FloatControl gainControlC = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                           gainControlC.setValue(i);
                        Thread.sleep(3);
                    }
                }
                catch(Exception e){ 
                System.out.print("Higher volume error: " + e + " ");
                }
            }         
        }
      }
    };

正如你可能看到的那样,我对Java不是很在行,但我的游戏到目前为止进展顺利,我不是,我拒绝使用“引擎”,因为我想要完全控制

有什么想法吗

谢谢

编辑:

谢谢你的回答,我已经修改了你给我的代码,但它不起作用=/

我现在制作了下面的代码,它在一个新的线程上运行(因此是可运行的),这样音乐在播放时就会消失

代码如下:

    try
    {
        if(clip != null)
        {
            clip.stop();
            clip.close();
        }

        clip = AudioSystem.getClip();

        URL a = this.getClass().getResource("/resource/sound/"+Filename + ".mid");

        ais = AudioSystem.getAudioInputStream(a);

        clip.open(ais);
        clip.loop(999);
        clip.start();
    }
    catch(Exception e)
    {

    }
private Boolean _SwapMusic = false;
private String _Filename;
Thread soundThread;

    Runnable r1 = new Runnable() {
      public void run() {
        while(true)
        {
            if(_SwapMusic)
            {
                _SwapMusic = false;
                try
                {
                    //Try to lower volume
                    for (int i = 0; i < 80; i ++) {
                        FloatControl gainControlA = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                           gainControlA.setValue(i * -1f);
                        Thread.sleep(10);
                    }
                }
                catch(Exception e){ System.out.print("Lower volume error: " + e + " ");}


                try{
                    clip.stop();
                    clip.close();
                }
                catch (Exception e) { System.out.print("clip.stop/close error: " + e + " ");}
                try
                {
                    clip = AudioSystem.getClip();

                    URL a = this.getClass().getResource("/resource/sound/"+ _Filename + ".mid");

                    ais = AudioSystem.getAudioInputStream(a);

                    clip.open(ais);

                    FloatControl gainControlB = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                    gainControlB.setValue(-80f);

                    clip.loop(999);
                    clip.start();
                }
                catch(Exception e){ System.out.print("Play error: " + e + " ");}


                try
                {
                    //Try to higher volume
                    for (int i = -80; i < 0; i ++) {
                        FloatControl gainControlC = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                           gainControlC.setValue(i);
                        Thread.sleep(3);
                    }
                }
                catch(Exception e){ 
                System.out.print("Higher volume error: " + e + " ");
                }
            }         
        }
      }
    };
private Boolean\u SwapMusic=false;
私有字符串\u文件名;
线声线;
Runnable r1=新的Runnable(){
公开募捐{
while(true)
{
如果(_SwapMusic)
{
_SwapMusic=假;
尝试
{
//尽量降低音量
对于(int i=0;i<80;i++){
FloatControl增益控件=(FloatControl)clip.getControl(FloatControl.Type.MASTER\u增益);
增益控制设定值(i*-1f);
睡眠(10);
}
}
catch(异常e){System.out.print(“低音量错误:“+e+”);}
试一试{
clip.stop();
clip.close();
}
catch(异常e){System.out.print(“clip.stop/close错误:“+e+”);}
尝试
{
clip=AudioSystem.getClip();
URL a=this.getClass().getResource(“/resource/sound/”+_Filename+”.mid”);
ais=AudioSystem.getAudioInputStream(a);
夹子。打开(ais);
FloatControl增益controllb=(FloatControl)clip.getControl(FloatControl.Type.MASTER\u增益);
增益控制设定值(-80f);
夹环(999);
clip.start();
}
catch(异常e){System.out.print(“播放错误:+e+”);}
尝试
{
//尽量提高音量
对于(int i=-80;i<0;i++){
FloatControl-gainControlC=(FloatControl)clip.getControl(FloatControl.Type.MASTER\u-GAIN);
增益控制设定值(i);
睡眠(3);
}
}
捕获(例外e){
系统输出打印(“较大音量错误:+e+”);
}
}         
}
}
};
为了弄清楚这一点,我正试图让地图A的音乐在地图B的音乐开始之前完全消失


感谢迄今为止的所有帮助。

Ryuk,为什么不在开始播放下一个剪辑时,将音量调大,将剪辑从离开的级别淡出呢

您必须原谅我,我不是100%确定您使用的是什么库,但是clip对象肯定有一个.adjustVolume()方法

要随时间调整音量,它看起来像:(psuedo代码提醒您)


您可以使用
MASTER_GAIN
控件降低第一个片段的声音,同时提高第二个片段的声音,您可能需要播放分贝和计时,但这应该可以:

Clip clipA = AudioSystem.getClip();
Clip clipB = AudioSystem.getClip();
clipA.open(aisA);
clipB.open(aisB);

for (int i = 0; i < 100; i ++) {
   FloatControl gainControlA = (FloatControl) clipA.getControl(FloatControl.Type.MASTER_GAIN);
   gainControlA.setValue(i * -1f);
   FloatControl gainControlB = (FloatControl) clipB.getControl(FloatControl.Type.MASTER_GAIN);
   gainControlB.setValue(-100f + i);

   Thread.sleep(100);
}
Clip clipA=AudioSystem.getClip();
Clip clipB=AudioSystem.getClip();
克利帕公开赛(aisA);
clipB.open(aisB);
对于(int i=0;i<100;i++){
FloatControl增益控制=(FloatControl)clipA.getControl(FloatControl.Type.MASTER\u增益);
增益控制设定值(i*-1f);
FloatControl增益controllb=(FloatControl)clipB.getControl(FloatControl.Type.MASTER\u增益);
增益控制设定值(-100f+i);
睡眠(100);
}

这与其说是一个答案,还不如说是添加了一些可能有用的信息,而这些信息在评论中并不合适

是的,-80到6.0有点时髦。我认为,它应该在舷外混音器上复制分贝。但到耳朵的斜率几乎不是线性的。如果我没记错的话,当你降到-20时,声音可能已经听不见了。在这和试图在体积变化中实现实时精度的性能问题之间,我放弃了使用控制线,开始直接处理PCM数据。但我不建议你在这种情况下这么做

为了使控件的数字范围更加均匀,可以映射某种指数或三角函数。我不知道最佳拟合,但通过以下两个函数,我得到了有用的结果

对于PCM数据,我一直在使用标准化为0到1范围的音量。下面是一些我一直在使用的函数示例

newValue = 1 - Math.cos(NormalizedPCMValue * PI/2)

newValue = Math.pow(NormalizedPCMValue, 6) 

newValue = Math.pow(2, NormalizedPCMValue)
这些对我来说都比直线更有效。我正在使用查找表,但您可能可以动态计算值。如果你得到了一个非常好用的映射函数,我很乐意在这里听到


顺便说一句,最好将控制行值降到范围的底部。突然切断声音,即使是在安静的情况下,或者在音量变化中跳跃很长的距离,都会导致不连续,表现为可听见的咔哒声。

“我拒绝使用‘引擎’,因为我想要完全控制”——这似乎有点骄傲,你不觉得吗?可能是塔尔文,但这是一种非常好的学习方式。我更喜欢用这种方式学习……我同意@Chad M:学习的可能翻版。但是,毫无理由地要求绝对控制你的代码是毫无意义的