// HomeAutomation software to accompany the book
// 'Practical Arduino + Android Projects for the Evil Genius'
// Copyright (C) 2011. Simon Monk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package com.simonmonk.home;
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 synchronized 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();
Thread.sleep(2000);
}
catch (Exception 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;
}
}