package wav;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Wav {
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// поток 0 main:
//разрешение экрана:	
//Dimension sSize = Toolkit.getDefaultToolkit ().getScreenSize ();
//количество пикселей по горизонтали и вертикали:
static int hor  = 0;
static int vert = 0;
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////поток 2 TX_wav:
//////////////////////////////////////// флаг wav_ON -начальное 0
static int flag_wav_ON = 0;     
//////////////////////////////////////// TX_wav_st счётчик пакетов int: 
static int TX_wav_st = 0;   
//////////////////////////////////////// byte
static byte[] TX_wav = new byte[1000];
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////поток 3 RX_wav:
//////////////////////////////////////// RX_wav_st счётчик пакетов int: 
static int RX_wav_st = 0;   
//////////////////////////////////////// byte
static byte[] RX_wav = new byte[1000];
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// IP_wav:
static String IP_wav = "127.0.0.1";    // ПК                        
//static String IP_wav = "10.0.0.1";   //                       
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////// TX_Ethernet_wav:
public static void TX_Ethernet_wav(DatagramSocket socket1) { 
	 //////////////////////////////////////////////////////// TX: Ethernet 
     try
	 {
       DatagramPacket dp = new DatagramPacket(TX_wav, TX_wav.length, InetAddress.getByName(IP_wav),81);
       socket1.send(dp);                   
	 }catch(IOException e)
	 { 

	 }
}
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// поток 0 Клиент: 
public static void main(String[] args) throws Exception
{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// Ethernet_wav:
        final DatagramSocket socket1 = new DatagramSocket(81);
        //socket1.setSendBufferSize(1);   //размер буфера TX Ethernet_wav
        //socket1.setReceiveBufferSize(1);//размер буфера RX Ethernet_wav
////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////// разрешение экрана:	
	    Dimension sSize = Toolkit.getDefaultToolkit ().getScreenSize ();
	    //количество пикселей по горизонтали и вертикали:
	    hor  = sSize.width;  //int 
	    vert = sSize.height; //int 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// окно_Консоль:	
		final JFrame frame = new JFrame(
		"Консоль " + hor + " x " + vert);  
		//остановить выполнение программы при закрытии окна
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBounds(hor-1010, vert-600, 1000, 545); // x,y,размер,размер 
		//не использует менеджеры по расположению элементов в окно_Консоль
		frame.setLayout(null);
        //фиксированный размер окна JFrame
		frame.setResizable(false);
////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////// окно_Входящие:
		final JFrame frame1 = new JFrame(
		"Входящие " + hor + " x " + vert); 
		frame1.setBounds(hor-1010, vert-1065, 1000, 445); // x,y,размер,размер
		//не использует менеджеры по расположению элементов в окно_Входящие
		frame1.setLayout(null);
        //фиксированный размер окна JFrame 
		frame1.setResizable(false);

		/////////////////////////////////////////////////////////// TextArea "TX"  
		final JTextArea ta = new JTextArea();        //"текст", 10, 20  
//		ta.setBounds(5, 5, 982, 100);                // x,y,размер,размер
		Color RGB_Fon = new Color(253, 245, 230);    // RGB фон     
		ta.setBackground(RGB_Fon);                   // RGB фон 
	    //ta.setBackground(Color.BLUE);              // RGB фон  
	    Color RGB_Text = new Color(25, 25, 112);     // RGB Text
	    ta.setForeground(RGB_Text);                  // RGB Text  
	    //ta.setForeground(Color.BLUE);              // RGB Text
	    // автоперенос на новую строку
//	    ta.setLineWrap(true);                        // true/false
	    // перенос длинных слов на новые строки целиком
//	 	ta.setWrapStyleWord(true);                   // true/false
	 	// шрифт
	 	ta.setFont(new Font("Dialog", Font.PLAIN, 14));
//	 	frame1.add(ta);                              // добавить 
	 	/////////////////////////////////////////////// ScrollPane
	    JScrollPane sp  =  new  JScrollPane (ta);
	    sp.setBounds(5, 5, 982, 100);                // x,y,размер,размер
	    frame1.add(sp);                              // добавить 

	    /////////////////////////////////////////////////////////// TextArea1 "RX"  
		final JTextArea ta1 = new JTextArea();       //"текст", 10, 20 
//		ta1.setBounds(5, 108, 982, 100);             // x,y,размер,размер
		Color RGB_Fon_1 = new Color(253, 245, 230);  // RGB фон     
		ta1.setBackground(RGB_Fon_1);                // RGB фон 
	    //ta.setBackground(Color.BLUE);              // RGB фон  
		Color RGB_Text_1 = new Color(25, 25, 112);   // RGB Text
	    ta1.setForeground(RGB_Text_1);               // RGB Text  
	    //ta1.setForeground(Color.BLUE);             // RGB Text
	    // автоперенос на новую строку
//		ta1.setLineWrap(true);                       // true/false
		// перенос длинных слов на новые строки целиком
//		ta1.setWrapStyleWord(true);                  // true/false
		// шрифт 
		ta1.setFont(new Font("Dialog", Font.PLAIN, 14));
//	    frame1.add(ta1);                             // добавить 
	    /////////////////////////////////////////////// ScrollPane
		JScrollPane sp1  =  new  JScrollPane (ta1);
	    sp1.setBounds(5, 108, 982, 100);             // x,y,размер,размер
	    frame1.add(sp1);                             // добавить 
	    	 	
////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////// Button "wav_ON"
 	   	JButton Button_wav_ON = new JButton("wav_ON");   
 	    Button_wav_ON.setBounds(750, 365, 120, 24);               // x,y,размер,размер  
 	    Button_wav_ON.setFont(new Font("Dialog", Font.PLAIN, 14));// шрифт
        frame.add(Button_wav_ON);                                 // добавить 
        Button_wav_ON.addActionListener(new ActionListener() {    // Слушатель Button   
		public void actionPerformed(ActionEvent event) {
			/////////////////////////////////////////////////////// 
			flag_wav_ON = 1;
		}});
        /////////////////////////////////////////////////////////// Button "wav_OFF"
 	   	JButton Button_wav_OFF = new JButton("wav_OFF");   
 	    Button_wav_OFF.setBounds(750, 395, 120, 24);               // x,y,размер,размер  
 	    Button_wav_OFF.setFont(new Font("Dialog", Font.PLAIN, 14));// шрифт
        frame.add(Button_wav_OFF);                                 // добавить 
        Button_wav_OFF.addActionListener(new ActionListener() {    // Слушатель Button   
		public void actionPerformed(ActionEvent event) {
			/////////////////////////////////////////////////////// 
			flag_wav_ON = 0;
		}});

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// окно_Консоль:
		frame.setVisible(true);     // true/false // включить окно_Консоль           
///////////////////////////////////////////////////////////////// окно_Входящие:
		frame1.setVisible(true);    // true/false // включить окно_Входящие //          
////////////////////////////////////////////////////////////////////////////////

		
		

////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////поток 2 TX_wav:
Thread Thready_2 = new Thread(new Runnable()
{
  public void run() // поток 2
  {
  	  //8000,11025,16000,22050,44100
	  //////////////////////////////////////////////////////// TX_wav:
      //PCM_UNSIGNED 8000.0 Hz, 8 bit, mono, 1 bytes/frame      
  	  //int sampleRate_TX = 8000;    //8000 
  	  int sampleRate_TX = 16000;     //16000 
  	  int sampleSizeInBits_TX = 8;   //бит
      //int sampleSizeInBits_TX = 16;//бит
      int channels_TX = 1;           //1 моно, 2 стерео 
      boolean signed_TX = false;     //false-без знака(0...255)(8бит-PCM_UNSIGNED)  
      //boolean signed_TX = true;    //true-знак(32768...+32767)(16бит-PCM_SIGNED)  
      boolean bigEndian_TX = false;  //true big-endian;(MSB)//false little-endian (LSB)//порядок байт
      AudioFormat format_TX = 
      new AudioFormat(sampleRate_TX, sampleSizeInBits_TX, channels_TX, signed_TX, bigEndian_TX);
	  //////////////////////////////////////////////////////// TX_wav:
      //строка данных - для чтения захваченных данные из буфера целевой строки данных.
      TargetDataLine line_TX = null;
      DataLine.Info info_TX = new DataLine.Info(TargetDataLine.class, format_TX);  
	  //////////////////////////////////////////////////////// TX_wav:
	  try {
		line_TX = (TargetDataLine)AudioSystem.getLine(info_TX);
	  } catch (LineUnavailableException e) {
		e.printStackTrace();
	  }
	  //////////////////////////////////////////////////////// TX_wav:
	  try {
		line_TX.open(format_TX);
	  } catch (LineUnavailableException e) {
		e.printStackTrace();
	  }
	  //////////////////////////////////////////////////////// TX_wav:
      while(true)   
      {
    	line_TX.stop(); 
        ////////////////////////////////////////////////////// ждём flag_wav_ON:
        while(flag_wav_ON == 0) {
          // останавливает поток на ms.
          try {Thread.sleep(1000);} // CPU !
          catch (InterruptedException e3) {} 
        }; 
  	    ////////////////////////////////////////////////////// TX_wav:
		line_TX.start();    
		//line_TX.stop();
        //line_TX.close();
		//Считывает аудиоданные из входного буфера линии передачи данных.// ждём...
	    //line_TX.read(wav_TX, 0, wav_TX.length);  
		////////////////////////////////////////////////////// TX_wav:
	    while(flag_wav_ON == 1)   
	    {
	  	    ////////////////////////////////////////////////// TX_wav:
		    line_TX.read(TX_wav, 0, TX_wav.length);         // (микрофон)
		    ////////////////////////////////////////////////// TX_wav_st счётчик пакетов: 
		    TX_wav_st ++;   
		    if (TX_wav_st > 0xFFFF){TX_wav_st = 0;};
		    ta.setText("TX_wav_st " + TX_wav_st);           // > TextArea 
			////////////////////////////////////////////////// TX_wav:
	    	TX_Ethernet_wav(socket1);// > TX_Ethernet_wav 
	  	    //////////////////////////////////////////////////  
	    }
    ////////////////////////////////////////////////////////// 
    } //while(true) 
  }  //run()
}); //Thread(new Runnable()
Thready_2.start();	// start поток 2
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////поток 3 RX_wav:
Thread Thready_3 = new Thread(new Runnable()
{
  public void run() // поток 3
  {
      //8000,11025,16000,22050,44100
	  //////////////////////////////////////////////////////// RX_wav:
	  //PCM_UNSIGNED 8000.0 Hz, 8 bit, mono, 1 bytes/frame      
  	  //int sampleRate_RX = 8000;    //8000 
      int sampleRate_RX = 16000;     //16000 
      int sampleSizeInBits_RX = 8;   //бит
      //int sampleSizeInBits_RX = 16;//бит
      int channels_RX = 1;           //1 моно, 2 стерео 
      boolean signed_RX = false;     //false-без знака(0...255)(8бит-PCM_UNSIGNED)  
      //boolean signed_RX = true;    //true-знак(32768...+32767)(16бит-PCM_SIGNED)  
      boolean bigEndian_RX = false;  //true big-endian; (MSB)//false little-endian (LSB)//порядок байт
      AudioFormat format_RX = 
      new AudioFormat(sampleRate_RX, sampleSizeInBits_RX, channels_RX, signed_RX, bigEndian_RX);
	  //////////////////////////////////////////////////////// RX_wav:
      //строка данных - для записи данных в буфер целевой строки данных.
	  SourceDataLine line_RX = null;
      DataLine.Info info_RX = new DataLine.Info(SourceDataLine.class, format_RX);  
	  //////////////////////////////////////////////////////// RX_wav:
      try {
		line_RX = (SourceDataLine)AudioSystem.getLine(info_RX);
	  } catch (LineUnavailableException e1) {
		e1.printStackTrace();
	  }
	  //////////////////////////////////////////////////////// RX_wav:
	  try {
		line_RX.open(format_RX);
	  } catch (LineUnavailableException e1) {
		e1.printStackTrace();
	  }
	  //////////////////////////////////////////////////////// RX_wav:
      while(true)   
      {
  		line_RX.stop();
        ////////////////////////////////////////////////////// ждём flag_wav_ON:
   		while(flag_wav_ON == 0) {
          // останавливает поток на ms.
          try {Thread.sleep(1000);} // CPU !
          catch (InterruptedException e3) {} 
        }; 
        ////////////////////////////////////////////////////// RX_wav:
        line_RX.start();   
		//line_RX.stop();
        //line_RX.close();
		//Запись аудиоданных в выходной буфер линии передачи данных.// ждём...
	    //line_RX.write(wav_RX, 0, wav_RX.length);  
        ////////////////////////////////////////////////////// RX_wav:
	    while(flag_wav_ON == 1)  
	    {
		    DatagramPacket reply1 = new DatagramPacket(RX_wav, RX_wav.length);//1500 Ethernet 
		    ////////////////////////////////////////////////// RX: Ethernet
		    try
		    {
		      socket1.receive(reply1);
		    }catch(IOException e)
		    {

		    }
		    ////////////////////////////////////////////////// RX Ethernet END  
		    ////////////////////////////////////////////////// RX: RX_st счётчик пакетов: 
		    RX_wav_st++;   
		    if (RX_wav_st > 0xFFFF){RX_wav_st = 0;};
		    ta1.setText("RX_wav_st " + RX_wav_st);          // > TextArea 
			////////////////////////////////////////////////// RX_wav:
		    line_RX.write(RX_wav, 0, RX_wav.length);        // (динамик) 
		    ////////////////////////////////////////////////// 
	     }
	////////////////////////////////////////////////////////// 
    } //while(true) 
  }  //run()
}); //Thread(new Runnable()
Thready_3.start();	// start поток 3
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
}
}


/*
////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// формат wav:
int[] wav_int = new int [44];  
/////////////////////////////////////////////////////////////// Data = 126.252 -8
///////////////////////// RIFF (4 байт)
wav_int[0]  = 0x52; // R
wav_int[1]  = 0x49; // I
wav_int[2]  = 0x46; // F 
wav_int[3]  = 0x46; // F
///////////////////////// Data Size (4 байт) 00 01 ED 24 = 126.244
wav_int[4]  = 0x24; //  
wav_int[5]  = 0xED; //   
wav_int[6]  = 0x01; //  
wav_int[7]  = 0x00; //  
/////////////////////////////////////////////////////////////// Data = 126.244 -32
///////////////////////// WAVE (4 байт)
wav_int[8]  = 0x57; // W  
wav_int[9]  = 0x41; // A 
wav_int[10] = 0x56; // V 
wav_int[11] = 0x45; // E 
///////////////////////// секция формата ("fmt") (4 байт)
wav_int[12] = 0x66; // f 
wav_int[13] = 0x6D; // m 
wav_int[14] = 0x74; // t  
wav_int[15] = 0x20; //  
///////////////////////// Data Size (4 байт)
wav_int[16] = 0x10; //  
wav_int[17] = 0x00; //  
wav_int[18] = 0x00; //  
wav_int[19] = 0x00; //  
///////////////////////// Код сжатия (Compression Code)	1 - 65,535 (2 байт) 1 = PCM/uncompressed
wav_int[20] = 0x01; // PCM/uncompressed
wav_int[21] = 0x00; //  
///////////////////////// Количество каналов (Number of Channels) 1 - 65,535 (2 байт) 1 моно, 2 стерео
wav_int[22] = 0x01; // 1 mono // 2 стерео 
wav_int[23] = 0x00; //  
///////////////////////// Скорость выборок (Sample Rate) 1 - 0xFFFFFFFF (4 байт) 1F 40 = 8000
wav_int[24] = 0x40; //0x40 8000 семпл в секунду
wav_int[25] = 0x1F; //0x1F 8000 семпл в секунду 
wav_int[26] = 0x00; //  
wav_int[27] = 0x00; //   
///////////////////////// Среднее количество байт в секунду (Average Bytes Per Second) 1 - 0xFFFFFFFF (4 байт) 3E 80 = 16000
wav_int[28] = 0x40; //0x40 8000  //0x80 16000  байт в секунду
wav_int[29] = 0x1F; //0x1F 8000  //0x3E 16000  байт в секунду
wav_int[30] = 0x00; //   
wav_int[31] = 0x00; //   
///////////////////////// Количество байт на одну выборку (Block Align) 1 - 65,535 (2 байт) 
wav_int[32] = 0x01; //0x01 1 bytes/frame  //0x02 2 bytes/frame   
wav_int[33] = 0x00; //   
///////////////////////// Количество бит на выборку (Significant Bits Per Sample) 1 - 65,535 (2 байт) 
wav_int[34] = 0x08; //0x08 8 бит на выборку //0x10 16 бит на выборку 
wav_int[35] = 0x00; //  
///////////////////////// Секция данных ("data")
wav_int[36] = 0x64; // d 
wav_int[37] = 0x61; // a 
wav_int[38] = 0x74; // t  
wav_int[39] = 0x61; // a 
///////////////////////// dword 01 ED 00 = 126.208
wav_int[40] = 0x00; //  
wav_int[41] = 0xED; //   
wav_int[42] = 0x01; //   
wav_int[43] = 0x00; //   
/////////////////////////////////////////////////////////////// Data = 126.208
///////////////////////// Data...
////////////////////////////////////////////////////////////////////////////////////
*/
