Javax Sound Sampled:FloatType.Control不支持的控件类型问题

时间:2018-06-09 20:31:50

标签: java javasound

我无法将控件类型添加到java采样包中的剪辑。请参阅以下代码作为参考。

我确保在向剪辑添加控件之前调用clip.open(),但我仍然遇到同样的问题。我试图打印出剪辑的所有可用控件,我发现我没有可用的控件。 奇怪的是,这适用于其他人的机器,但我遇到了麻烦。它无法识别任何可用的FloatControl.Type,如MasterGain,Volume等。

我试图从JDK 9降级到8,因为我的朋友有8个.Java 7是最后一个JDK与JavaSound没有问题但是我很困惑为什么它可以在其他人机器上工作。 我知道我目前没有与Threads同时运行,代码需要重构。任何特定于我的问题的建议表示赞赏。

增益/音量由另一个类中的JSlider控制,这在使用changelistener打印出值时工作正常。 (问题的代码是我的代码链的非常底部)

public class AudioEngine {

    private FileManager filemanager;
    private File sound;
    private Clip clip;
    private ArrayList<File> files;
    private ArrayList<Clip> clips;
    private DataLine.Info[] lines;
    private ArrayList<AudioInputStream> streams;
    private long trackposition; // positioning of current clip to determine where in a track our play back starts from.
    private Mixer mixer;   // main mixer
    private boolean playtrigger;

    public AudioEngine() {

        filemanager = new FileManager();

        trackposition = 0;    // set initial playback to beginning of track unless it is paused....

        playtrigger = true;

        Mixer.Info[] mixInfos = AudioSystem.getMixerInfo();     // get I/O devices for set up
        for (Mixer.Info info : mixInfos) {
            System.out.println(info.getName() + " --------- " + info.getDescription());
        }


        mixer = AudioSystem.getMixer(mixInfos[0]);

        Line[] lines = mixer.getSourceLines();


    }

    /**
     * Set up the Mixer with multiple data lines, input streams, files and clips.
     */

    public void mixerSetUp(JComboBox<String> list, ArrayList<String> tracklist) throws Exception {

        files = new ArrayList<>();
        streams = new ArrayList<>();
        clips = new ArrayList<>();
        lines = new DataLine.Info[tracklist.size()];

        for (int i = 0; i < tracklist.size(); i++) {
            files.add(new File(tracklist.get(i)));
            streams.add(AudioSystem.getAudioInputStream(files.get(i)));
            lines[i] = new DataLine.Info(Clip.class, streams.get(i).getFormat());
            clips.add((Clip) AudioSystem.getLine(lines[i]));
            clips.get(i).open(streams.get(i));

        }

        System.out.println("mixer lines: " + lines.length);
        System.out.println(files.size());
        System.out.println(streams.size());
        System.out.println(clips.size());
        System.out.println(lines.length);

        Line line = mixer.getLine(lines[0]);

       Control [] controls = line.getControls();
       System.out.println(controls.length);
       for(Control control: controls) {
           System.out.println(control);
       }

    }

    /**
     * Converts our .WAV file in to an audio stream. Then we convert stream into a clip for playback.
     *
     * @param list      Our track list displayed in JComboBox (shortened version of full file path).
     * @param tracklist Our list of tracks with their full path. Plays as a Clip if selected.
     * @throws IOException
     * @throws UnsupportedAudioFileException
     * @throws LineUnavailableException
     * @throws Exception                     - More generic as all 3 of the above exceptions would have need to be thrown.
     */


    public void play(JComboBox<String> list, ArrayList<String> tracklist) throws LineUnavailableException {

        // PRESS LOAD TRACKS EVERY TIME A NEW TRACK IS ADDED

        for (Clip clip : clips) {
            if (clip != null) {
                System.out.println("Start Running");
                clip.setMicrosecondPosition(trackposition);
                clip.start();

            }
        }

    }

    /**
     * If track is running, stop the clip and set track positioning back to 0.
     */

    public void stop() {

        for (Clip clip : clips) {
            if (clip.isRunning()) {
                clip.stop();
                trackposition = 0;
            }
        }

    }

    /**
     * Set the track position when the pause button is pressed. Play back will continue from this set position once
     * user presses Play button. Track position will be set to 0 once user stops the track.
     */

    public void pause() {

        for (Clip clip : clips) {

            trackposition = clip.getMicrosecondPosition();
            clip.stop();
        }

    }

    /**
     * Iterates through all of the tracks and sets volume to value specified in parameter
     * @param value The volume for the tracks to be set to.
     */

    public void adjustVolume(int value) throws LineUnavailableException {


        if (clips != null) {
            for (Clip clip : clips) {
                FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
                gainControl.setValue((float)value);
            }
        }
    }


}

1 个答案:

答案 0 :(得分:0)

控件的存在与否取决于计算机和操作系统。您可以使用isControlSupported

测试是否支持控件

即使支持(命中或未命中)控件,它们通常也未充分实现以实现更高端的实时目的。例如,它们可能只传递缓冲区边界的变化,如果您尝试进行实时混合,可能会导致拉链效应或其他不连续性。

您可能需要编写自己的卷更改(使用SourceDataLine提供的声音数据访问)或使用执行此操作的公共库。例如,AudioCue被写成像Clip一样,但实现了实时音量,平移和频率变化。代码在github(opensource)上,如果你决定自己动手,也会让你检查如何实现它。