//
/* ---------------------------------------------------------------------------------------------- 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(247,255,247)); // 背景色 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.clearRect(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.clearRect(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; r戻る0) 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; } } } //