samer@0
|
1 /*
|
samer@0
|
2 * AudioSink.java
|
samer@0
|
3 *
|
samer@0
|
4 * Copyright (c) 2000, Samer Abdallah, King's College London.
|
samer@0
|
5 * All rights reserved.
|
samer@0
|
6 *
|
samer@0
|
7 * This software is provided AS iS and WITHOUT ANY WARRANTY;
|
samer@0
|
8 * without even the implied warranty of MERCHANTABILITY or
|
samer@0
|
9 * FITNESS FOR A PARTICULAR PURPOSE.
|
samer@0
|
10 */
|
samer@0
|
11
|
samer@46
|
12 package ishara.audio;
|
samer@0
|
13 import javax.sound.sampled.AudioFormat;
|
samer@0
|
14
|
samer@0
|
15 /**
|
samer@0
|
16 General interface for objects that accept a stream of
|
samer@0
|
17 samples.
|
samer@0
|
18 */
|
samer@0
|
19
|
samer@0
|
20 public abstract class AudioSink
|
samer@0
|
21 {
|
samer@0
|
22 AudioFormat format;
|
samer@0
|
23 double scale;
|
samer@0
|
24
|
samer@0
|
25 public AudioSink(AudioFormat f) { format=f; }
|
samer@0
|
26 public AudioFormat getFormat() { return format; }
|
samer@0
|
27
|
samer@0
|
28 public double getScale() { return scale; }
|
samer@0
|
29 public void setScale(double s) { scale=s; }
|
samer@0
|
30
|
samer@0
|
31 public abstract void dispose();
|
samer@0
|
32 public abstract void start();
|
samer@0
|
33 public abstract void stop();
|
samer@0
|
34 public abstract int bwrite(byte [] bbuf, int offs, int len) throws Exception;
|
samer@0
|
35
|
samer@0
|
36 /** Return a task which takes samples from the given buffer
|
samer@0
|
37 * The idea is that the audio sink can choose the right
|
samer@0
|
38 * kind of writer depending on the format of the audio stream,
|
samer@0
|
39 * and then handle any conversions automatically.
|
samer@0
|
40 * Should return the number of samples NOT written.
|
samer@0
|
41 */
|
samer@0
|
42
|
samer@0
|
43 public Writer writer(int len) {
|
samer@0
|
44 return new Writer(len,format.getSampleSizeInBits()/8);
|
samer@0
|
45 }
|
samer@0
|
46
|
samer@0
|
47 public class Writer {
|
samer@0
|
48 byte[] bbuf;
|
samer@0
|
49 int bps;
|
samer@0
|
50 Converter conv;
|
samer@0
|
51
|
samer@0
|
52 public Writer(int len, int bps) {
|
samer@0
|
53 this.bps=bps;
|
samer@0
|
54 bbuf=new byte[len*bps];
|
samer@0
|
55 conv=getConverter(bbuf,bps);
|
samer@0
|
56 }
|
samer@0
|
57
|
samer@0
|
58 public int write(double dbuf[]) throws Exception { return write(dbuf,0,dbuf.length); }
|
samer@0
|
59 public int write(double dbuf[], int off, int len) throws Exception {
|
samer@0
|
60 conv.convert(dbuf,off,len);
|
samer@0
|
61 int rem=len*bps, pos=0;
|
samer@0
|
62 while (rem>0) {
|
samer@0
|
63 int count = bwrite(bbuf, pos, rem);
|
samer@0
|
64 if (count<=0) { return rem; }
|
samer@0
|
65 rem -= count; pos += count;
|
samer@0
|
66 }
|
samer@0
|
67 return 0;
|
samer@0
|
68 }
|
samer@0
|
69 }
|
samer@0
|
70
|
samer@0
|
71 private interface Converter { public void convert(double [] dbuf, int offset, int count); }
|
samer@0
|
72 private Converter getConverter(final byte [] b,final int bps) {
|
samer@0
|
73 switch (bps) {
|
samer@0
|
74 case 1: return new Converter() { public void convert(double[] d,int i, int n) { Util.doubleToByte(d,b,i,n,scale); } };
|
samer@0
|
75 case 2: return new Converter() { public void convert(double[] d,int i, int n) { Util.doubleToShort(d,b,i,n,scale); } };
|
samer@0
|
76 case 3: return new Converter() { public void convert(double[] d,int i, int n) { Util.doubleToMedium(d,b,i,n,scale); } };
|
samer@0
|
77 case 4: return new Converter() { public void convert(double[] d,int i, int n) { Util.doubleToInt(d,b,i,n,scale); } };
|
samer@0
|
78 }
|
samer@0
|
79 throw new Error("Unrecognised sample format");
|
samer@0
|
80 }
|
samer@0
|
81
|
samer@0
|
82 protected static void print(String msg) { System.out.println(msg); }
|
samer@0
|
83 }
|
samer@0
|
84
|