/*
/ Copyright (C) 2009 Risto Känsäkoski- Sesca ISW Ltd
/
/ This file is part of SIP-Applet (www.sesca.com, www.purplescout.com)
/
/ 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 2
/ 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, write to the Free Software
/ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sesca.audio;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import com.sesca.misc.Logger;
public class SineInput extends Thread implements AudioSource
{
int k=0;
int BUFFER_SIZE = 2560;
boolean running = false;
boolean suspended = false;
long timeStamp = 0;
long timeElapsed = 0;
int bytesperframe = 0;
int millisecondsperframe = 0;
MathContext mc=null;
File soundFile;
AudioFormat format;
//TargetDataLine line;
//AudioInputStream inputStream;
int frameSize;
byte[] frame;
AudioSourceListener listener;
double f1=400;
double f2=0;
long index=0;
int hz=8000;
int bitRate=8;
int toneDurationInMilliS=20;
public SineInput(AudioFormat f, int frameSize)
{
mc = new MathContext(4);
}
public void init(AudioSourceListener l, AudioFormat f, int fs)
{
listener = l;
format = f;
frameSize = fs;
frame = new byte[fs];
DataLine.Info lineInfo = new DataLine.Info(TargetDataLine.class, format, BUFFER_SIZE); // Tähän
bitRate=format.getSampleSizeInBits();
int bytespersecond = (int) (f.getSampleRate() * f.getFrameSize() * f.getChannels());
int framespersecond = bytespersecond / frameSize;
millisecondsperframe = 1000 / framespersecond;
}
public void run()
{
//System.out.println("SineInput has priority:"+this.getPriority());
running = true;
try
{
while (running)
{
k++;
// synchronized (this)
// {
if(suspended)
{
wait();
}
// }
//
try
{
timeStamp = System.nanoTime();
do
{
while (running && !suspended)
{
if(running && !suspended)
{
listener.onIncomingRawFrame(generateTone());
k++;
//if (k==3) running=false;
//sentframes++;
timeElapsed += millisecondsperframe*1000000;
long currentTime = System.nanoTime();
long timespentincode = currentTime - timeStamp;
long delta = (timeElapsed - timespentincode)/1000000;
//if (delta/1000000 <=20 || delta/1000000 >= 60){
if ((timeElapsed/1000000)%1000 == 1000){
System.out.print("audiotime="+timeElapsed/1000000);
System.out.print(", runtime="+timespentincode/1000000);
System.out.println(", delta="+delta);
}
//if(timespentincode + 10000000 < timeElapsed)
if (delta>200)
{
Thread.sleep(delta-200);
//System.out.println("Nukutaan"+(timeElapsed - (timespentincode + 10000000))/1000000+" ms.");
//Thread.sleep((timeElapsed - (timespentincode + 10000000))/1000000);
}
}
else System.out.println("runnig="+running+", suspended="+suspended);
}
//inputStream.close();
//inputStream = AudioSystem.getAudioInputStream(soundFile);
//System.out.println("End of file");
}
while (running && !suspended);
// halt();
}
finally
{
}
}
}
catch (Exception e)
{
running = false;
e.printStackTrace();
halt();
}
}
public void halt()
{
//line.stop();
//line.flush();
suspended = true;
}
//public synchronized boolean unhalt()
public boolean unhalt()
{
if(suspended == true)
{
try
{
suspended = false;
//line.start();
//inputStream.skip(inputStream.available());
notify();
}
finally{}
}
return true;
}
public void go()
{
Logger.debug("Starting FileInput");
start();
}
public void close()
{
running = false;
halt();
try
{
//inputStream.close();
}
finally
{
}
//line.stop();
//line.flush();
//line.close();
}
byte[] flip(byte b[])
{
byte c[] = new byte[b.length];
int j = 0;
for (int i = b.length - 1; i >= 0; i--)
{
c[j] = b[i];
}
return c;
}
byte[] generateTone()
{
//halt();
long bytesPerSecond=hz*bitRate/8;
long satsi=bytesPerSecond*toneDurationInMilliS/1000;
long framesPerSatsi=satsi/frame.length;
satsi = framesPerSatsi*frame.length;
//Logger.debug("Satsi="+satsi);
for (int k=0;k<framesPerSatsi;k++){
for (int i=0;i<frame.length;i+=2){
//double d=128 + 63*Math.sin(index*2*Math.PI*f1/8000) + 63*Math.sin(index*2*Math.PI*f2/8000);
double d1=0;
double d2=0;
if (f1!=0) d1=16383/2*Math.sin(index*2*Math.PI*f1/hz);
if (f2!=0) d2=16383/2*Math.sin(index*2*Math.PI*f2/hz);
double d=d2+d1;
int sample=(int)d;
//System.out.println(sample);
//little endian
frame[i]=(byte) (sample & 0xFF);
frame[i+1]=(byte) (int)((sample >> 8) & 0xFF);
//(byte)((byte)d+(byte)0);
index++;
}
}
//System.out.println("generated frame size: "+frame.length);
return frame;
}
}