/*
* Copyright (C) 2013 gujicheng
*
* Licensed under the GPL License Version 2.0;
* you may not use this file except in compliance with the License.
*
* If you have any question, please contact me.
*
*************************************************************************
** Author information **
*************************************************************************
** Email: gujicheng197@126.com **
** QQ : 29600731 **
** Weibo: http://weibo.com/gujicheng197 **
*************************************************************************
*/
package com.libra.sinvoice;
import com.libra.sinvoice.Buffer.BufferData;
import com.libra.sinvoice.LogHelper;
public class SinGenerator {
private static final String TAG = "SinGenerator";
private static final int STATE_START = 1;
private static final int STATE_STOP = 2;
public static final int BITS_8 = 128;
public static final int BITS_16 = 32768;
public static final int SAMPLE_RATE_8 = 8000;
public static final int SAMPLE_RATE_11 = 11250;
public static final int SAMPLE_RATE_16 = 16000;
public static final int UNIT_ACCURACY_1 = 4;
public static final int UNIT_ACCURACY_2 = 8;
private int mState;
private int mSampleRate;
private int mBits;
private int mDuration;
private int mGenRate;
private static final int DEFAULT_BITS = BITS_8;
private static final int DEFAULT_SAMPLE_RATE = SAMPLE_RATE_8;
private static final int DEFAULT_BUFFER_SIZE = 1024;
private int mFilledSize;
private int mBufferSize;
private Listener mListener;
private Callback mCallback;
public static interface Listener {
void onStartGen();
void onStopGen();
}
public static interface Callback {
BufferData getGenBuffer();
void freeGenBuffer(BufferData buffer);
}
public SinGenerator(Callback callback) {
this(callback, DEFAULT_SAMPLE_RATE, DEFAULT_BITS, DEFAULT_BUFFER_SIZE);
}
public SinGenerator(Callback callback, int sampleRate, int bits, int bufferSize) {
mCallback = callback;
mBufferSize = bufferSize;
mSampleRate = sampleRate;
mBits = bits;
mDuration = 0;
mFilledSize = 0;
mState = STATE_STOP;
}
public void setListener(Listener listener) {
mListener = listener;
}
public void stop() {
if (STATE_START == mState) {
mState = STATE_STOP;
}
}
public void start() {
if (STATE_STOP == mState) {
mState = STATE_START;
}
}
public void gen(int genRate, int duration) {
if (STATE_START == mState) {
mGenRate = genRate;
mDuration = duration;
if (null != mListener) {
mListener.onStartGen();
}
int n = mBits / 2;
int totalCount = (mDuration * mSampleRate) / 1000;
double per = (mGenRate / (double) mSampleRate) * 2 * Math.PI;
double d = 0;
LogHelper.d(TAG, "genRate:" + genRate);
if (null != mCallback) {
mFilledSize = 0;
BufferData buffer = mCallback.getGenBuffer();
if (null != buffer) {
for (int i = 0; i < totalCount; ++i) {
if (STATE_START == mState) {
int out = (int) (Math.sin(d) * n) + 128;
if (mFilledSize >= mBufferSize - 1) {
// free buffer
buffer.setFilledSize(mFilledSize);
mCallback.freeGenBuffer(buffer);
mFilledSize = 0;
buffer = mCallback.getGenBuffer();
if (null == buffer) {
LogHelper.e(TAG, "get null buffer");
break;
}
}
buffer.mData[mFilledSize++] = (byte) (out & 0xff);
if (BITS_16 == mBits) {
buffer.mData[mFilledSize++] = (byte) ((out >> 8) & 0xff);
}
d += per;
} else {
LogHelper.d(TAG, "sin gen force stop");
break;
}
}
} else {
LogHelper.e(TAG, "get null buffer");
}
if (null != buffer) {
buffer.setFilledSize(mFilledSize);
mCallback.freeGenBuffer(buffer);
}
mFilledSize = 0;
if (null != mListener) {
mListener.onStopGen();
}
}
}
}
}