Java声音类不循环[关闭]

Posted

技术标签:

【中文标题】Java声音类不循环[关闭]【英文标题】:Java sound class not looping [closed] 【发布时间】:2013-01-24 21:18:49 【问题描述】:

我正在尝试开发一款游戏,但我找到了 2 个声音来源。

我在下面发布了整个课程,即使 looped_foreverloop_times 设置为这样做,它似乎也不会循环:

package com.jayitinc.ponygame;

import java.io.*;

import javax.sound.sampled.*;

public class Sound

Thread t;
String read;
String name;

AudioInputStream stream = null;
AudioFormat format = null;

// New sound, the String it it's location relative to your project folder.
// I suggest you add a class folder in the project properties to access the
// files from there.
public Sound(String read, String name)

    sound = new File("sound/" + read);
    try
    
        stream = Audiosystem.getAudioInputStream(sound);
     catch (Exception e)
    
        e.printStackTrace();
    
    format = stream.getFormat();
    this.name = name;


// New sound with set volume
public Sound(String read, float volume, String name)

    this(read, name);
    setVolume(volume);
    try
    
        stream = AudioSystem.getAudioInputStream(sound);
     catch (Exception e)
    
        // TODO Auto-generated catch block
        e.printStackTrace();
    
    format = stream.getFormat();


public void play()

    t = new Thread(play);
    // Write you own file location here and be aware that it need to be an
    // .wav file
    t.start();


// ONLY USE IF YOU HAVE STARTED THE THREAD FIRST
public void stop()

    // stops the sound thread from playing
    t.stop();


// Just in case you would like to change it
public void setVolume(float volume)

    this.volume = volume;


File sound;
boolean muted = false; // This should explain itself
float volume = 100.0f; // This is the volume that goes from 0 to 100
float pan = 0.0f; // The balance between the speakers 0 is both sides and it
                    // goes from -1 to 1
boolean isPlaying;

double seconds = 0.0d; // The amount of seconds to wait before the sound
                        // starts playing

boolean looped_forever = false; // It will keep looping forever if this is
                                // true

int loop_times = 0; // Set the amount of extra times you want the sound to
                    // loop (you don't need to have looped_forever set to
                    // true)
int loops_done = 0; // When the program is running this is counting the
                    // times the sound has looped so it knows when to stop

// The rest of this is pretty complicated, you don't need to bother with it.

final Runnable play = new Runnable() // This Thread/Runnable is for playing
                                        // the sound

    public void run()
    
        try
        
            // Check if the audio file is a .wav file
            if (sound.getName().toLowerCase().contains(".wav"))
            

                if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED)
                
                    format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), format.getSampleSizeInBits() * 2, format.getChannels(), format.getFrameSize() * 2, format.getFrameRate(), true);

                    stream = AudioSystem.getAudioInputStream(format, stream);
                

                SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, stream.getFormat(), (int) (stream.getFrameLength() * format.getFrameSize()));

                SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(stream.getFormat());
                line.start();

                // Set Volume
                FloatControl volume_control = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
                volume_control.setValue((float) (Math.log(volume / 100.0f) / Math.log(10.0f) * 20.0f));

                // Mute
                BooleanControl mute_control = (BooleanControl) line.getControl(BooleanControl.Type.MUTE);
                mute_control.setValue(muted);

                FloatControl pan_control = (FloatControl) line.getControl(FloatControl.Type.PAN);
                pan_control.setValue(pan);

                int num_read = 0;
                byte[] buf = new byte[line.getBufferSize()];

                while ((num_read = stream.read(buf, 0, buf.length)) >= 0)
                
                    int offset = 0;

                    while (offset < num_read)
                    
                        offset += line.write(buf, offset, num_read - offset);
                    
                

                line.drain();
                line.stop();

                if (looped_forever)
                
                    new Thread(play).start();
                 else if (loops_done < loop_times)
                
                    loops_done++;
                    new Thread(play).start();
                
            
         catch (Exception ex)
        
            ex.printStackTrace();
        
    
;
public int getLength()

    long audioFileLength = sound.length();
    int frameSize = format.getFrameSize();
    float frameRate = format.getFrameRate();
    float durationInSeconds = (audioFileLength / (frameSize * frameRate));
    return (int) durationInSeconds;


public void setPan(float pan)

    this.pan = pan;


public float getPan()

    return pan;


public void setLoop(boolean loop)

    looped_forever = loop;


public boolean getLoop()

    return looped_forever;


public String getName()

    return name;


public void setName(String name)

    this.name = name;


编辑:我需要能够控制音量,所以如果你有其他课程,请确保它可以控制音量!

【问题讨论】:

您尝试过使用调试器吗? 为什么要每次都重新启动一个新线程,而不是多次将数据流发送到音频输出?这比它需要的复杂得多。 哇,有将近 200 行损坏的代码来循环声音! Java Sound tag Wiki 显示了仅在 24 LOC 中成功循环声音的代码。试试那个代码。 我没有编写这个代码,实际上我确实更改了那部分代码,但看看它是否有效。原来是: if (looped_forever) new Thread(play).start(); else if (loops_done @AndrewThompson 我以前也有过类似的东西,但是你如何控制音量? 【参考方案1】:

(re Clip) ..你如何控制音量?

试试Java Sound tag Wiki 上看到的代码变体。

import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.event.*;

public class VolumeControl 

    public static void main(String[] args) throws Exception 
        URL url = new URL(
            "http://pscode.org/media/leftright.wav");
        Clip clip = AudioSystem.getClip();
        // getAudioInputStream() also accepts a File or InputStream
        AudioInputStream ais = AudioSystem.
            getAudioInputStream( url );
        clip.open(ais);
        Control[] c = clip.getControls();
        FloatControl temp = null;
        for (Control control : c) 
            System.out.println(control);
            if (control.toString().toLowerCase().contains("master gain")) 
                // we found it!
                temp = (FloatControl)control;
            
        
        final FloatControl vol = temp;
        clip.loop(Clip.LOOP_CONTINUOUSLY);
        SwingUtilities.invokeLater(new Runnable() 
            public void run() 
                JComponent c = null;
                if (vol!=null) 
                    final JSlider volControl = new JSlider(
                            (int)(100*vol.getMinimum()),
                            (int)(100*vol.getMaximum()),
                            (int)(100*vol.getValue())
                            );
                    ChangeListener cl = new ChangeListener() 

                        @Override
                        public void stateChanged(ChangeEvent e) 
                            System.out.println( "Vol: " + volControl.getValue()/100f );
                            vol.setValue(volControl.getValue()/100f);
                        
                    ;
                    volControl.addChangeListener(cl);
                    c = volControl;
                 else 
                    c = new JLabel("Close to exit!");
                
                JOptionPane.showMessageDialog(null, c);
            
        );
    

【讨论】:

以上是关于Java声音类不循环[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

比较Java中的两个声音(有容差)[关闭]

使用 Javascript 的声音 HTML? [关闭]

向Java程序添加音频[关闭]

如何向我的 Java JFrame 添加一些声音? [关闭]

Android,Soundpool 类 - 循环声音时出现自动暂停问题

使用 Java 进行音频操作 [关闭]