📄 sourcevoiceline.java
字号:
package local.dialogic;
import javax.sound.sampled.*;
import java.io.*;
import java.util.*;
public class SourceVoiceLine extends InputStream implements SourceDataLine
{
// Default buffer size, can be reset via open(format, bufferSize)
int bufferSize = 8096;
byte buffer[] = null;
boolean active = false;
int pos = 0;
// Available bytes
int cap = 0;
// Next incoming byte
int at = 0;
// Should be linked to Voice constants, may be command Voice from here ?
// Can be reset via open(format) or open(format, bufferSize)
AudioFormat format = new AudioFormat(
AudioFormat.Encoding.ULAW, // Encoding
8000, // Sample rate
8, // bits per sample
1, // channels
1, // frame size
8000, // frame rate
true); // big endian
//My listeners
Vector listeners = new Vector();
// InputStream
/**
* Reads audio data from the data line's input buffer.
*/
public synchronized int read(byte[] b, int off, int len) {
while (active && (cap < len)) {
try {
wait();
} catch (InterruptedException ie) {};
}
int i, ato = at - cap;
if (ato < 0) ato += bufferSize;
for (i = 0; (i < len) && (i < cap); i++) {
b[i+off] = buffer[ato++];
if (ato >= bufferSize) ato = 0;
}
cap -= i;
return i;
}
/**
* Read one byte
*/
public synchronized int read() throws IOException {
while (active && (cap < 1)) {
try {
wait();
} catch (InterruptedException ie) {};
}
if (cap > 0) {
int ato = at - cap;
if (ato < 0) ato += bufferSize;
cap--;
return (int)buffer[ato];
} else
return -1;
}
// Line methods
/**
* Adds a listener to this line.
*/
public void addLineListener (LineListener listener) {
synchronized(listeners) {
listeners.add(listener);
}
}
/**
* Closes the line, indicating that any system resources in use by the line can be released.
*/
public synchronized void close() {
buffer = null;
active = false;
pos = 0;
at = 0;
cap = 0;
}
/**
* Obtains a control of the specified type, if there is any.
*/
public Control getControl (Control.Type control) throws IllegalArgumentException {
throw new IllegalArgumentException();
}
/**
* Obtains the set of controls associated with this line.
*/
public Control[] getControls () {
return new Control[0];
}
/**
* Obtains the Line.Info object describing this line.
*/
public Line.Info getLineInfo () {
return new Line.Info(SourceVoiceLine.class);
}
/**
* Indicates whether the line supports a control of the specified type.
*/
public boolean isControlSupported (Control.Type control) {
return false;
}
/**
* Indicates whether the line is open, meaning that it has reserved system
* resources and is operational, although it might not currently be playing
* or capturing sound.
*/
public boolean isOpen () {
return (buffer != null);
}
/**
* Opens the line, indicating that it should acquire any required system
* resources and become operational.
*/
public synchronized void open () {
buffer = new byte[bufferSize];
pos = 0;
at = 0;
cap = 0;
}
/**
* Removes the specified listener from this line's list of listeners.
*/
public void removeLineListener(LineListener listener) {
synchronized(listeners) {
listeners.remove(listener);
}
}
// DataLine methods
/**
* Obtains the number of bytes of data currently available to the application
* for processing in the data line's internal buffer.
*/
public int available() {
return bufferSize - cap;
}
/**
* Drains queued data from the line by continuing data I/O until the data
* line's internal buffer has been emptied.
*/
public synchronized void drain() {
while(cap > 0) {
try {
wait();
} catch (InterruptedException ie) {};
}
}
/**
* Flushes queued data from the line.
*/
public synchronized void flush() {
at = cap = 0;
notifyAll();
}
/**
* Obtains the maximum number of bytes of data that will fit in the data
* line's internal buffer.
*/
public int getBufferSize() {
return bufferSize;
}
/**
* Obtains the current format (encoding, sample rate, number of channels, etc.)
* of the data line's audio data.
*/
public AudioFormat getFormat() {
return format;
}
/**
* Obtains the current position in the audio data, in sample frames.
*/
public int getFramePosition() {
return pos;
}
/**
* Obtains the current volume level for the line
*/
public float getLevel() {
return (float)AudioSystem.NOT_SPECIFIED;
}
/**
* Obtains the current position in the audio data, in microseconds.
*/
public long getMicrosecondPosition() {
return (long)pos * 1000L / (long)format.getFrameRate();
}
/**
* Indicates whether the line is engaging in active I/O (such as playback or capture).
*/
public boolean isActive() {
return active;
}
/**
* Indicates whether the line is running.
*/
public boolean isRunning() {
return true;
}
/**
* Allows a line to engage in data I/O.
*/
public synchronized void start() {
if (isOpen())
active = true;
// XXX Should inform listeners...
}
/**
* Stops the line.
*/
public synchronized void stop() {
active = false;
notifyAll();
// XXX Should inform listeners...
}
// TargetDataLine methods
/**
* Opens the line with the specified format, causing the line to acquire
* any required system resources and become operational.
*/
public synchronized void open(AudioFormat format) {
this.format = format;
open();
}
/**
* Opens the line with the specified format and requested buffer size,
* causing the line to acquire any required system resources and
* become operational.
*/
public void open(AudioFormat format, int bufferSize) {
this.bufferSize = bufferSize;
open(format);
}
/**
* Writes audio data to the mixer via this source data line.
*/
public synchronized int write(byte[] b, int off, int len) {
int i = 0, step;
// Only write to active lines
if (!active)
return 0;
// No offset please
if (off != 0)
throw new RuntimeException("Offset not supported!");
// Stay here while active untill all data is written
while (active && i < len) {
// Wait for some space at buffer
while (active && (cap >= bufferSize)) {
try {
wait();
} catch (InterruptedException ie) {};
}
if (!active) break;
// write whatever we can fit
step = bufferSize - cap;
// don't overshoot
if (i + step > len) step = len - i;
for (int j = 0; j < step; j++) {
buffer[at++] = b[i+j];
if (at >= bufferSize) at = 0;
}
cap += step;
i += step;
// Let any consumers out there know there's some data
notifyAll();
}
System.out.println("SourceVoiceLine write " + len + " at " + at + " cap " + cap);
return i;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -