package com.simonmonk.spike;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
public class Beeper {
private final static int SAMPLE_RATE = 16000;
private final static int ONE_DURATION = 32;
private final static int ZERO_DURATION = 8;
private final static int BIT_DURATION = 64;
private final static int DURATION = BIT_DURATION * 32;
private final static float f = 1000.0f;
private short[] buffer = null;
public void beep(int word) {
AudioTrack at;
int bufsizbytes = DURATION * SAMPLE_RATE / 1000;
int bufsizsamps = bufsizbytes / 2;
buffer = new short[bufsizsamps];
fillbuf(word, bufsizsamps);
try {
at = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufsizbytes,
AudioTrack.MODE_STATIC);
at.setStereoVolume(1.0f, 1.0f);
at.write(buffer, 0, bufsizsamps);
at.play();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
void fillbuf(int word, int bufsizsamps) {
double omega, t;
double dt = 1.0 / SAMPLE_RATE;
t = 0.0;
omega = (float) (2.0 * Math.PI * f);
for (int i = 0; i < bufsizsamps; i++) {
if (toneRequired(t, word)) {
buffer[i] = (short) (32000.0 * Math.sin(omega * t));
} else {
buffer[i] = 0;
}
t += dt;
}
}
boolean toneRequired(double t, long word) {
int ms = (int) (t * 1000);
int bitIndex = ms / BIT_DURATION;
int bit = (int) ((word >> (15 - bitIndex)) & 1);
int msWithinBit = ms - (bitIndex * BIT_DURATION);
if (bit == 1 && msWithinBit < ONE_DURATION) {
return true;
}
if (bit == 0 && msWithinBit < ZERO_DURATION) {
return true;
}
return false;
}
}