working on java 1.1 audio

This commit is contained in:
benfry
2005-02-05 03:35:59 +00:00
parent 5643ac6bf1
commit d94e560d31
2 changed files with 208 additions and 11 deletions

View File

@@ -25,6 +25,7 @@
package processing.core;
import java.io.*;
import java.lang.reflect.*;
import sun.audio.*;
// add check for reflection in host applet for sound completion
@@ -32,18 +33,30 @@ import sun.audio.*;
/**
* This is the crappy 8 khz ulaw version that's compatible
* This is the crappy 8 khz mono ulaw version that's compatible
* with Java 1.1 and 1.2. For Java 1.3 and higher, PSound2 is used.
*/
public class PSound {
PApplet applet;
// supposedly this is actually 8012.8210513 according to spec
public static final int SAMPLING_RATE = 8000;
PApplet parent;
Method soundEventMethod;
InputStream stream;
boolean loop;
float volume = 1;
//int length;
int position;
int data[];
public PSound() { } // for subclass
public PSound() { } // for 1.3 subclass
public PSound(PApplet applet, InputStream input) {
this.applet = applet;
public PSound(PApplet parent, InputStream input) {
this.parent = parent;
/*
try {
@@ -52,10 +65,40 @@ public class PSound {
error("<init>", e);
}
*/
parent.registerDispose(this);
try {
soundEventMethod =
parent.getClass().getMethod("soundEvent",
new Class[] { PSound.class });
// if we're here, then it means that there's a method for it
/*
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
try {
soundEventMethod.invoke(parent,
new Object[] { PSound.this });
} catch (Exception e) {
System.err.println("error, disabling soundEvent()");
e.printStackTrace();
soundEventMethod = null;
}
}
}
});
*/
} catch (Exception e) {
// no such method, or an error.. which is fine, just ignore
}
}
public void play() {
AudioPlayer.player.start(stream);
}
@@ -63,6 +106,7 @@ public class PSound {
* either sets repeat flag, or begins playing (and sets)
*/
public void loop() {
loop = true;
}
@@ -72,10 +116,12 @@ public class PSound {
* continue to the end of the clip."
*/
public void noLoop() {
loop = false;
}
public void pause() {
AudioPlayer.player.stop(stream);
}
@@ -83,6 +129,8 @@ public class PSound {
* Stops the audio and rewinds to the beginning.
*/
public void stop() {
AudioPlayer.player.stop(stream);
}
@@ -90,7 +138,8 @@ public class PSound {
* current position inside the clip (in seconds, just like video)
*/
public float time() {
return 0;
//return 0;
return (float)position / (float)SAMPLING_RATE;
}
@@ -103,6 +152,7 @@ public class PSound {
public void volume(float v) { // ranges 0..1
this.volume = v;
}
@@ -111,7 +161,154 @@ public class PSound {
* I think of something slightly more intelligent to do.
*/
protected void error(String where, Exception e) {
applet.die("Error inside PSound." + where + "()", e);
parent.die("Error inside PSound." + where + "()", e);
//e.printStackTrace();
}
// ------------------------------------------------------------
class Stream extends InputStream {
int index;
public int available() throws IOException {
return data.length - position;
}
public void close() throws IOException { }
public synchronized void mark() { }
public boolean markSupported() {
return false;
}
public int read() throws IOException {
return 0;
}
public int read(byte b[]) throws IOException {
return 0;
}
public int read(byte b[], int off, int len) throws IOException {
return 0;
}
public synchronized void reset() {
position = 0;
}
public long skip(long n) {
position = (position + (int)n) % data.length;
return n;
}
}
// ------------------------------------------------------------
// Conversion
// ulaw from http://www-svr.eng.cam.ac.uk/comp.speech/Section2/Q2.7.html
static final short BIAS = 0x84;
static final int CLIP = 32635;
static final int[] LINEAR_LUT = {
0, 132, 396, 924, 1980, 4092, 8316, 16764
};
static final int[] LAW_LUT = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};
/**
* 16 bit linear to 8 bit ulaw
*/
static byte linear2ulaw(int linear) {
//int sign, exponent, mantissa;
//byte ulaw;
if (linear > 32767) {
linear = 32767;
} else if(linear < -32768) {
linear = -32768;
}
int sign = linear >> 8 & 0x80;
if (sign != 0) linear = -linear;
if (linear > CLIP) linear = CLIP;
linear += BIAS;
int exponent = LAW_LUT[linear >> 7 & 0xFF];
int mantissa = linear >> exponent + 3 & 0xf;
byte ulaw = (byte) ( ~(sign | exponent << 4 | mantissa));
if (ulaw == 0) ulaw = 2; // CCITT trap
return ulaw;
}
/**
* 8 bit ulaw to 16 bit linear
*/
static int ulaw2linear(int ulaw) {
ulaw = ~ulaw;
int sign = ulaw & 0x80;
int exponent = (ulaw >> 4) & 7;
int mantissa = ulaw & 0x0F;
int linear = LINEAR_LUT[exponent] + (mantissa << exponent + 3);
return (short) ((sign != 0) ? -linear : linear);
}
/**
* cheap resampling with pitch distortion and aliasing
*/
static int[] resample(int original[], int oldfreq, int newfreq) {
int resampled[] = null;
float factor = 0;
int newlength;
if (oldfreq > newfreq) { // downsample
factor = (float)oldfreq / (float)newfreq;
newlength = (int)(original.length / factor);
resampled = new int[newlength];
for (int i = 0; i < newlength; i++) {
resampled[i] = original[(int)(i * factor)];
}
return resampled;
} else if (oldfreq < newfreq) { // upsample (is it necesary??)
factor = (float)newfreq / (float)oldfreq;
newlength = (int) (original.length * factor);
resampled = new int[newlength];
for (int i = 0; i < newlength; i++) {
resampled[i] = original[(int) (i * factor)];
}
return resampled;
}
return original;
}
}

View File

@@ -33,7 +33,7 @@ import javax.sound.sampled.*;
// for this class: http://javaalmanac.com/egs/javax.sound.sampled/pkg.html
public class PSound2 extends PSound {
PApplet parent;
//PApplet parent;
Method soundEventMethod;
Clip clip;
@@ -47,12 +47,11 @@ public class PSound2 extends PSound {
AudioInputStream stream =
AudioSystem.getAudioInputStream(input);
// *** this code appears as though it may just be faulty ***
// At present, ALAW and ULAW encodings must be converted
// to PCM_SIGNED before it can be played
AudioFormat format = stream.getFormat();
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
// *** this code appears as though it may just be faulty ***
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits()*2,
@@ -61,7 +60,7 @@ public class PSound2 extends PSound {
format.getFrameRate(),
true); // big endian
stream = AudioSystem.getAudioInputStream(format, stream);
//} else {
//} else {
//System.out.println("no conversion necessary");
}
@@ -202,6 +201,7 @@ public class PSound2 extends PSound {
gainControl.setValue(dB);
}
/** mute */
/*
public void noVolume() {