Java
sound
audio programming
Java sound API
Java development

How can I play sound in Java?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Playing sound in Java can greatly enhance the interactivity and user experience of an application. From creating engaging games to integrating notifications in productivity tools, sound can serve multiple purposes. Given Java’s comprehensive libraries, it provides built-in functionalities to play sound through the javax.sound.sampled package and other libraries. This article will guide you through the process of playing sound in Java, covering both simple and more advanced implementations.

Basic Sound Playback with Clip

The javax.sound.sampled package offers classes and interfaces to handle audio operations. One of the simplest ways to play sound in Java is by using the Clip interface. Clips are loaded entirely into memory before they are played, making them suitable for short sounds like notifications or effects.

Example with Clip

Here's how you can use the Clip interface to play a sound file (WAV format):

java
1import javax.sound.sampled.*;
2import java.io.File;
3import java.io.IOException;
4
5public class SoundPlayer {
6    public static void main(String[] args) {
7        try {
8            // Specify the sound file as a File object.
9            File soundFile = new File("example.wav");
10            
11            // Get an audio input stream from the sound file.
12            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
13            
14            // Get a clip resource.
15            Clip clip = AudioSystem.getClip();
16            
17            // Open the clip and load the sound.
18            clip.open(audioInputStream);
19            
20            // Start playing the sound.
21            clip.start();
22            
23            // To keep the program running until the sound completes.
24            Thread.sleep(clip.getMicrosecondLength() / 1000);
25        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException | InterruptedException e) {
26            e.printStackTrace();
27        }
28    }
29}

Technical Explanation

  • AudioInputStream: Used to open a file as an audio stream.
  • Clip: Interface that represents an audio clip. Clips are pre-loaded into memory.
  • start(): Initiates the playback of the clip. The clip will play from the current position to the end.
  • Thread.sleep: Ensures that the program keeps running long enough for the sound to play to the end.

Playing Longer Audio with SourceDataLine

The Clip class works well for short audio clips. However, for longer audio, SourceDataLine can be used. This allows for streaming audio data, making it suitable for lengthy tracks or continuous playback.

Example with SourceDataLine

java
1import javax.sound.sampled.*;
2import java.io.File;
3import java.io.IOException;
4
5public class StreamAudio {
6    public static void main(String[] args) {
7        File soundFile = new File("example.wav");
8        try {
9            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
10            AudioFormat format = audioInputStream.getFormat();
11            DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
12            SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(info);
13            sourceLine.open(format);
14            sourceLine.start();
15
16            int nBytesRead = 0;
17            byte[] buffer = new byte[1024];
18            
19            while (nBytesRead != -1) {
20                nBytesRead = audioInputStream.read(buffer, 0, buffer.length);
21                if (nBytesRead >= 0) {
22                    sourceLine.write(buffer, 0, nBytesRead);
23                }
24            }
25            
26            sourceLine.drain();
27            sourceLine.close();
28        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
29            e.printStackTrace();
30        }
31    }
32}

Technical Explanation

  • SourceDataLine: This interface is for streaming audio data. It is more memory efficient for longer audio tracks.
  • write(): Writes data to the line's buffer. This method processes the audio in chunks (buffers).
  • drain(): Allows the data line to finish playing the buffered data.

Handling Other Audio Formats

While WAV files are commonly used, Java can also handle other formats like MP3 with the help of external libraries. Libraries such as JLayer or Javazoom provide functionalities to manage these formats.

Example with JLayer for MP3

Here’s a basic example of playing an MP3 file using JLayer:

java
1import javazoom.jl.decoder.JavaLayerException;
2import javazoom.jl.player.Player;
3import java.io.FileInputStream;
4
5public class MP3Player {
6    public static void main(String[] args) {
7        try (FileInputStream fis = new FileInputStream("example.mp3")) {
8            Player player = new Player(fis);
9            player.play();
10        } catch (Exception e) {
11            e.printStackTrace();
12        }
13    }
14}

Table Summary

ComponentDescription
AudioInputStreamOpens and converts the audio input for playback.
ClipSuitable for short audio clips; loads entire audio into memory before playing.
SourceDataLineStreams audio data; suitable for longer audio tracks.
JLayerExternal library needed to handle MP3 files in Java.

Conclusion

Playing sound in Java applications requires an understanding of the different classes and interfaces available in the javax.sound.sampled package. For short audio clips, Clip is straightforward, but for longer sounds, SourceDataLine provides more flexibility. For handling non-WAV formats like MP3, external libraries such as JLayer are essential. The flexibility that Java provides in managing audio ensures it can be used in a variety of applications, enhancing the overall user experience.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.