The built in API of java can not handle audio files larger than 5mb. I googled a lot to find other alternatives but, unfortunately there isn't much support for audio in Java. After hours of searching, I found this
hack which is a part of many hacks, tips and tricks while working with Java Swing originally from the book "
Swing Hacks" written by Joshua Marinacci and Chris Adamson.
Let me start by showing you how .wav file is organized internally,
 |
Internal structure of Microsoft wave sound file
Source: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ |
a detailed explanation of the wave file format can be found at
Sonic Spot - " Wave File Format"
What I have been able to do so far:
- Play/plause/stop large audio files ( > 5 Mega Bytes ) encoded in Pulse-code modulation (PCM) format ( stored as .wav file ).
- Attach UI components ( javax.swing.JButton, javax.swing.JSlider, javax.swing.JProgressBar ) as an extension for GUI interaction.
- attach UI Container ( java.awt.Container) to display the wave form.
What is still left:
- Seek functionality, for more interaction.
* Update#1*
A preview of the API that I am working on now.
java.io.File audFile = new File("/path/to/wave/file.wav");
// create an instance of NonTrivialAudio
NonTrivialAudio audio = new NonTrivialAudio(audFile);
// display the header information
System.out.println("Header information: "+audio.getHeader());
// start playing the audio
audio.start();
// pause it
audio.pause();
// stop the play
audio.stop();
sample output for the above code
Header information:File size: 224044 Bytes
Header Size: 44
00-03 Letters : RIFF
04-07 Length of rdata chunk : 224036
================ rdata chunk ===================
08-11 Letters : WAVE
=============== format chunk ================
12-15 Letters : fmt
16-19 Length of rest of chunk : 16
20-21 WAV Format Tag : 1
22-23 Number of channels : 1
24-27 Sample frequency : 16000
28-31 nAvgBytesPerSec : 32000
32-33 nBlockAlign : 2
34-35 wBitsPerSample : 16
================ data chunk =================
36-39 Letters : data
40-43 Length of following data: 224000
44-224044 (data)
Add UI elements for additional interactivity:
// create an instance of AudioUI
AudioUI myAudio = new AudioUI();
// initialize swing components
javax.swing.JScrollPane myScrollPane = new JScrollPane();
javax.swing.JButton stopAudio = new JButton();
javax.swing.JButton playAudio = new JButton();
// ... code
// Hookup swing UI components for UI interactions
// myAudio.setUIWvContainer(myScrollPane); //Check update#2
myAudio.setDisplayContainer(myScrollPane);
myAudio.setUIPlay(playAudio);
myAudio.setUIPause(stopAudio);
// ... some more code
// setting source to AudioUI
java.io.File audFile = new File("/path/to/wave/file.wav");
myAudio.setAudioFile(audFile);
A demo application which makes use of the above code
 |
| AudioUI demo |
* Update #2 *
A lot has been done after the first preview. I am attaching the screenshots below
Working with the 'Wavform' display:
Setting up the zoom level i.e., display length
int defaultZlevel=7; // in seconds
// if requested Zlevel is not available, the maximum available will be used
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).setZoomLevel(defaultZlevel);
Zooming
int zStep = 1 ; //seconds
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).setZoomStep(zStep);
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).zoomIn(); // zoom in one 'zStep'
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).zoomOut(); // zoom out one 'zStep'
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).resetZoom(); // resets the zoom -- display the whole track
Refresh the display after every update.
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).refreshDisplay();
1: Adding Labels to audio track
String label = "MyLabel";
Double pos_in_sec = 1;
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).setLabelAt(label, pos_in_sec);
// No refresh necessary, labels are automatically loaded

2. Editing labels:
You can edit the the labels once you have loaded them into the display.
By enabling label editing you can, change the position of the labels on the current track. As shown in the screenshots below
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).editLabels(true);
Get the label at the current position of the mouse *inside* the display
Label labelAtPos = myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).getLabelAtXY(evt.getX(), evt.getY());
// 'evt' is the object of java.awt.event.MouseEvent
Now change the position of the label
if (labelAtPos != null)
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).setLabelAtXY(l, evt.getX(), evt.getY());
Toggle the display of labels
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM).toggleLabels();
You can also change the length of the crosshair ( the dark blue portion) that surrounds the current play position, the little red dot -- the pulse.
myAudio.getDisplay(AudioDisplay.TYPE.WAVEFORM)setCrosshairLen(crosshairLen)
This is my favorite visualization: I call it the 'ECG' display of audio (as it shows *only* the current play position -the red dot and its vicinity in blue).
The screenshot gives the view of it, but it looks a lot cooler in action ;)
You can find some more screenshots below :
 |
| Add caption |
I will post the code snippet soon. ( Check above)
More updates soon!
Further updates will be posted
here