package javaforce.media;
/**
* FIFO buffer for audio samples (16bit only).
* Uses a cyclical buffer to avoid using locks or reallocation.
*/
import javaforce.*;
public class AudioBuffer {
private int bufsiz;
private short buf[];
private int head = 0, tail = 0;
public AudioBuffer(int freq, int chs, int seconds) {
bufsiz = freq * chs * seconds;
buf = new short[bufsiz];
clear();
}
public void add(short in[], int pos, int len) {
boolean wrap = false;
int nhead = head + len;
if (nhead >= bufsiz) {
wrap = true;
nhead -= bufsiz;
}
if (nhead == tail) return; //buffer full
if ( (head > tail) && (nhead > tail) && (wrap) ) return; //buffer full
if ( (head < tail) && (nhead > tail) && (!wrap) ) return; //buffer full
if (wrap) {
//copy 2 pieces
int p1 = bufsiz - head;
int p2 = len - p1;
System.arraycopy(in, pos, buf, head, p1);
System.arraycopy(in, pos+p1, buf, 0, p2);
} else {
//copy 1 piece
System.arraycopy(in, pos, buf, head, len);
}
head = nhead;
}
public boolean get(short out[], int pos, int len) {
if (tail == head) return false;
boolean wrap = false;
int ntail = tail + len;
if (ntail >= bufsiz) {
wrap = true;
ntail -= bufsiz;
}
if ( (tail > head) && (ntail > head) && (wrap) ) return false; //buffer empty
if ( (tail < head) && (ntail > head) && (!wrap) ) return false; //buffer empty
if (wrap) {
//copy 2 pieces
int p1 = bufsiz - tail;
int p2 = len - p1;
System.arraycopy(buf, tail, out, pos, p1);
System.arraycopy(buf, 0, out, pos+p1, p2);
} else {
//copy 1 piece
System.arraycopy(buf, tail, out, pos, len);
}
tail = ntail;
return true;
}
/** Returns # samples in buffer */
public int size() {
int t = tail;
int h = head;
if (t == h) return 0;
if (h > t) return h - t;
return bufsiz - t + h;
}
public void clear() {
tail = head;
}
}