19
Music Visualizer With JavaFX TM , JMF TM + Java TM Sound Lucas Jordan EffectiveUI Denver - Rochester - Vancouver

Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

Embed Size (px)

Citation preview

Page 1: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

Music VisualizerWith JavaFXTM,JMFTM + JavaTM SoundLucas JordanEffectiveUIDenver - Rochester - Vancouver

Page 2: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

2

IntroductionJavaFX Launch> Sun came to us

“You tell us what you should make”> Music Visualizer - Synethesiator

Fancy UI Complex computation Music is hip (right?) Perfect for JavaFX

What is a music Visualizer and is JavaFX a reasonable platform for this?

Page 3: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

What is an Audio Visualizer> Digital Audio

Sound is air pressure on your eardrum The pressure is proportional to the movement of a speaker The movement is proportional to the voltage in a wire The voltage is proportional to a byte in your application A byte of sound

> Digital Graphics Take that byte of sound Display a graphic proportional to the byte

> Now you are seeing something proportional to what you are hearing!

Page 4: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

Examples

Page 5: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

5

How do we get JavaFX to do this?> Playing audio with java

javafx.scene.media.* java.applet.AudioClip sun.audio.* java.sound.sampled.* javax.media.* Quicktime?

But which give us access to the audio data as it is played?

Page 6: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

6

How do we get JavaFX to do this?> JavaFX can’t do this on its own

JMF or Java Sound required> But it can when there is a J2SE stack

Desktop Web Probably the fancier phones soon

Page 7: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

7

How do we get JavaFX to do this?> JMF - Java Media Framework

Kind of ancient Really flexible Poor codec support / we are cheap Insane deployment story

Originally designed as an extension to the JVM> Java Sound

Poor codec support JavaFX can play MP3s, but Java out of the box can’t? Find third party jars

Built into the JVM

Page 8: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

8

Getting at the audio data (JMF)> JMF requires a lot of code to set up> Here are the highlights on setting it up

To simply play audio Player player = Manager.createPlayer(url); We can’t use a Player

Implement Effect Register your Effect with the Manager Create a Processor from the Manager

A Processor extends Player Plug-in your Effect

Page 9: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

9

Getting at the audio data (JMF)> The Effect interface

Extends Codec Gets inserted after the audio is decoded by a codec Has lots of other methods, process is what is interesting to us

public int process(Buffer inputBuffer, Buffer outputBuffer){//Copy inputBuffer into outputBuffer//Look at inputBuffer, do something interesting return BUFFER_PROCESSED_OK;}

Page 10: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

10

Getting at the audio data (Java Sound)> Steps to get at the byte of sound

Create an AudioInputStream of a known AudioFormat Create a SourceDataLine Create a Thread

Reads from AudioInputStream Does something interesting Write to SourceDataLine

> We want a known format because we don’t want to write a spectrum analyzer for each possible encoding, sample rate, etc

Page 11: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

11

Getting at the audio data (Java Sound)> The code to set up the audio input and outputAudioInputStream originalInputStream = AudioSystem.getAudioInputStream(inputStream);

//Format of data read inAudioFormat originalFormat = originalInputStream.getFormat();

//Normalize the data to something we knowdecodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,

originalFormat.getSampleRate(), … );

//Input stream of the normalized format.AudioInputStream decodedInputStream = AudioSystem.getAudioInputStream(decodedFormat,

originalInputStream);

SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);

line.open(decodedFormat);line.start();

Page 12: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

12

Getting at the audio data (Java Sound)> Thread to play the audio

Runnable.run() dis is a decodedInputStream

byte[] data = new byte[4096]int nBytesRead;while (nBytesRead = dis.read(data, 0, data.length) != -1) {

//Do Something Interesting! line.write(data, 0, nBytesRead);}

Page 13: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

13

Doing Something Interesting Considerations> Sample Rate

Audio processing thread updates too fast for JavaFX A Spectrum Analysis or other FFT code might want more data then just one

read-write loop We want to accumulate audio bytes in the audio processing thread Create another thread which produces a final value at a more reasonable

rate We want to accumulate audio bytes in the audio processing thread

> Interacting With JavaFX Presenting our processed value in a JavaFX way We want to bind to the value JavaFX wrapper class Observable/Observer

Page 14: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

14

Java and JavaFX classes> Create a Java class SoundDetailspublic class SoundDetails extends Observable implements Runnable{

private byte[] accumulatedData; private float currentLoudness;

public void run() { while(true){ try { Thread.sleep(1000 / 33); currentLoudness = calculateLoudness(accumulatedData); setChanged(); notifyObservers(); } catch (InterruptedException ex) { //log or something } } }}

Page 15: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

15

Java and JavaFX classes> Create a class SoundDetailsFX

public class SoundDetailsFX extends Observer{ public-init var soundDetails:SoundDetails; public-read var currentLoudness:Number; init{ soundDetails.addObserver(this); } override function update(observable: Observable, arg: Object) { currentLoudness = soundDetails.getCurrentLoudness(); }}

Page 16: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

16

Java and JavaFX classes> Finally, doing something interesting

Where sdfx is a SoundDetailsFX object

var rect = Rectangle{ width: 10 height: bind sdfx.currentLoudness fill: Color.ANTIQUEWHITE }

Page 17: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

17

Recap> Exposed bytes of sound as they are being played

JMF or Java Sound> Accumulated and processed those bytes

Processing Thread> Wrapped the result of that process in a JavaFX object

Observable/Observer> Used a JavaFX programming paradigm to display a graphic

bind

Page 18: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

18

Resources> Example Code

http://lucasjordan.com/audiovisualizer> JMF

http://java.sun.com/javase/technologies/desktop/media/jmf/> Java Sound

http://java.sun.com/products/java-media/sound/> Tritonus: Open Source Java Sound

http://www.tritonus.org/> EffectiveUI

http://effectiveui.com

Page 19: Music Visualizer With JavaFX, JMF + Java Sound · Music Visualizer With JavaFXTM, JMFTM + JavaTM Sound Lucas Jordan ... How do we get JavaFX to do this? ... Music Visualizer With

19

Lucas [email protected]@effectiveui.com

effectiveui.comlucasjordan.com