Word to Phoneme for Indonesian Language

Tulisan ini menampilkan algoritma untuk melakukan pemisahan fonem dari kata dalam bahasa Indonesia. Fonem merupakan satuan bahasa yang mendeskripsikan bunyi yang dikeluarkan oleh organ penghasil suara. Fonem terdiri dari beberapa huruf. Kode yang ditampilkan telah diuji dengan Borland Delphi 7.

persoalan datangnya dari forum delphi-id oleh indray2j

Bro sekalian help me neh, bantuin skripsi..
ada yang punya source untuk parsing vonem gak ya???
jadi bisa membaca suara, misalkan kita masukin kata : ‘sebenarnya’.
trus dia bisa baca ambil dari database, trus ngucapin : se – be – nar – nya.
please bgt, thanks

skrinsyut hasil program

Kode berikut menampilkan kamus data yang digunakan.

type
  { tipe data enumerasi }
  kartype = (kVokal, kKonsonan);

var
  s_in	: string;	{ masukan berupa string }
  s_buf : string;	{ penampung sementara }
  s_out : TStrings; { keluaran berupa list of string }
  i : integer;		{ pencacah }
  last : kartype; 	{ tipe karakter terakhir }
  len : integer; 	{ panjang kata }

Beberapa fungsi predikat dibuat terpisah dari algoritma utama.

  function is_vokal(cc:char):boolean;
  begin
    result := cc in ['a', 'i', 'u', 'e', 'o'];
  end;
  function is_alpha(cc:char):boolean;
  begin
    { simbol # dan $ merupakan diftong 'ng' dan 'ny' }
    result := cc in ['a'..'z', '#', '$', '@', '!', '%'];
  end;

Algoritma utama dimulai oleh kode berikut.

begin

Langkah awal yang dilakukan adalah mengganti diftong ‘ng’ dan ‘ny’ menjadi simbol lain (karakter ‘#’ dan ‘$’) yang dianggap sebagai konsonan.

  s_out := TStringlist.Create;
  s_in  := lowercase(Edit1.Text);

  { fase 0 : pre-proses diftong }
  s_in := StringReplace(s_in, 'ng', '#', [rfReplaceAll]);
  s_in := StringReplace(s_in, 'ny', '$', [rfReplaceAll]);
  s_in := StringReplace(s_in, 'gr', '@', [rfReplaceAll]);
  s_in := StringReplace(s_in, 'pl', '!', [rfReplaceAll]);
  s_in := StringReplace(s_in, 'tr', '%', [rfReplaceAll]);

Algoritma utama pemisahan fonem adalah sebagai berikut :

  • setiap fonem diakhiri oleh karakter vokal (aiueo)
  • jika terjadi pengulangan karakter konsonan maka karakter tersebut dipisah

  { fase 1 : proses pemisahan }
  s_buf := '';
  i := 1;
  len := length(s_in);
  last := kVokal;
  if (len > 0) then
  while (i < len) do begin
    if is_vokal(s_in[i]) then begin
      s_buf := s_buf + s_in[i];
      s_out.Add(s_buf);
      s_buf := '';
      last := kVokal;
    end else begin//konsonan
      if (last = kKonsonan) then begin
        s_out.Add(s_buf);
        s_buf := s_in[i];
      end else begin
        s_buf := s_buf + s_in[i];
      end;
      last := kKonsonan;
    end;
    inc(i);
  end;
  { append last character }
  s_buf := s_buf + s_in[i];
  s_out.Add(s_buf);

Setelah pemisahan dilakukan, data yang dihasilkan masih perlu diproses lebih lanjut untuk memperbaiki fonem-fonem yang disusun oleh satu karakter khususnya konsonan.

  { fase 2 : filtering }
  { tangani kasus fonem pertama adalah 1 huruf konsonan }
  s_buf := s_out[0];
  if (length(s_buf) = 1)
  and not is_vokal(s_buf[1]) then begin
    s_out[1] := s_buf + s_out[1];
    s_out.Delete(0);
  end;
  { tangani kasus fonem ke-n adalah 1 huruf konsonan }
  i := 1;
  while (i < s_out.Count) do begin
    s_buf := s_out[i];
    if (length(s_buf)=1) 
    and not is_vokal(s_buf[1]) then begin
	  s_out[i-1] := s_out[i-1] + s_buf;
      s_out.Delete(i);
      continue;
    end;
    inc(i);
  end;

Langkah terakhir yang dilakukan adalah mengembalikan karakter sementara sebagai pengganti diftong ke bentuk aslinya.

  { fase 3 : post-proses }
  { restore }
  s_in := StringReplace(s_in, '#', 'ng', [rfReplaceAll]);
  s_in := StringReplace(s_in, '$', 'ny', [rfReplaceAll]);
  s_in := StringReplace(s_in, '@', 'gr', [rfReplaceAll]);
  s_in := StringReplace(s_in, '!', 'pl', [rfReplaceAll]);
  s_in := StringReplace(s_in, '%', 'tr', [rfReplaceAll]);
  for i := 0 to s_out.Count-1 do begin
    s_buf := s_out[i];
    s_buf := StringReplace(s_buf, '#', 'ng', [rfReplaceAll]);
    s_buf := StringReplace(s_buf, '$', 'ny', [rfReplaceAll]);
    s_buf := StringReplace(s_buf, '@', 'gr', [rfReplaceAll]);
    s_buf := StringReplace(s_buf, '!', 'pl', [rfReplaceAll]);
    s_buf := StringReplace(s_buf, '%', 'tr', [rfReplaceAll]);
    s_out[i] := s_buf;
  end;

Kode di bawah ini menampilkan keluaran pada komponen TMemo.

  { tampilkan keluaran }
  s_out.Delimiter := '-';
  memo1.Lines.Add(s_in+' menjadi '+s_out.DelimitedText);
  s_out.Free;

end;

Wassalam,

7 comments

  1. indra jaya · Agustus 8, 2007

    Bro pebbie terimakasih atas referensinya untuk permasalahan saya, saya akan coba implementasikan algoritma ini kedalam program saya..
    Saya rasa program skripsi yang saya buat terbantu dengan referensi ini, terimakasih ^^

  2. irfin · Februari 4, 2009

    very nice.

  3. bree · November 17, 2011

    itu kan untuk per kata.,kalau dari kalimat menjadi fonem bagaimana?mohon balasannya .tq

    • pebbie · November 17, 2011

      kalau jadi kalimat perlu di-tokenisasi dulu, supaya dapat kata-per-kata atau tanda baca

  4. Neal Tungtung · Maret 13, 2015

    terimakasih mas.atas referensinya hhe
    akhirnya program skripsi saya terbantu dengan adanya artikel mas ^_^

    cmn saya mau mengembangkan untuk pemenggalan kalimat mas, baimna ya?
    ditokenisasi maksudnya gmn mas?🙂

    • pebbie · Maret 13, 2015

      sama2..

      di-tokenisasi maksudnya dipecah menjadi satuan yang lebih kecil (dari kalimat menjadi list kata)

      • Neal Tungtung · Maret 20, 2015

        biar ada spasinya gitu mas
        inikan misalnya buat jalanjalan = ja-lan-ja-lan (dalam penggalan suku kata sih udah betul prosesnya)
        tp klo ada spasi jalan jalan = ja-“lan “-ja-lan

        yg saya bingungnya, knp petiknya ngikut ya
        bknnya itu sbagai batas simpanan smntara ya mas?

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s