Critical Security.NET: Java Sound - Critical Security.NET

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Java Sound

#1 Guest_PhatCat_*

  • Group: Guests

Post icon  Posted 24 March 2006 - 12:41 PM

I am currently developing a game.
I would like to implement some sound samples. (MIDI Sequences)
I was wondering if any of you have some experience with that and can point me to
some good resources to learn from. Google only comes up with long tutorials and I just cant
believe implementing sound is that hard in Java. Especially when you know how easy it is to
program GUI and all.

#2 User is offline   Sideshow Icon

  • Critical Member
  • PipPipPipPip
  • Group: Oldies
  • Posts: 162
  • Joined: 06-October 05
  • Location:Australia

Posted 27 March 2006 - 05:09 AM

heres some code for making a simple audio player.... i'm sure you can slice up what you need.

// you will need to use javax.sound.sampled.SourceDataLine
// and javax.sound.sampled.TargetDataLine to read and write to audio buffers
// for sample code see 	http://www.jsresources.org/examples/audio_misc.html
//						http://javaalmanac.com/egs/javax.sound.sampled/StreamAudio.html
// 						  http://207.150.176.83/archive/index.php?t-54523.html

//package je3.sound;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.sound.sampled.*;


/**
 * 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 AudioPlayer extends JComponent 
{
	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 AudioPlayer in a Frame and displays it
	public static void main(String[  ] args) 
		throws IOException,
			   UnsupportedAudioFileException,
			   LineUnavailableException
	{
		AudioPlayer player;

		File file = new File("test.wav");//args[0]);   // This is the file we'll be playing
		// Determine whether it is midi or sampled audio

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

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

	// Create a AudioPlayer component for the specified file.
	public AudioPlayer(File f)
		throws IOException,
			   UnsupportedAudioFileException,
			   LineUnavailableException
	{

		// 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( );
					time.setText(value/1000 + "." + (value%1000)/100);   // Update the time label
					if (value != audioPosition) skip(value);			 // If we're not already there, skip there.
				}
			});
		
		// 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
		addSampledControls( );
	}

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

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

	// Stop playing the sound and reset the position to 0
	public void reset( ) 
	{
		stop( );
		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;
		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 (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;
	}

}

0

#3 Guest_Smartin_*

  • Group: Guests

Posted 27 March 2006 - 02:01 PM

Yes, I found it a lot more difficult to find something about sound in Java than about graphics.
Here's another smaller example. It is very basic though. You can do stuff like changing the tempo and things later.

import java.io.File;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;

String file = "C:/Java/MyGame/Sound/Music.mid";
	
void play()
throws Exception {

	//preparations
	Sequencer sequencer = MidiSystem.getSequencer();
	sequencer.open();
	Sequence seq = MidiSystem.getSequence(new File(file));
	sequencer.setSequence(seq);

	//start
	sequencer.start();

	//wait until finished
	while (sequencer.isRunning()) {
		Thread.sleep(1000); }

	//close
	sequencer.stop();
	sequencer.close();

}

This post has been edited by Smartin: 27 March 2006 - 02:03 PM


#4 User is offline   rake Icon

  • Posting Superpower
  • PipPipPipPipPipPipPip
  • Group: Oldies
  • Posts: 1,021
  • Joined: 06-October 05
  • Gender:Male
  • Location:San Francisco

Posted 27 March 2006 - 03:40 PM

Yeah, always make sure you run it as a thread, otherwise you won't be able to do anything with the program while the sound is running.
0

#5 User is offline   Sideshow Icon

  • Critical Member
  • PipPipPipPip
  • Group: Oldies
  • Posts: 162
  • Joined: 06-October 05
  • Location:Australia

Posted 28 March 2006 - 12:08 AM

Yeah i'd go with code Smartin provided, as you probably wont have much need for some of the things in the one i put up.

As we're on this topic, anyone got any info on implementing a text-to-speech synthesizer in java? I've got to make one for a uni class and if anyone knows of any good resources that'd be cool.
0

#6 Guest_PhatCat_*

  • Group: Guests

Posted 18 April 2006 - 06:17 PM

First of all, thanks for the replies, they were to say the least, very helpful.
This is my code right now :
import java.lang.Thread;
import java.io.File;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;

public class SoundManager {
   
	public void play () throws Exception {

	//preparations
	Sequencer sequencer = MidiSystem.getSequencer ();
	sequencer.open ();
	Sequence seq = MidiSystem.getSequence (
		(new File (new File ("prog","sounds"), "Battle.mid"))
	);
	sequencer.setSequence (seq);

	//start
	sequencer.start();

	//wait until finished
	while (sequencer.isRunning ()) 
		Thread.sleep (1000); 

	//close
	sequencer.stop ();
	sequencer.close ();
	}
}


Is it correct to assume that when the method 'play' of this class is called it will play the midi file once and sleep the thread while doing it ?
So all I need to do is call this call somewhere in my main program and the song will play once?

This post has been edited by PhatCat: 18 April 2006 - 06:19 PM


#7 Guest_PhatCat_*

  • Group: Guests

Posted 25 April 2006 - 04:55 PM

:) Boink
Sorry, couldn't check up on this for a while.
Anyone?

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users