• Tidak ada hasil yang ditemukan

Pembuatan Game Tetris Dengan Kendali Pengenalan Perintah Suara Pada Smartphone Android

N/A
N/A
Protected

Academic year: 2019

Membagikan "Pembuatan Game Tetris Dengan Kendali Pengenalan Perintah Suara Pada Smartphone Android"

Copied!
25
0
0

Teks penuh

(1)

LAMPIRAN

Tetris.java

package android.tetris;

import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View;

import android.view.View.OnClickListener; import android.view.Window;

import android.widget.Button;

public class Tetris extends Activity {

private Button btnNewGame, btnHighScores, btnAbout, btnExit;

/** Called when the activity is first created. */ @Override

public void onCreate(Bundle savedInstanceState) { //Assign layouts

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main);

//Find and assign buttons

btnNewGame = (Button) findViewById(R.id.buttonNewGame); btnNewGame.setOnClickListener(new OnClickListener(){ public void onClick(View v) {

Intent intent = new Intent(Tetris.this, Game.class); startActivity(intent);

} });

btnHighScores = (Button) findViewById(R.id.buttonHighScores); btnHighScores.setOnClickListener(new OnClickListener(){ public void onClick(View v) {

Intent intent = new Intent(Tetris.this, HighScores.class);

startActivity(intent); }

});

btnAbout = (Button) findViewById(R.id.buttonAbout);

//btnResumeGame.setEnabled(false); //Disabled (unimplemented feature) btnAbout.setOnClickListener(new OnClickListener(){

public void onClick(View v) {

Intent intent = new Intent(Tetris.this, About.class); startActivity(intent);

} });

(2)

btnExit = (Button) findViewById(R.id.buttonExit); btnExit.setOnClickListener(new OnClickListener(){ public void onClick(View v) {

finish(); }

}); } }

Game.java

package android.tetris;

import java.util.Calendar; import java.util.Date; import android.app.Activity; import android.content.Context;

import android.content.SharedPreferences; import android.media.AudioFormat;

import android.os.Bundle;

import android.os.CountDownTimer; import android.os.Vibrator; import android.view.Display; import android.view.View;

import android.view.View.OnClickListener; import android.view.Window;

import android.widget.Button; import android.widget.ImageView; import android.widget.TextView;

import java.io.File;

import java.util.ArrayList; import java.util.List;

import android.content.res.AssetManager; import java.io.FileInputStream;

import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream;

import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Button;

import android.tetris.voice.RecordAudio.interp.ConsistentFrequencyDetector; import android.tetris.voice.RecordAudio.interp.LoudNoiseDetector;

(3)

import android.tetris.voice.RecordAudio.record.AudioClipRecorder;

import android.tetris.voice.RecordAudio.record.OneDetectorManyObservers; import android.tetris.voice.RecordTask.AudioTaskUtil;

import android.tetris.voice.RecordTask.RecordAudioTask;

import android.tetris.voice.RecordAudio.interp.LoudNoiseDetector;

public class Game extends Activity {

RecordAudioTask recordAudioTask; LoudNoiseDetector lnd;

BoardView gameBoard;

int d; // The side of a box public Box[][] box;

int x, y;

BoardView boardView; Display display; CountDownTimer timer; public Piece currentPiece; public Piece nextPiece; boolean pieceOnGame; ImageView nextPieceImg; //Score and combo TextView textScore; ImageView imageCombo; int score = 0;

int combo = 1; Vibrator vibrator; //The pause indicator boolean game;

/** Called when the activity is first created. */ @Override

public void onCreate(Bundle savedInstanceState) {

///Assign File Database

cekFileDatabase();

//Assign layouts

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.game);

//Get measures for the board

display = getWindowManager().getDefaultDisplay(); int width = (int) (display.getWidth() * 0.7); int height = (int) (display.getHeight() * 0.9); gameBoard = (BoardView) findViewById(R.id.GameView); d = (int) (width * 0.85 / 10);

//Asign score and combo resources

textScore = (TextView) findViewById(R.id.TextViewScore); imageCombo = (ImageView) findViewById(R.id.imageViewCombo);

(4)

x = (int) (width * 0.05); y = (int) (height * 0.05); gameBoard.createWall(x, y, d); for (int i = 0; i < 20; i++){ x = (int) (width * 0.05); for (int j = 0; j < 10; j++){

box[i][j] = new Box(x + d * j, y + d * i, d); gameBoard.initialize(i, j, x, y, d);

x = x + d; }

y = y + d; };

//initialize vibrator

vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

//Initialize pieces

currentPiece = new Piece(); nextPiece = new Piece();

nextPieceImg = (ImageView) findViewById(R.id.imageViewNext);

//Start the time bucle game = true;

timer = new CountDownTimer(180000, 1000) {

public void onTick(long millisUntilFinished) { gameAction();

}

public void onFinish() { gameAction(); start();

} }.start();

//Start the game

textScore.setText("0"); currentPiece.start();

//Set image for next piece

//Has to be done here, or there is no next piece image at the beggining

switch(nextPiece.type){ case Values.PIECE_0:

nextPieceImg.setImageResource(R.drawable.piece0); break;

case Values.PIECE_1:

nextPieceImg.setImageResource(R.drawable.piece1); break;

case Values.PIECE_2:

nextPieceImg.setImageResource(R.drawable.piece2); break;

(5)

nextPieceImg.setImageResource(R.drawable.piece3); break;

case Values.PIECE_4:

nextPieceImg.setImageResource(R.drawable.piece4); break;

case Values.PIECE_5:

nextPieceImg.setImageResource(R.drawable.piece5); break;

case Values.PIECE_6:

nextPieceImg.setImageResource(R.drawable.piece6); break;

} }

public void EnableButton(boolean on) { btnMoveDown.setEnabled(on);

}

public void KIRI (){ unDraw();

currentPiece.moveLeft(); vibrator.vibrate(30); reDraw();

}

public void KANAN(){ unDraw();

currentPiece.moveRight(); vibrator.vibrate(30); reDraw();

}

public void PUTAR(){ unDraw();

currentPiece.rotateRight(); vibrator.vibrate(30); reDraw();

}

public void BAWAH(){ unDraw();

currentPiece.moveDown(); currentPiece.moveDown(); vibrator.vibrate(30); reDraw();

}

public void StartWordRecognition(){

startTask(new LoudNoiseDetector()); }

//The time bucle

public void gameAction(){ if (game == true){

(6)

unDraw();

//Try to move down.

if (currentPiece.moveDown() == false){

//If couldnt move fix the blocks currently occupied...

for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++){

if (currentPiece.box[i][j] == true){

box[i][j].setColor(currentPiece.getColor());

gameBoard.setColor(i, j, currentPiece.getColor());

}

}

/// ...check if there is any full row... if (lookForRows() == false){

combo = 1; //If nothing has been removed, set combo to 1

imageCombo.setImageResource(R.drawable.alpha); }

//... check if the game is loose... if (gameLoose() == true)

finish();

// ... and start a new piece currentPiece = nextPiece; currentPiece.start(); nextPiece = new Piece();

//Set the next piece image switch(nextPiece.type){

case Values.PIECE_0:

nextPieceImg.setImageResource(R.drawable.piece0); break;

case Values.PIECE_1:

nextPieceImg.setImageResource(R.drawable.piece1); break;

case Values.PIECE_2:

nextPieceImg.setImageResource(R.drawable.piece2); break;

case Values.PIECE_3:

nextPieceImg.setImageResource(R.drawable.piece3); break;

case Values.PIECE_4:

nextPieceImg.setImageResource(R.drawable.piece4); break;

case Values.PIECE_5:

nextPieceImg.setImageResource(R.drawable.piece5); break;

(7)

nextPieceImg.setImageResource(R.drawable.piece6); break;

} }

//Copy the board info to the piece currentPiece.readBoard(box);

reDraw(); }

}

//If there is something in the two first rows before starting a new piece, the game is loose

private boolean gameLoose() {

int hScore1, hScore2, hScore3, aux;

String hScore1Date, hScore2Date, hScore3Date, auxDate; boolean loose = false;

for (int j = 0; j < 10; j++)

if (box[1][j].getColor() != Values.COLOR_NONE) loose = true;

if (loose == false) return false;

//What to do on game over?

//Notify the user TODO: (Maybe deactivate buttons?) game = false;

vibrator.vibrate(1000);

//Stop Word Record TAsk stopAll();

//Add high scores if needed SharedPreferences highScores = getSharedPreferences("highScores", 0);

hScore1 = highScores.getInt("hScore1", 0); hScore2 = highScores.getInt("hScore2", 0); hScore3 = highScores.getInt("hScore3", 0);

hScore1Date = highScores.getString("hScore1Date", "0"); hScore2Date = highScores.getString("hScore2Date", "0"); hScore3Date = highScores.getString("hScore3Date", "0"); Calendar currentDate = Calendar.getInstance();

Date dateNow = currentDate.getTime(); if(score > hScore3){

hScore3 = score;

hScore3Date = dateNow.toString(); }

if(hScore3 > hScore2){ aux = hScore2;

auxDate = hScore2Date; hScore2 = hScore3;

hScore2Date = hScore3Date; hScore3 = aux;

hScore3Date = auxDate; }

if(hScore2 > hScore1){ aux = hScore1;

auxDate = hScore1Date; hScore1 = hScore2;

(8)

hScore2 = aux;

hScore2Date = auxDate; }

SharedPreferences.Editor editor = highScores.edit(); editor.putInt("hScore1", hScore1);

editor.putInt("hScore2", hScore2); editor.putInt("hScore3", hScore3);

editor.putString("hScore1Date", hScore1Date); editor.putString("hScore2Date", hScore1Date); editor.putString("hScore3Date", hScore1Date); editor.commit();

return true; }

//Look for complete rows public boolean lookForRows(){

boolean somethingRemoved = false; //To determine if some row has been removed to keep the combo

boolean full = true;

for (int i = 1; i < 20; i++){ full = true;

for (int j = 0; j < 10; j++){

if (box[i][j].getColor() == Values.COLOR_NONE)

full = false;

}

if (full == true){

somethingRemoved = true;

removeRow(i);

}

}

return somethingRemoved; }

//Remove row and score

public void removeRow(int row){

score = score + Values.SCORE_PER_ROW * combo; textScore.setText(Integer.toString(score)); //Setcombo multiplier

combo = combo * 2; if (combo == 32) combo = 16; switch (combo){ case 2:

imageCombo.setImageResource(R.drawable.x2);

break;

case 4:

imageCombo.setImageResource(R.drawable.x4);

break;

case 8:

imageCombo.setImageResource(R.drawable.x8);

break;

case 16:

imageCombo.setImageResource(R.drawable.x16);

break;

}

for (int i = row; i > 1; i--)

(9)

box[i][j].setColor(box[i - 1][j].getColor()); gameBoard.setColor(i, j, (byte) box[i - 1][j].getColor());

}

}

//Redraw the screen public void reDraw(){

//Read where the piece is and colorize for (int i = 0; i < 20; i++)

for (int j = 0; j < 10; j++){

if (currentPiece.box[i][j] == true){

box[i][j].setColor(currentPiece.getColor()); gameBoard.setColor(i, j, currentPiece.getColor());

}

} }

//Undraw the current piece before moving public void unDraw(){

for (int i = 0; i < 20; i++)

for (int j = 0; j < 10; j++){

if (currentPiece.box[i][j] == true){ box[i][j].setColor(0);

gameBoard.setColor(i, j, (byte) 0);

}

} }

private void startTask(AudioClipListener detector) {

stopAll();

recordAudioTask = new RecordAudioTask(this); //wrap the detector to show some output

List<AudioClipListener> observers = new ArrayList<AudioClipListener>();

OneDetectorManyObservers wrapped =

new OneDetectorManyObservers(detector, observers); recordAudioTask.execute(wrapped);

}

private void stopAll() {

//Log.d(TAG, "stop record audio");

shutDownTaskIfNecessary(recordAudioTask); }

private void shutDownTaskIfNecessary(final AsyncTask task) {

if ( (task != null) && (!task.isCancelled())) {

if ((task.getStatus().equals(AsyncTask.Status.RUNNING)) || (task.getStatus()

.equals(AsyncTask.Status.PENDING))) {

(10)

task.cancel(true); }

else {

//Log.d(TAG, "task not running"); }

} }

private void cekFileDatabase(){

File dbFile = new File

("data/data/android.tetris/codebook/codebook.cbk");

if (dbFile.exists()){

System.out.println(" database file already exist, No need to create");

} else {

try {

copyFileDatabase();

} catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace();

} }

}

private void copyFileDatabase() throws IOException{

AssetManager asset = getAssets(); String[] files1 = null;

String[] files2 = null;

File codebookFile = new File ("data/data/android.tetris/codebook/"); codebookFile.mkdirs();

File hmmFile = new File ("data/data/android.tetris/hmm/"); hmmFile.mkdirs();

try {

files1 = asset.list("codebook") ;

if (files1 != null) {

for ( int i = 0;i<files1.length;i++) {

Log.d("",files1[i]);

InputStream in = asset.open("codebook/" + files1[i]); OutputStream out = new FileOutputStream(codebookFile +"/"+ files1[i]);

(11)

in.close(); in = null; out.flush(); out.close();

System.out.println("Copy File Database " + files1[i] + "Sukses");

} }

} catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace();

}

try {

files2 = asset.list("hmm"); if (files2 != null)

{

for ( int i = 0;i<files2.length;i++) {

Log.d("",files2[i]);

InputStream in = asset.open("hmm/" + files2[i]); OutputStream out = new FileOutputStream(hmmFile +"/" + files2[i]);

copyFile(in,out); in.close(); in = null; out.flush(); out.close();

System.out.println("Copy File Database " + files2[i] + " Sukses");

} }

} catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace();

}

}

private void copyFile(InputStream in, OutputStream out) throws IOException {

byte[] buffer = new byte [1024]; int read;

while ((read = in.read(buffer)) != -1){ out.write(buffer,0,read);

} }

(12)

}

MFCC.java

/*

Please feel free to use/modify this class.

If you give me credit by keeping this information or

by sending me an email before using it or by reporting bugs , i will be happy.

Email : gtiwari333@gmail.com,

Blog : http://ganeshtiwaridotcomdotnp.blogspot.com/ */

package audio.feature;

/** *

* @author Ganesh Tiwari *

*/

public class MFCC {

private int numMelFilters = 30;// how much private int numCepstra;// number of mfcc coeffs private double preEmphasisAlpha = 0.95;

private double lowerFilterFreq = 80.00;// FmelLow private double samplingRate;

private double upperFilterFreq; private double bin[];

private int samplePerFrame; // /////

FFT fft; DCT dct;

public MFCC(int samplePerFrame, int samplingRate, int numCepstra) { this.samplePerFrame = samplePerFrame;

this.samplingRate = samplingRate; this.numCepstra = numCepstra;

upperFilterFreq = samplingRate / 2.0; fft = new FFT();

dct = new DCT(this.numCepstra, numMelFilters); }

public double[] doMFCC(float[] framedSignal) { // Magnitude Spectrum

bin = magnitudeSpectrum(framedSignal); framedSignal = preEmphasis(framedSignal); /*

* cbin=frequencies of the channels in terms of FFT bin indices (cbin[i]

* for the i -th channel) */

// prepare filter for for melFilter

(13)

// process Mel Filterbank

double fbank[] = melFilter(bin, cbin); // magnitudeSpectrum and bin filter indices

// System.out.println("after mel filter"); // ArrayWriter.printDoubleArrayToConole(fbank);

// Non-linear transformation

double f[] = nonLinearTransformation(fbank); // System.out.println("after N L T");

// ArrayWriter.printDoubleArrayToConole(f);

// Cepstral coefficients, by DCT double cepc[] = dct.performDCT(f); // System.out.println("after DCT");

// ArrayWriter.printDoubleArrayToConole(cepc); return cepc;

}

private double[] magnitudeSpectrum(float frame[]) { double magSpectrum[] = new double[frame.length]; // calculate FFT for current frame

fft.computeFFT(frame);

// System.err.println("FFT SUCCEED"); // calculate magnitude spectrum

for (int k = 0; k < frame.length; k++) {

magSpectrum[k] = Math.sqrt(fft.real[k] * fft.real[k] + fft.imag[k] * fft.imag[k]);

}

return magSpectrum; }

/**

* emphasize high freq signal *

* @param inputSignal * @return

*/

private float[] preEmphasis(float inputSignal[]) { // System.err.println(" inside pre Emphasis");

float outputSignal[] = new float[inputSignal.length]; // apply pre-emphasis to each sample

for (int n = 1; n < inputSignal.length; n++) { outputSignal[n] = (float) (inputSignal[n] - preEmphasisAlpha * inputSignal[n - 1]);

}

return outputSignal; }

private int[] fftBinIndices() {

int cbin[] = new int[numMelFilters + 2];

cbin[0] = (int) Math.round(lowerFilterFreq / samplingRate * samplePerFrame);// cbin0

cbin[cbin.length - 1] = (samplePerFrame / 2);// cbin24 for (int i = 1; i <= numMelFilters; i++) {// from cbin1 to cbin23

(14)

cbin[i] = (int) Math.round(fc / samplingRate * samplePerFrame);

}

return cbin; }

/**

* performs mel filter operation *

* @param bin

* magnitude spectrum (| |)^2 of fft * @param cbin

* mel filter coeffs

* @return mel filtered coeffs--> filter bank coefficients. */

private double[] melFilter(double bin[], int cbin[]) { double temp[] = new double[numMelFilters + 2]; for (int k = 1; k <= numMelFilters; k++) { double num1 = 0.0, num2 = 0.0;

for (int i = cbin[k - 1]; i <= cbin[k]; i++) { // System.out.println("Inside filter loop"); num1 += ((i - cbin[k - 1] + 1) / (cbin[k] - cbin[k - 1] + 1)) * bin[i];

}

for (int i = cbin[k] + 1; i <= cbin[k + 1]; i++) { // System.out.println("Inside filter loop 222222");

num2 += (1 - ((i - cbin[k]) / (cbin[k + 1] - cbin[k] + 1))) * bin[i];

}

temp[k] = num1 + num2; }

double fbank[] = new double[numMelFilters]; for (int i = 0; i < numMelFilters; i++) { fbank[i] = temp[i + 1];

// System.out.println(fbank[i]); }

return fbank; }

/**

* performs nonlinear transformation *

* @param fbank

* @return f log of filter bac */

private double[] nonLinearTransformation(double fbank[]) { double f[] = new double[fbank.length];

final double FLOOR = -50;

for (int i = 0; i < fbank.length; i++) { f[i] = Math.log(fbank[i]);

// check if ln() returns a value less than the floor if (f[i] < FLOOR) {

f[i] = FLOOR; }

(15)

return f; }

private double centerFreq(int i) { double melFLow, melFHigh;

melFLow = freqToMel(lowerFilterFreq); melFHigh = freqToMel(upperFilterFreq);

double temp = melFLow + ((melFHigh - melFLow) / (numMelFilters + 1)) * i;

return inverseMel(temp); }

private double inverseMel(double x) {

double temp = Math.pow(10, x / 2595) - 1; return 700 * (temp);

}

protected double freqToMel(double freq) { return 2595 * log10(1 + freq / 700); }

private double log10(double value) {

return Math.log(value) / Math.log(10);}}

HiddenMarkov.java

/*

OC Volume - Java Speech Recognition Engine Copyright (c) 2002-2004, OrangeCow organization All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the

distribution.

* Neither the name of the OrangeCow organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

(16)

EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Contact information:

Please visit http://ocvolume.sourceforge.net. */

package classify.speech;

import db.DataBase;

import db.ObjectIODataBase; import util.ArrayWriter;

/**

* last updated on June 15, 2002<br>

* <b>description:</b> this class represents a left-to-right Hidden Markov Model

* and its essential methods for speech recognition. The collection of methods

* include Forward-Backward Algorithm, Baum-Welch Algorithm, Scaling, Viterbi,

* etc.<br>

* <b>calls:</b> none<br>

* <b>called by:</b> volume, train<br> * <b>input:</b> sequence of integers<br> * <b>output:</b> probability

*

* @author Danny Su *

* @modified-by Ganesh Tiwari : DB Operations, Initialization of parameters * Corrected last updated on Dec-27,2010

*/

public class HiddenMarkov { /**

* minimum probability */

// final double MIN_PROBABILITY = 0.00000000001; final double MIN_PROBABILITY = 0.0001;

/**

* length of observation sequence */

protected int len_obSeq; /**

* number of state in the model example: number of urns */

protected int num_states; /**

(17)

* colour balls there are */

protected int num_symbols; /**

* number of states the model is allowed to jump */

protected final int delta = 2; /**

* discrete set of observation symbols example: sequence of colour of balls

*/

protected int obSeq[][]; /**

* current observation sequence */

protected int currentSeq[]; /**

* number of observation sequence */

protected int num_obSeq; /**

* state transition probability example: probability from one state to

* another state */

protected double transition[][]; /**

* discrete output probability example: probability of a specific output

* from a state */

protected double output[][]; /**

* initial state distribution example: which state is the starting state

*/

protected double pi[]; /**

* forward variable alpha */

protected double alpha[][]; /**

* backward variable beta */

protected double beta[][]; /**

* Scale Coefficient */

protected double scaleFactor[]; /**

* variable for viterbi algorithm */

private int psi[][]; /**

* best state sequence */

(18)

/**

* viterbi algorithm used to get best state sequence and probability<br>

* calls: none<br> * called by: volume *

* @param testSeq

* test sequence * @return probability */

public double viterbi(int testSeq[]) { setObSeq(testSeq);

double phi[][] = new double[len_obSeq][num_states]; psi = new int[len_obSeq][num_states];

q = new int[len_obSeq];

for (int i = 0; i < num_states; i++) { double temp = pi[i];

if (temp == 0) {

temp = MIN_PROBABILITY; }

phi[0][i] = Math.log(temp) + Math.log(output[i][currentSeq[0]]);

psi[0][i] = 0; }

for (int t = 1; t < len_obSeq; t++) {

for (int j = 0; j < num_states; j++) { double max = phi[t - 1][0] + Math.log(transition[0][j]);

double temp = 0; int index = 0;

for (int i = 1; i < num_states; i++) {

temp = phi[t - 1][i] + Math.log(transition[i][j]);

if (temp > max) { max = temp; index = i; }

}

phi[t][j] = max + Math.log(output[j][currentSeq[t]]);

psi[t][j] = index; }

}

double max = phi[len_obSeq - 1][0]; double temp = 0;

int index = 0;

for (int i = 1; i < num_states; i++) { temp = phi[len_obSeq - 1][i];

(19)

max = temp; index = i; }

}

q[len_obSeq - 1] = index;

for (int t = len_obSeq - 2; t >= 0; t--) { q[t] = psi[t + 1][q[t + 1]]; }

return max; }

/**

* rescales backward variable beta to prevent underflow<br> * calls: none<br>

* called by: HiddenMarkov *

* @param t

* index number of backward variable beta */

private void rescaleBeta(int t) {

for (int i = 0; i < num_states; i++) { beta[t][i] *= scaleFactor[t]; }

}

/**

* rescales forward variable alpha to prevent underflow<br> * calls: none<br>

* called by: HiddenMarkov *

* @param t

* index number of forward variable alpha */

private void rescaleAlpha(int t) { // calculate scale coefficients

for (int i = 0; i < num_states; i++) { scaleFactor[t] += alpha[t][i]; }

scaleFactor[t] = 1 / scaleFactor[t];

// apply scale coefficients

for (int i = 0; i < num_states; i++) { alpha[t][i] *= scaleFactor[t]; }

}

/**

* returns the probability calculated from the testing sequence<br> * calls: none<br>

* called by: volume *

* @param testSeq

* testing sequence

(20)

*/

public double getProbability(int testSeq[]) { setObSeq(testSeq);

double temp = computeAlpha();

return temp; }

/**

* calculate forward variable alpha<br> * calls: none<br>

* called by: HiddenMarkov *

* @return probability */

protected double computeAlpha() { /**

* Pr(obSeq | model); Probability of the observation sequence given the

* hmm model */

double probability = 0;

// reset scaleFactor[]

for (int t = 0; t < len_obSeq; t++) { scaleFactor[t] = 0;

}

/**

* Initialization: Calculating all alpha variables at time = 0

*/

for (int i = 0; i < num_states; i++) {

// System.out.println("current "+i+" crr "+currentSeq[0]);

alpha[0][i] = pi[i] * output[i][currentSeq[0]]; }

rescaleAlpha(0);

/**

* Induction: */

for (int t = 0; t < len_obSeq - 1; t++) { for (int j = 0; j < num_states; j++) {

/**

* Sum of all alpha[t][i] * transition[i][j] */

double sum = 0;

/**

* Calculate sum of all alpha[t][i] * transition[i][j], 0 <= i <

* num_states */

(21)

sum += alpha[t][i] * transition[i][j];

}

alpha[t + 1][j] = sum * output[j][currentSeq[t + 1]];

}

rescaleAlpha(t + 1); }

/**

* Termination: Calculate Pr(obSeq | model) */

for (int i = 0; i < num_states; i++) {

probability += alpha[len_obSeq - 1][i]; }

probability = 0;

// double totalScaleFactor = 1; for (int t = 0; t < len_obSeq; t++) { // System.out.println("s: " + Math.log(scaleFactor[t]));

probability += Math.log(scaleFactor[t]);

// totalScaleFactor *= scaleFactor[t]; }

return -probability;

// return porbability / totalScaleFactor; }

/**

* calculate backward variable beta for later use with Re-Estimation method<br>

* calls: none<br>

* called by: HiddenMarkov */

protected void computeBeta() { /**

* Initialization: Set all beta variables to 1 at time = len_obSeq - 1

*/

for (int i = 0; i < num_states; i++) { beta[len_obSeq - 1][i] = 1; }

rescaleBeta(len_obSeq - 1);

/**

* Induction: */

for (int t = len_obSeq - 2; t >= 0; t--) { for (int i = 0; i < num_states; i++) {

for (int j = 0; j < num_states; j++) { beta[t][i] += transition[i][j] * output[j][currentSeq[t + 1]] * beta[t + 1][j];

(22)

rescaleBeta(t); }

}

/**

* set the number of training sequences<br> * calls: none<br>

* called by: trainHMM *

* @param k

* number of training sequences */

public void setNumObSeq(int k) { num_obSeq = k;

obSeq = new int[k][]; }

/**

* set a training sequence for re-estimation step<br> * calls: none<br>

* called by: trainHMM *

* @param k

* index representing kth training sequence * @param trainSeq

* training sequence */

public void setTrainSeq(int k, int trainSeq[]) { obSeq[k] = trainSeq;

}

/**

* set training sequences for re-estimation step<br> * calls: none<br>

* called by: trainHMM *

* @param trainSeq

* training sequences */

public void setTrainSeq(int trainSeq[][]) { num_obSeq = trainSeq.length;

obSeq = new int[num_obSeq][];// /ADDED

// System.out.println("num obSeq << setTrainSeq() "+num_obSeq);

for (int k = 0; k < num_obSeq; k++) { obSeq[k] = trainSeq[k]; }

}

/**

* train the hmm model until no more improvement<br> * calls: none<br>

* called by: trainHMM */

public void train() {

// re-estimate 25 times

(23)

for (int i = 0; i < 20; i++) { reestimate();

System.out.println("reestimating..."); }

// // oldm= }

/**

* Baum-Welch Algorithm - Re-estimate (iterative udpate and improvement) of

* HMM parameters<br> * calls: none<br> * called by: trainHMM */

private void reestimate() {

// new probabilities that will be the optimized and replace the older

// version

double newTransition[][] = new double[num_states][num_states];

double newOutput[][] = new double[num_states][num_symbols]; double numerator[] = new double[num_obSeq];

double denominator[] = new double[num_obSeq];

// calculate new transition probability matrix double sumP = 0;

for (int i = 0; i < num_states; i++) {

for (int j = 0; j < num_states; j++) {

if (j < i || j > i + delta) { newTransition[i][j] = 0; }

else {

for (int k = 0; k < num_obSeq; k++) { numerator[k] = denominator[k] = 0;

setObSeq(obSeq[k]);

sumP += computeAlpha(); computeBeta();

for (int t = 0; t < len_obSeq - 1; t++) {

numerator[k] += alpha[t][i] * transition[i][j] * output[j][currentSeq[t + 1]] * beta[t + 1][j];

denominator[k] += alpha[t][i] * beta[t][i];

} }

double denom = 0;

for (int k = 0; k < num_obSeq; k++) { newTransition[i][j] += (1 / sumP) * numerator[k];

denom += (1 / sumP) * denominator[k];

(24)

newTransition[i][j] /= denom; newTransition[i][j] +=

MIN_PROBABILITY;

} }

}

// calculate new output probability matrix sumP = 0;

for (int i = 0; i < num_states; i++) {

for (int j = 0; j < num_symbols; j++) { for (int k = 0; k < num_obSeq; k++) { numerator[k] = denominator[k] = 0; setObSeq(obSeq[k]);

sumP += computeAlpha(); computeBeta();

for (int t = 0; t < len_obSeq - 1; t++) {

if (currentSeq[t] == j) { numerator[k] += alpha[t][i] * beta[t][i];

}

denominator[k] += alpha[t][i] * beta[t][i];

} }

double denom = 0;

for (int k = 0; k < num_obSeq; k++) { newOutput[i][j] += (1 / sumP) * numerator[k];

denom += (1 / sumP) * denominator[k]; }

newOutput[i][j] /= denom;

newOutput[i][j] += MIN_PROBABILITY; }

}

// replace old matrices after re-estimate transition = newTransition;

output = newOutput; }

/**

* set observation sequence<br> * calls: none<br>

* called by: trainHMM *

* @param observationSeq

* observation sequence */

public void setObSeq(int observationSeq[]) { currentSeq = observationSeq;

len_obSeq = observationSeq.length;

(25)

alpha = new double[len_obSeq][num_states]; beta = new double[len_obSeq][num_states]; scaleFactor = new double[len_obSeq]; }

/**

* class constructor - used to create a model from a saved file<br> * calls: none<br>

* called by: volume, trainHMM *

* @param word

* path of the file to load */

public HiddenMarkov(String word) {

DataBase db = new ObjectIODataBase(); db.setType("hmm");

HMMModel model = new HMMModel();

model = (HMMModel) db.readModel(word);// System.out.println(model.getClass());

num_obSeq = model.getNum_obSeq(); output = model.getOutput();//

ArrayWriter.print2DTabbedDoubleArrayToConole(output); transition = model.getTransition(); pi = model.getPi();

num_states = output.length; num_symbols = output[0].length;

// System.out.println("num states :"+num_states+"num symbols :"+num_symbols);

}

/**

* class constructor - used to create a left-to-right model with multiple

* observation sequences for training<br> * calls: none<br>

* called by: trainHMM *

* @param num_states

* number of states in the model * @param num_symbols

* number of symbols per state */

public HiddenMarkov(int num_states, int num_symbols) { this.num_states = num_states;

this.num_symbols = num_symbols;

transition = new double[num_states][num_states]; output = new double[num_states][num_symbols]; pi = new double[num_states];

/**

* in a left-to-right HMM model, the first state is always the initial

* state. e.g. probability = 1 */

pi[0] = 1;

Referensi

Dokumen terkait

ROM terdiri dari fleksi dan ekstensi siku, pronasi dan supinasi lengan bawah, fleksi bahu, adduksi, dan abduksi bahu, rotasi bahu, ekstensi jari jari tangan, inversi dan iversi

Tujuan penelitian ini dilakukan adalah untuk menentukan kadar air dan besar bilangan penyabunan dalam minyak kelapa serta menentukan apakah kadar air dan bilangan penyabunan

The main objectives of this study are the (1) measurement and mapping of the spatial distribution of the deformation rates in the study area; (2) analysis of

Sistem penilaian dengan system KPI, selain dapat mengukur kinerja orang per orang, juga bisa dilakukan untuk melakukan pengukuran kinerja secara kelompok, baik itu

Dengan menggunakan Akibat 2.3 ini, dapat dikonstruksi sebuah aljabar graf pada graf- berhingga baris tanpa sources seperti halnya pada graf berarah, dinotasikan dengan

Level 3 ini aktor harus memakan lebih banyak keju dan dihadapkan dengan musuh yang lebih banyak maka dari itu pada level 3 ini pemain harus lebih berhati-hati

informasi manajemen rumah sakit adalah suatu sistem berbasis komputer yang.. menghasilkan sekumpulan informasi yang telah diolah dan saling

Pada tahap pelaksanaan, kegiatan pembelajaran dibagi menjadi tiga bagian yaitu kegiatan awal, kegiatan inti dan kegiatan penutup. Pada kegiatan awal dimulai dengan