//
/* ----------------------------------------------------------------------------------------------
pcm.java パルス符号変調 ver. 1.00 (JDK 1.02)
ueyama@infonet.co.jp 1998.12.12
---------------------------------------------------------------------------------------------- */
import java.applet.Applet;
import java.awt.*;
import java.lang.Math;
import java.util.*;
public class pcm extends Applet implements Runnable
{
int i,j;
int Wait=1024;
int Ww,Wh; // applet の幅と高さ
int Ebdx=260,Ebdy=260,Ebdh=30; // Encode の2進数表示位置、サイズ
int Step=0; // PCM Step
int Pitch=16; // サンプリングピッチ(単位:Pixel)
int Q_bit=16; // 量子化ビット数 (単位:Pixel)
int Fn=5; // 2進数桁数
int Ac=100; // double を int で 1/100 まで表示
int Qp=4; // Pitch / 4
int R1=0,R2=0; // mouse で select された 角度(r)
int Q0=0; // 標本化値
int Dr=0; // 符号化の表示角度
int Cx=32; // コメント表示 X 座標値
boolean Run=false; // t: 符号化 f: その他
boolean Rf=true; // t: random wave f: sin wave
int Mx=0; // マウス X 座標の Pitch 整数倍値
int Wf[]=new int[361];
double Wa[]=new double[16];
Color col[]={new Color(170,170,96),/*波形色*/ new Color(224,192,128),/*標本化色*/
new Color(144,112,48),/*量子化色*/ new Color(192,160,96), /*標本化選択色*/
new Color(96,64,16), /*量子化選択色*/};
Button bt_h_fine, bt_h_rough, bt_v_fine, bt_v_rough, bt_sin, bt_random, bt_clear, bt_step;
Button bt_slow, bt_fast;
Graphics gr;
Image Comm; // 文字表示用 (pcm.gif)
Thread th=null;
public void start()
{
if(th==null)
{
th=new Thread(this);
th.start();
}
}
public void init()
{
Ww=size().width; Wh=size().height;
setBackground(new Color(255,255,232)); // 背景色
gr=getGraphics();
MediaTracker mt=new MediaTracker(this);
Comm=getImage(getCodeBase(),"pcm.gif");
mt.addImage(Comm, 0);
try
{
mt.waitForID(0);
}
catch(InterruptedException e){};
Panel p=new Panel();
p.add(bt_slow =new Button("<<"));
p.add(bt_fast =new Button(">>"));
p.add(bt_h_rough=new Button("H Rough"));
p.add(bt_h_fine =new Button("H Fine"));
p.add(bt_v_rough=new Button("V Rough"));
p.add(bt_v_fine =new Button("V Fine"));
p.add(bt_sin =new Button("SIN Wave"));
p.add(bt_random =new Button("RND Wave"));
p.add(bt_clear =new Button("CLEAR"));
p.add(bt_step =new Button("STEP"));
setLayout(new BorderLayout());
add("South",p);
Wa[0]=1.0;
new_wave();
}
public void new_wave() // 新規波形の発生
{
int max=0;
double a,e,s,v;
Random r=new Random();
e=(Rf)?0.333:0.0; // SIN 波形の場合は高調波振幅=0
for(i=1;i<16;i++) // 高調波の振幅比を乱数で決める
{
s =r.nextDouble();
Wa[i]=r.nextDouble()*e;
Wa[i]*=(s<0.5)?1.0:-1.0;
e*=0.81;
}
for(i=0;i<360;i++) // 各角度の振幅値を計算する
{
a=(double)i*3.14159/180; v=0.0;
for(j=0;j<16;j++) v+=Wa[j]*Math.sin(a*(double)(j+1))*128*Ac;
Wf[i]=(int)v;
if(Wf[i]>max) max=Wf[i];
}
for(i=0;i<360;i++) {Wf[i]*=120*Ac; Wf[i]/=max; Wf[i]+=128*Ac;}
}
public void draw_wave() // 波形表示
{
int r;
gr.setColor(col[0]);
for(r=0;r<720-1;r++)
{
if(Step>0) gr.drawLine(r,256-py(r),r+1,256-py(r+1));
else
{
for(i=-1;i<2;i++) for(j=-1;j<2;j++) gr.drawLine(r+i,256-py(r)+j,r+1+i,256-py(r+1)+j);
}
}
}
public int py(int a) // 角度 a における y 座標値
{
return Wf[a%360]/Ac;
}
public void dsp_comm(int x, int n, int l) // コメントの表示
{ // n=0:原波形 1:標本化 2:量子化 3:符号化
Graphics gx=gr.create();
gx.clipRect(x,262,23*l,22);
gx.drawImage(Comm,x-n*92,262,this);
gx.dispose();
}
public void dsp_n(int n) // 数値の表示
{
Graphics gx=gr.create();
gx.clipRect(Cx,262,18,22);
gx.drawImage(Comm,Cx-(368+n*18),262,this);
gx.dispose();
Cx+=(n==10)? 8:18;
}
public int dsp_bq(int r, int c) // 量子化グラフの表示
{
int p=(py(r)%Q_bit+Q_bit/2)/Q_bit*Q_bit;
int q=py(r)/Q_bit*Q_bit+p;
gr.setColor(col[c]);
gr.fillRect(r-Qp,256-q, Qp*2+1,q);
return q;
}
public void dsp_b(int x, int y, int c, boolean f) // 棒グラフの表示
{
gr.setColor(col[c]);
if(f) gr.fillRect(x-Qp,256-y, Qp*2+1,y);
}
public void paint(Graphics g)
{
int p,q,r,x,y;
g.clearRect(0,0,Ww,Wh);
g.setColor(new Color(224,224,192)); // 格子を描く
for(i=1;i<=256/Q_bit;i++) g.drawLine(0,i*Q_bit, Ww,i*Q_bit);
for(r=0;r<720;r+=Pitch) g.drawLine(r,256, r,0);
if(Step>0) for(r=0;r<720;r+=Pitch) dsp_b(r,py(r),1,true); // 標本化
if(Step>1) for(r=0;r<720;r+=Pitch) dsp_bq(r,2); // 量子化
if(Step<3) dsp_comm(32,Step,3);
draw_wave();
}
public void run()
{
while(th!=null)
{
if(Run) dsp_e();
try
{
th.sleep(Wait);
}
catch (InterruptedException e){}
if(Run)
{
Dr+=Pitch;
if(Dr>=720) Dr=0;
}
}
}
public void dsp_s(int n) // 標本化値表示
{
int r,y;
String rm;
y=Wf[n%360]; y*=100; y/=256;
rm=y/Ac+"."+((y%Ac<10)?"0":"")+y%Ac;
dsp_comm(32,1,4);
for(Cx=140,r=0; r0) draw_wave();
}
Mx=r;
}
return true;
}
public boolean action(Event e, Object o)
{
boolean rpf=true;
if(e.target==bt_slow)
{
Wait*=2; bt_fast.enable(); rpf=false;
if(Wait==8192) bt_slow.disable();
showStatus("wait: "+(float)Wait/1024.0+"sec.");
}
else if(e.target==bt_fast)
{
Wait/=2; bt_slow.enable(); rpf=false;
if(Wait==32) bt_fast.disable();
showStatus("wait: "+(float)Wait/1024.0+"sec.");
}
else if(e.target==bt_h_rough)
{
Pitch*=2; bt_h_fine.enable();
if(Pitch==64) bt_h_rough.disable();
}
else if(e.target==bt_h_fine && Pitch>4)
{
Pitch/=2; bt_h_rough.enable();
if(Pitch==4) bt_h_fine.disable();
}
else if(e.target==bt_v_rough)
{
Q_bit*=2; Fn--; bt_v_fine.enable();
if(Q_bit==64) bt_v_rough.disable();
}
else if(e.target==bt_v_fine)
{
Q_bit/=2; Fn++; bt_v_rough.enable();
if(Q_bit==4) bt_v_fine.disable();
}
else if(e.target==bt_sin)
{
Rf=false; Dr=0; new_wave();
}
else if(e.target==bt_random)
{
Rf=true; Dr=0; new_wave();
}
else if(e.target==bt_clear)
{
Step=0; Dr=0; bt_step.enable(); Run=false; R1=0; R2=0;
}
else if(e.target==bt_step)
{
Step++;
if(Step==3)
{
Run=true;
bt_step.disable();
}
else
{
gr.clearRect(0,Ebdy,Ww,Ebdh);
dsp_comm(32,Step,3);
}
}
Qp=Pitch/4;
if(rpf) repaint();
return true;
}
public void stop()
{
if(th!=null)
{
th.stop();
th=null;
}
}
}
// 戻る