`
i2534
  • 浏览: 182831 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java调节音量

    博客分类:
  • util
阅读更多

今天需要给mp3播放器添加音量调节功能.搜索了下,发现了以下方法,大同小异:

 

首先是 Java and Sound, Part 1 中 Playing Sounds with javax.sound提供了一个例子,贴在下面

import java.io.*;

/**
 * This class is a Swing component that can load and play a sound clip,
 * displaying progress and controls. The main( ) method is a test program. This
 * component can play sampled audio or MIDI files, but handles them differently.
 * For sampled audio, time is reported in microseconds, tracked in milliseconds
 * and displayed in seconds and tenths of seconds. For midi files time is
 * reported, tracked, and displayed in MIDI "ticks". This program does no
 * transcoding, so it can only play sound files that use the PCM encoding.
 */
public class SoundPlayer extends JComponent {
	boolean midi; // Are we playing a midi file or a sampled one?
	Sequence sequence; // The contents of a MIDI file
	Sequencer sequencer; // We play MIDI Sequences with a Sequencer
	Clip clip; // Contents of a sampled audio file
	boolean playing = false; // whether the sound is currently playing

	// Length and position of the sound are measured in milliseconds for
	// sampled sounds and MIDI "ticks" for MIDI sounds
	int audioLength; // Length of the sound.
	int audioPosition = 0; // Current position within the sound

	// The following fields are for the GUI
	JButton play; // The Play/Stop button
	JSlider progress; // Shows and sets current position in sound
	JLabel time; // Displays audioPosition as a number
	Timer timer; // Updates slider every 100 milliseconds

	// The main method just creates a SoundPlayer in a Frame and displays it
	public static void main(String[] args) throws IOException,
			UnsupportedAudioFileException, LineUnavailableException,
			MidiUnavailableException, InvalidMidiDataException {
		SoundPlayer player;

		File file = new File("F:\\music\\Dragon Dance.wav"); // This is the file we'll be playing
		// Determine whether it is midi or sampled audio
		boolean ismidi;
		try {
			// We discard the return value of this method; we just need to know
			// whether it returns successfully or throws an exception
			MidiSystem.getMidiFileFormat(file);
			ismidi = true;
		} catch (InvalidMidiDataException e) {
			ismidi = false;
		}

		// Create a SoundPlayer object to play the sound.
		player = new SoundPlayer(file, ismidi);

		// Put it in a window and play it
		JFrame f = new JFrame("SoundPlayer");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.getContentPane().add(player, "Center");
		f.pack();
		f.setVisible(true);
	}

	// Create a SoundPlayer component for the specified file.
	public SoundPlayer(File f, boolean isMidi) throws IOException,
			UnsupportedAudioFileException, LineUnavailableException,
			MidiUnavailableException, InvalidMidiDataException {
		if (isMidi) { // The file is a MIDI file
			midi = true;
			// First, get a Sequencer to play sequences of MIDI events
			// That is, to send events to a Synthesizer at the right time.
			sequencer = MidiSystem.getSequencer(); // Used to play sequences
			sequencer.open(); // Turn it on.

			// Get a Synthesizer for the Sequencer to send notes to
			Synthesizer synth = MidiSystem.getSynthesizer();
			synth.open(); // acquire whatever resources it needs

			// The Sequencer obtained above may be connected to a Synthesizer
			// by default, or it may not. Therefore, we explicitly connect it.
			Transmitter transmitter = sequencer.getTransmitter();
			Receiver receiver = synth.getReceiver();
			transmitter.setReceiver(receiver);

			// Read the sequence from the file and tell the sequencer about it
			sequence = MidiSystem.getSequence(f);
			sequencer.setSequence(sequence);
			audioLength = (int) sequence.getTickLength(); // Get sequence length
		} else { // The file is sampled audio
			midi = false;
			// Getting a Clip object for a file of sampled audio data is kind
			// of cumbersome. The following lines do what we need.
			AudioInputStream ain = AudioSystem.getAudioInputStream(f);
			try {
				DataLine.Info info = new DataLine.Info(Clip.class, ain
						.getFormat());
				clip = (Clip) AudioSystem.getLine(info);
				clip.open(ain);
			} finally { // We're done with the input stream.
				ain.close();
			}
			// Get the clip length in microseconds and convert to milliseconds
			audioLength = (int) (clip.getMicrosecondLength() / 1000);
		}

		// Now create the basic GUI
		play = new JButton("Play"); // Play/stop button
		progress = new JSlider(0, audioLength, 0); // Shows position in sound
		time = new JLabel("0"); // Shows position as a #

		// When clicked, start or stop playing the sound
		play.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (playing)
					stop();
				else
					play();
			}
		});

		// Whenever the slider value changes, first update the time label.
		// Next, if we're not already at the new position, skip to it.
		progress.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				int value = progress.getValue();
				// Update the time label
				if (midi)
					time.setText(value + "");
				else
					time.setText(value / 1000 + "." + (value % 1000) / 100);
				// If we're not already there, skip there.
				if (value != audioPosition)
					skip(value);
			}
		});

		// This timer calls the tick( ) method 10 times a second to keep
		// our slider in sync with the music.
		timer = new javax.swing.Timer(100, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				tick();
			}
		});

		// put those controls in a row
		Box row = Box.createHorizontalBox();
		row.add(play);
		row.add(progress);
		row.add(time);

		// And add them to this component.
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.add(row);

		// Now add additional controls based on the type of the sound
		if (midi)
			addMidiControls();
		else
			addSampledControls();
	}

	/** Start playing the sound at the current position */
	public void play() {
		if (midi)
			sequencer.start();
		else
			clip.start();
		timer.start();
		play.setText("Stop");
		playing = true;
	}

	/** Stop playing the sound, but retain the current position */
	public void stop() {
		timer.stop();
		if (midi)
			sequencer.stop();
		else
			clip.stop();
		play.setText("Play");
		playing = false;
	}

	/** Stop playing the sound and reset the position to 0 */
	public void reset() {
		stop();
		if (midi)
			sequencer.setTickPosition(0);
		else
			clip.setMicrosecondPosition(0);
		audioPosition = 0;
		progress.setValue(0);
	}

	/** Skip to the specified position */
	public void skip(int position) { // Called when user drags the slider
		if (position < 0 || position > audioLength)
			return;
		audioPosition = position;
		if (midi)
			sequencer.setTickPosition(position);
		else
			clip.setMicrosecondPosition(position * 1000);
		progress.setValue(position); // in case skip( ) is called from outside
	}

	/** Return the length of the sound in ms or ticks */
	public int getLength() {
		return audioLength;
	}

	// An internal method that updates the progress bar.
	// The Timer object calls it 10 times a second.
	// If the sound has finished, it resets to the beginning
	void tick() {
		if (midi && sequencer.isRunning()) {
			audioPosition = (int) sequencer.getTickPosition();
			progress.setValue(audioPosition);
		} else if (!midi && clip.isActive()) {
			audioPosition = (int) (clip.getMicrosecondPosition() / 1000);
			progress.setValue(audioPosition);
		} else
			reset();
	}

	// For sampled sounds, add sliders to control volume and balance
	void addSampledControls() {
		try {
			FloatControl gainControl = (FloatControl) clip
					.getControl(FloatControl.Type.MASTER_GAIN);
			if (gainControl != null)
				this.add(createSlider(gainControl));
		} catch (IllegalArgumentException e) {
			// If MASTER_GAIN volume control is unsupported, just skip it
		}

		try {
			// FloatControl.Type.BALANCE is probably the correct control to
			// use here, but it doesn't work for me, so I use PAN instead.
			FloatControl panControl = (FloatControl) clip
					.getControl(FloatControl.Type.PAN);
			if (panControl != null)
				this.add(createSlider(panControl));
		} catch (IllegalArgumentException e) {
		}
	}

	// Return a JSlider component to manipulate the supplied FloatControl
	// for sampled audio.
	JSlider createSlider(final FloatControl c) {
		if (c == null)
			return null;
		final JSlider s = new JSlider(0, 1000);
		final float min = c.getMinimum();
		final float max = c.getMaximum();
		final float width = max - min;
		float fval = c.getValue();
		s.setValue((int) ((fval - min) / width * 1000));

		java.util.Hashtable labels = new java.util.Hashtable(3);
		labels.put(new Integer(0), new JLabel(c.getMinLabel()));
		labels.put(new Integer(500), new JLabel(c.getMidLabel()));
		labels.put(new Integer(1000), new JLabel(c.getMaxLabel()));
		s.setLabelTable(labels);
		s.setPaintLabels(true);

		s.setBorder(new TitledBorder(c.getType().toString() + " "
				+ c.getUnits()));

		s.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				int i = s.getValue();
				float f = min + (i * width / 1000.0f);
				c.setValue(f);
			}
		});
		return s;
	}

	// For Midi files, create a JSlider to control the tempo,
	// and create JCheckBoxes to mute or solo each MIDI track.
	void addMidiControls() {
		// Add a slider to control the tempo
		final JSlider tempo = new JSlider(50, 200);
		tempo.setValue((int) (sequencer.getTempoFactor() * 100));
		tempo.setBorder(new TitledBorder("Tempo Adjustment (%)"));
		java.util.Hashtable labels = new java.util.Hashtable();
		labels.put(new Integer(50), new JLabel("50%"));
		labels.put(new Integer(100), new JLabel("100%"));
		labels.put(new Integer(200), new JLabel("200%"));
		tempo.setLabelTable(labels);
		tempo.setPaintLabels(true);
		// The event listener actually changes the tempo
		tempo.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				sequencer.setTempoFactor(tempo.getValue() / 100.0f);
			}
		});

		this.add(tempo);

		// Create rows of solo and checkboxes for each track
		Track[] tracks = sequence.getTracks();
		for (int i = 0; i < tracks.length; i++) {
			final int tracknum = i;
			// Two checkboxes per track
			final JCheckBox solo = new JCheckBox("solo");
			final JCheckBox mute = new JCheckBox("mute");
			// The listeners solo or mute the track
			solo.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					sequencer.setTrackSolo(tracknum, solo.isSelected());
				}
			});
			mute.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					sequencer.setTrackMute(tracknum, mute.isSelected());
				}
			});

			// Build up a row
			Box box = Box.createHorizontalBox();
			box.add(new JLabel("Track " + tracknum));
			box.add(Box.createHorizontalStrut(10));
			box.add(solo);
			box.add(Box.createHorizontalStrut(10));
			box.add(mute);
			box.add(Box.createHorizontalGlue());
			// And add it to this component
			this.add(box);
		}
	}
}

 接着在sun论坛上也发现了一个方法:

Java Sound - how to adjust volume level 代码如下:

AudioInputStream ain=AudioSystem.getAudioInputStream(new File(fname));        
        //fname - string
        cont=new byte[8];
        DataLine.Info info = new DataLine.Info(SourceDataLine.class,ain.getFormat());
        /*
         * built-in inner class, constructs the properties information about
         * the given file stream 
         */
        sline=(SourceDataLine)AudioSystem.getLine(info);
        // gets the source line for given audio file using its properties
        sline.open();                
        FloatControl volctrl=(FloatControl)sline.getControl(FloatControl.Type.MASTER_GAIN); 
volctrl.setValue(newVal);// newVal - the value of volume slider

 也就是说,必须开始播放,得到了播放的DataLine以后才可以得到Control信息.

我这么做了,的到

Master Gain with current value: 0.0 dB (range: -80.0 - 6.0206)

不太懂dB是怎么算的,反正默认值为0,也就是说,向正(增大音量)只能移动6个单位.对于一个JSlider来说,实在太小距离了.

不知道怎样让正负可以均匀分布,难道要判断正负,然后正的需要增大10倍来计算?

分享到:
评论

相关推荐

    android java 自定义音量键seekbar控制系统的媒体音量和通话音量,可自动实现切换

    在Android开发中,有时我们需要对系统的音量进行自定义控制,比如使用Seekbar来模拟音量调节滑块,同时能够根据不同的场景(如媒体播放、通话中)智能切换控制对应的音量。本教程将深入讲解如何实现这个功能,主要...

    用Java调用VC音量控制程序

    1. **音量调整**:修改VC程序以支持音量增减操作,并相应地调整Java端的调用逻辑。 2. **GUI界面**:设计一个简单的图形用户界面,使用户可以直观地控制音量。 3. **错误处理**:增强异常处理机制,提供更友好的错误...

    set_Volume_JMF音量调节_

    总之,JMF音量调节是通过`VolumeControl`接口实现的,它允许开发者在播放过程中动态调整音量。通过理解这个过程,开发者可以构建更复杂的多媒体应用程序,包括音量渐变、声道平衡等功能。在实际项目中,还需要考虑...

    音乐播放器之进度条控制音量大小

    在数字音频系统中,音量通常通过改变音频信号的幅度来调节。这个过程可以是线性的,也可以是指数的,因为人耳对声音的感知是非线性的,往往更敏感于较低的音量变化。在软件中,我们可以使用简单的乘法操作或使用特定...

    实例31 调节系统音量

    在VC++环境中,实例31主要讲解如何调节系统的音量,这是一个非常实用的功能,尤其对于初学者来说,有助于理解Windows API函数的使用以及系统级别的控制。在这个实例中,我们将探讨如何利用Windows API来操作音频设备...

    android设置系统音量、媒体音量Demo

    6. **调整音量** 如果需要按比例增加或减少音量,可以使用`adjustStreamVolume()`方法: ```java audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0); ``` `ADJUST_...

    Android 各种音量的获取

    ### Android各种音量的获取详解 ...这对于开发涉及音频控制的应用非常重要,尤其是在需要根据不同场景动态调整音量的应用中更是必不可少的功能之一。希望本文能帮助开发者更好地理解和运用这些技术。

    java代码-使用java解决设计与实现一个 ISoundable 接口,该接口具有发声功能、还能调节音量大小的源代码

    java代码-使用java解决设计与实现一个 ISoundable 接口,该接口具有发声功能、还能调节音量大小的源代码 ——学习参考资料:仅用于个人学习使用!

    java实现定义一个Soundable接口,该接口具有播放声音、关闭声音、增大音量、减小音量等功能。

    本文将详细讲解Java中Soundable接口的设计与实现,该接口具有播放声音、关闭声音、增大音量、减小音量等功能,并使用多种设备实现该接口,如收音机、随身听、手机等。 Soundable接口的设计 在Java中,接口是抽象...

    命令行设置电脑音量的程序

    在命令行输入.\blueVolume.exe+空格+音量值可以设置电脑音量

    Android之系统音量亮度调节

    此外,AudioManager还提供了调整音量的其他方法,如adjustStreamVolume用于微调音量。 接着,我们来看亮度调节。Android系统通过调节屏幕背光的亮度来改变显示的明暗程度。屏幕亮度的控制主要涉及到WindowManager...

    seekbar调节音量

    在`onProgressChanged`方法中,我们需要根据新的进度值`progress`来调整音量。音量的范围通常为0到100,我们可以使用`AudioManager`来设置媒体音量: ```java private void updateVolume(int progress) { ...

    设置手机音量大小

    在实际应用中,可能还需要添加用户界面元素,如滑动条,以便用户直观地调整音量。滑动条的值可以通过OnSeekBarChangeListener监听并更新到AudioManager中: ```java SeekBar volumeSeekBar = findViewById(R.id....

    基于鸿洋博客自定义View完善的一个调节音量的自定义控件

    通过阅读提供的压缩包文件(如`CustomVolumeSeekBar.java`或类似命名的源代码文件),我们可以深入理解实现细节,如如何处理滑动事件、如何更新音量、如何绘制UI以及如何自定义属性等。同时,查看示例布局文件(如`...

    Android SeekBar调节音量

    在这个场景中,我们关注的是如何利用SeekBar来调节系统的音量。这个功能在很多应用程序中都有所应用,比如音乐播放器、视频应用等,用户可以通过滑动SeekBar直观地调整音量大小。 首先,我们要了解Android中的音量...

    Android实现音量调节的方法

    以下将详细阐述如何在Android中实现音量调节,包括页面布局和多媒体播放的设置技巧。 首先,我们需要创建一个UI界面来展示音量调节的控件。在提供的`main.xml`布局文件中,可以看到三个关键组件: 1. `...

    android设置系统亮度、音量

    首先,让我们来看看如何调整系统亮度。在Android中,可以通过访问`Settings.System`类来更改屏幕亮度。以下是一个简单的示例代码: ```java // 获取系统亮度的当前值 int brightness = Settings.System.getInt...

    Android实现手机音量最大值限制

    这样的功能在很多场景下都非常实用,比如避免小孩子过度调整音量导致听力损伤,或者在公共场合防止突然的高音量打扰他人。在本案例中,"Android实现手机音量最大值限制"是一个应用程序,它允许用户设置一个特定的...

    android自定义音量调节

    本文将深入探讨如何实现"android自定义音量调节",主要涉及以下几个方面:自定义SeekBar、音量管理以及界面美化。 首先,`SeekBar`是Android系统提供的一个滑动条组件,常用于用户进行数值选择或进度调整。在音量...

    Android 自定义View (四) 视频音量调控

    3. **手势识别**:通过监听MotionEvent.ACTION_DOWN、ACTION_MOVE和ACTION_UP事件,我们可以捕捉到用户的滑动操作,然后根据滑动距离调整音量。 4. **动画效果**:为了提供更好的用户体验,可以添加平滑的动画效果...

Global site tag (gtag.js) - Google Analytics