20
1 Sound in Java Summary: Sound API Basics MIDI JavaSound - Part of the UIT User Interface Toolkit

1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

Embed Size (px)

Citation preview

Page 1: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

1

Sound in Java

Summary: Sound API Basics MIDI

JavaSound- Part of the UIT

User Interface Toolkit

Page 2: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

2

Page 3: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

3

MIDI in JavaSound Data is a MIDI file is a series

of commands that defines a piece of music

Up to 16 MIDI channels are available (each instrument uses one channel)

A MIDI Synthesizer reproduces(synthesizes) sounds in response to MIDI commands H/W part of the sound card S/W as in JavaSound

A sequencer is a device that processes a MIDI sequence in order to play it on a synthesizer, or possible to edit it. H/W or S/W

A device conforming to the General MIDI spec. must provide:

A min. of 128 preset instruments + 47 percussive sounds

A min. of 16 simultaneous timbres (instruments)

A min. of 24 simultaneous voices, where each voice is a note of given velocity (loudness) for any of the available instruments and percussive sounds

16 midi channels, where each channel is polyphonic(can play multiple simultaneous voices). Percussive sounds are always on channel 10

Page 4: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

4

Midi Note Numbers

The Note Number ranges from 0-127 60 = middle C Number DIV 12 is the octave 91 DIV 12 or octave number 7 127 DIV 12 or 10 octaves in all

Page 5: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

5

Note Number to Class

Number MOD 12 is the note class Note Name Note Class

C 0C# 1D 2

D# 3E 4F 5

F# 6G 7

G# 8A 9

A# 10B 11

Page 6: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

6

Whole Note Names CDEFGABC Whole Note Classes Wnc[]={0,2,4,5,7,9,

11}

Note Name Note ClassC 0

C# 1D 2

D# 3E 4F 5

F# 6G 7

G# 8A 9

A# 10B 11

Page 7: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

7

Note Class

Octave-NN matrixOctave Note Numbers # C C# D D# E F F# G G# A A# B

0 0 1 2 3 4 5 6 7 8 9 10 111 12 13 14 15 16 17 18 19 20 21 22 232 24 25 26 27 28 29 30 31 32 33 34 353 36 37 38 39 40 41 42 43 44 45 46 474 48 49 50 51 52 53 54 55 56 57 58 595 60 61 62 63 64 65 66 67 68 69 70 716 72 73 74 75 76 77 78 79 80 81 82 837 84 85 86 87 88 89 90 91 92 93 94 958 96 97 98 99 100 101 102 103 104 105 106 1079 108 109 110 111 112 113 114 115 116 117 118 119

10 120 121 122 123 124 125 126 127

Page 8: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

8

Note Number to Frequency

public static double getMidiFrequency(int midiNoteNumber){

return 440. * Math.pow(2,((midiNoteNumber-69.)/12.));

}

( 69) /12440*2 nnf

Page 9: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

9

MIDI Resources in JavaSound

Sequencer Synthesizer

MidiDevice

Declares basic operations for a MIDI device. Inner class, MidDevice.Info can be used for specifying a device

A sequencer object can play a sequence, which you can construct from a MIDI file

A synthesizer object encapsumates a h/w or s/w MIDI synthesizer

Declares operations specific to a synthesizer

Declares operations specific to a sequencer. Innerclass Sequencer.SyncMode used for synchronizing with another device

Page 10: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

10

Playing a MIDI fileTo play a MIDI file, you don’t need to access a synthesizer

directly. All you need is a Sequencer reference and an object encapsulating the sequence that you want to play.

Steps:1. sequencer = MidiSystem.getSequencer();

// Get a sequencer

2. sequencer.open(); 3. sequence = MidiSystem.getSequence(midiFile)

// Encapsulate the midi src (file here; URL possible) in a sequence obj.

4. sequencer.setSequence(sequence); // Hand the sequence over to the sequencer

5. sequencer.start();// Play it. Stop it: sequencer.stop()

Page 11: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

11

Page 12: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

12

Java Sound Preliminaries

File Formats Supported .au or .snd : usually

stores 8-bit -law encoded samples, but can also store 8 or 16 bit linear samples

.aif : usually stores 8 or 16 bit linear encoded samples

.wav :Can store 8 or 16 bit samples using linear or -law encoded samples

.midi : follows the midi data format

Note: The file header indicates the actual format

Frames and Frame Rates Sample Frame

Stores all the samples taken at an instant of time

# of bytes in a frame = # of bytes in a sample X number of channels

Frame Rate The number of frames per

second of sound In most cases frame rate is

same as sample rate In compressed sound, the

frame rate will be less than sample rate.

Page 13: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

13

Simple Sound Outputimport java.applet.*;

import javax.swing.*;

import java.awt.event.*;

public class PlayIt extends JApplet

{

AudioClip clip; // The sound clip

JButton button;

final String play = "PLAY";

final String stop = "STOP";

public void init()

{

// Get the sound clip

String fileName = getParameter("clip");

// Get the file name

clip =

getAudioClip(getDocumentBase(),fileName);

// Create the clip

// Rest of the applet initialization...

button = new JButton(play);

button.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

if(e.getActionCommand().equals(play))

{

clip.loop();

button.setText(stop);

}

else

{

clip.stop();

button.setText(play);

}

}

}

);

getContentPane().add(button);

}

<APPLET CODE =“PlayIt.class” CODEBASE = “.” WIDTH = 300 Height = 50 clip = “myClip.wav” >

</APPLET>

Playit.html

PlayIt.java

Page 14: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

14

Sound in Applications

Similar to an Applet The Applet class defines a static method,

newAudioClip()that retrieves an audio clip from a URL and returns a reference type AudioClip that encapsulates the audio clip. This method being static, you don’t have to have

an applet object to call it. It can be called from an application as well, like so:AudioClip clip = Applet.newAudioClip(URL location)

Take a look at example PlaySounds.java in the examples directory

Page 15: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

15

Java Sound APISystem Resources Audio Line: Any resource

that is a source or destination of sampled sound data A line can encapsulate

several channels Example: input/output

ports on the sound card Lines have controls (gain

and pan control) Mixer: Receives input

from one or more source data lines and outputs the result of combining the input to an output line called a target data line

Other Sound Sources A file or more generally a

URL

Terminology: A source data line is a

source for a mixer, not a source for you; you write to it

A target data line is the output from the mixer; your read from it

MIXERSound i/p

Sound i/p

Sound i/p

Sound o/p

Sound o/p

Target Data LinesSource Data Lines

Page 16: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

16

Java Sound API (…contd)Packages: javax.sound.sampled javax.sound.midi javax.sound.sampled.spi javax.sound.sampled.mid

i

The AudioSystem class Establish whether a

particular resource is available

Get a ref. to the object that encapsulates the resource

Call methods to operate the resource

AudioStreamInput class Represents a stream that

is a source of sampled sound data with a specific format

You can create an AudioStreamInput object from a local sound file, from another input stream or a URL

You can Read data from it Write its contents to an

output stream Convert its format

Page 17: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

17

Sampled Sound Interfaces

TargetDataLineSomething you read from.

Data keeps comingUse it or loose it!

Mixer DataLinePort

(mic, dataline, etc)

SourceDataLine

Line(info on everything)

Clip (not streaming)Audio in memory

Page 18: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

18

Resource Descriptor Classes

Mixer.Info DataLine.Info Port.Info

Line.Info

The Line, DataLine, Mixer and Port interface definitions each include an inner class with the name Info. Objects of these class types encapsulate data specifying an object of the corresponding type

Specifies a Line object by its Class

Specifies a Mixer object by its name, vendor version and description

Specifies a DataLine by the audio formats to be supported, the buffer size limits, and the Class of the data line

Specifies a Port object by its Class, its name, and whether it is a source or target line

Page 19: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

19

Why Descriptor Class?In order to answer that question, we have to look at the

steps involved in playing audio:1. Create an instance of a Line that specifies the format

of the sound data you wish to play (use descriptor class). Not all formats will be supported.

2. Get a reference to a line (a DataLine, Port, Mixer or Clip) that supports this format

1. May check if supported before requesting reference

3. Create an Audio Stream that encapsulates the sound data (file, URL, another stream)

1. Extract the format from the Audio Stream

4. Tie the source of the sound data to the reference (line) that will play it. I.e., open the source

5. Play it; loop; goto; quit.

Page 20: 1 Sound in Java Summary: r Sound API Basics r MIDI JavaSound - Part of the UIT User Interface Toolkit

20

Playing a Clip vs. StreamAudioInputStream source =

AudioSystem.getAudioInputStream(file);

// Step 3.

DataLine.Info clipInfo = new DataLine.Info(Clip.class, source.getFormat());

// Step 1.

if(AudioSystem.isLineSupported(clipInfo))

{

Clip newClip = (Clip)AudioSystem.getLine(clipInfo);

// Step 2.

newClip.open(source);// Step 4.

}

clip.loop(clip.LOOP_CONTINUOUSLY); // loop

clip.stop(); // stop

clip.setFramePosition(0);

Clip.close();

AudioInputStream newSource = AudioSystem.getAudioInputStream(file);

// Step 3.AudioFormat format = newSource.getFormat(); DataLine.Info sourceInfo = new

DataLine.Info(SourceDataLine.class, format); // Step 1.

if(AudioSystem.isLineSupported(sourceInfo)){ srcLine =

(SourceDataLine)AudioSystem.getLine(sourceInfo); // Step 2.

bufferSize = (int)(format.getFrameSize()*format.getFrameRate()/2.0f);

soundData = new byte[bufferSize]; srcLine.open(format, bufferSize); //4.}while(playing){ byteCount = source.read(soundData, 0,

soundData.length); // Read the stream if(byteCount == -1) { sourceLine.drain(); // rest of buffer playing = false; break; } sourceLine.write(soundData,0, byteCount);

// Write the array to the line}