import java.applet.Applet; import java.awt.*; import java.lang.Math; import java.lang.Integer; import sun.audio.*; import java.util.Random; public class asynth07 extends java.applet.Applet implements Runnable { /* GLOBALE VARIABLER */ Choice algo = new Choice(); Choice env = new Choice(); Choice lng = new Choice(); Button B_comp = new Button("make sound"); Button B_play = new Button("-"); /* play /stop sound */ boolean overload = false; boolean loop =false; boolean first =true; boolean going = false; Random r = new Random(); int varlng = (int)(10000*r.nextDouble()); int arrmax = 32000; /* (30000+varlng);*/ /* en cyklus på 5 sek. virker ok */ int arrlng = arrmax; /* max længden af data */ byte arrud[] = new byte[arrmax]; /* bruges til at holde data til soundplay */ AudioData data = new AudioData(arrud); ContinuousAudioDataStream austream = new ContinuousAudioDataStream(data); Label s1 = new Label("2",Label.CENTER); Label s2 = new Label("25",Label.CENTER); Label s3 = new Label("25",Label.CENTER); Label s4 = new Label("7",Label.CENTER); Label l4 = new Label("Overtones",Label.LEFT); Label l5 = new Label("Diffusion",Label.LEFT); Label l6 = new Label("Regularity",Label.LEFT); Label l7 = new Label("Volume",Label.LEFT); /* Scrollbar slider1 = new Scrollbar(orientation, slider1værdi, pageværdi, minværdi, maxværdi); */ Scrollbar slider1 = new Scrollbar(Scrollbar.HORIZONTAL,10, 10, 0, 50); Scrollbar slider2 = new Scrollbar(Scrollbar.HORIZONTAL,5, 5, 0, 50); Scrollbar slider3 = new Scrollbar(Scrollbar.HORIZONTAL,2, 2, 0, 50); Scrollbar slider4 = new Scrollbar(Scrollbar.VERTICAL,2, 2, 0, 10); asynth05canvas pfcanvas = new asynth05canvas(); /* METODER */ public asynth07() { GridBagLayout asynth07 = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setFont(new Font("Times New Roman", Font.PLAIN, 10)); setLayout(asynth07); c.fill = GridBagConstraints.BOTH; /* INDSTIL + ADD BUTTONS + slider1-3 */ c.gridwidth=1; c.gridheight=8; c.weightx=0; asynth07.setConstraints(slider4, c); add(slider4); c.gridwidth=1; c.gridheight=1; c.insets.top=2; c.insets.bottom=0; c.insets.left=0; c.insets.right=2; c.weightx=0; asynth07.setConstraints(l4, c); asynth07.setConstraints(s1, c); c.weightx=1; c.gridwidth = GridBagConstraints.REMAINDER; asynth07.setConstraints(slider1, c); add(l4);add(s1);add(slider1); c.gridwidth=1; c.gridheight=1; c.weightx=0; asynth07.setConstraints(l5, c); asynth07.setConstraints(s2, c); c.weightx=1; c.gridwidth = GridBagConstraints.REMAINDER; asynth07.setConstraints(slider2, c); add(l5);add(s2);add(slider2); c.gridwidth=1; c.gridheight=1; c.weightx=0; asynth07.setConstraints(l6, c); asynth07.setConstraints(s3, c); c.weightx=1; c.gridwidth = GridBagConstraints.REMAINDER; asynth07.setConstraints(slider3, c); add(l6);add(s3);add(slider3); /* INDSTIL CHOICE algo + env + lng */ c.insets.top=0; c.insets.bottom=0; c.gridheight=1; c.gridwidth = GridBagConstraints.REMAINDER; asynth07.setConstraints(algo, c); asynth07.setConstraints(env, c); asynth07.setConstraints(lng, c); asynth07.setConstraints(B_comp, c); algo.addItem("sound algo. 1"); algo.addItem("sound algo. 2"); algo.addItem("sound algo. 3"); algo.addItem("sound algo. 4"); env.addItem("shell 1 envelope"); env.addItem("shell 2 envelope"); env.addItem("linear fade envelope"); env.addItem("linear envelope"); env.addItem("bell 1 envelope"); env.addItem("bell 2 envelope curve"); lng.addItem("long sound"); lng.addItem("medium sound"); lng.addItem("short sound"); add(algo);add(env);add(lng);add(B_comp); /* INITIALISER SLIDER'S: */ /* setvalues(startværdi, pageværdi, minværdi, maxværdi ) */ slider1.setValues(2,0,0,70); slider2.setValues(25,0,0,50); slider3.setValues(25,0,0,50); slider4.setValues(3,1,0,10); } public void soundplay() { if (loop == false) { B_play.setLabel("Stop sound"); AudioPlayer.player.start(austream); loop=true; } else { B_play.setLabel("Play sound"); AudioPlayer.player.stop(austream); loop=false; } } private Thread player_th = null; public void start() { if (player_th == null) { player_th = new Thread(this); first = false; player_th.setPriority(2); player_th.start(); } } public void name(String str) { player_th.setName(str); } public void stop() { going=false; loop=false; AudioPlayer.player.stop(austream); /* afslutter lyden inden der lukkes ned */ if (player_th !=null) player_th.stop(); player_th=null; first=true; } public void run() { int count=0; boolean op=true; double val1,val2,val3,val7,val8,val9,val4,val5,val6,val0; int arr[] = new int[arrmax]; /* LOKAL array */ double vx,vx2,usik,usik2,vib,tmp,envelope,amp_mod; double shel2envelope,linearenvelope; /* bruges i algoritme 4 */ amp_mod = 0.5; /* for at bære bølgen ikke helt skal forsvinde */ /* til konverteringsdelen */ int CLIP = 32635; int BIAS = 0x84; int sign, exponent, mantissa, sample; byte ulawbyte; int exp_lut[] = new int[256]; int lut, rest; if (!(B_comp.getLabel()=="recomputing")) {player_th.suspend();} /* stopper thread indtil comp_B=ned */ /* while løkke - kører for evigt men bliver hver gang suspenderet */ while (true) { B_comp.setLabel("computing"); going= true; /* forhindre knapper i at blive rykket på så længe udregning er igang */ /* VOL */ if ((slider1.getValue())<15) { val3=slider1.getValue()+2; val8=2; val1=50;} else if (slider1.getValue()<33) { val3=12; val8=(int)((slider1.getValue()-15)*1.8)+3; val1=(int)(30+((50-val3-val8)*0.6));} else { val3=((slider1.getValue()-33)*2)+16; val8=slider1.getValue(); val1=(int)(12+((100-val3-val8)*0.3)); } /* MASTER VOL */ val1 = (int)((double)(0.13*(11-slider4.getValue())) * val1); /* FRQ */ if ((slider2.getValue())<10) { val2=slider2.getValue(); val7=0; val9=0;} else if (slider2.getValue()<20) { val2=20-slider2.getValue(); val7=(int)((slider2.getValue()-10)*2); val9=0;} else if (slider2.getValue()<35) { val2=(int)((slider2.getValue()-20)*2.3); val7=20; val9=0;} else { val2=slider2.getValue(); val7=slider2.getValue()-15+((slider2.getValue()-35)*3); val9=(slider2.getValue()-35)*5; } /* MOD */ if ((slider3.getValue())<20) { val6 = 2+slider3.getValue()*1.5; /* chorus volume double*/ val4 = slider3.getValue()*0.5; /* chorus frequenc double*/ val0 = 0.5; /* vibrato volume double */ val5 = 0.5; /* vibrato frequenc double */ } else if (slider3.getValue()<40) { val6 = 27-slider3.getValue()*0.5; /* chorus volume double*/ val4 = ((slider3.getValue()-19.5)*1.5)+10; /* chorus frequenc double */ val0 = (slider3.getValue()-19.5); /* vibrato volume double */ val5 = (slider3.getValue()-19.5)*0.5; /* vibrato frequenc double */ } else { val6 = (slider3.getValue()-39)*4.5; /* chorus volume double*/ val4 = ((slider3.getValue()-40)*7)+30; /* chorus frequenc double */ val0 = 18-(slider3.getValue()-40); /* vibrato volume double */ val5 = 10; /* vibrato frequenc double */ } /* længden af lyden sættes */ if (lng.getSelectedIndex() ==0) {arrlng=arrmax;} if (lng.getSelectedIndex() ==1) {arrlng=(int)(arrmax/2);} if (lng.getSelectedIndex() ==2) {arrlng=(int)(arrmax/4);} usik2=0.00001*val6; /* usik2 giver forskel på vx og vx2 */ usik=0.0001*val6+usik2; envelope=0.0; /* vx=1 ; vx2=1; vib=1; giver nogle gode lyde til algorime 4 */ for (int i=0; i0.95) {tmp=envelope; envelope=tmp*(((double)1)-((double)i)/arrlng)*20; } /* ALGORITMER */ /* HVILKEN ALGORITME SKAL DER BRUGES algo.getSelectedIndex( 0- 3 ) */ switch (algo.getSelectedIndex()) { case 0: /* ALGORITME 1 */ arr[i]=(int) (envelope* ( ( ( Math.sin(vib+ (0.1+(0.01*val9)) * i )*val1) + ( amp_mod*Math.sin(vib+(usik+0.1+(0.05*val9)) * i ) *val1) ) * ( ( Math.sin( (0.0137*val2) * i) *(0.01*val3*(vx+vx2)) ) +1 ) * ( ( Math.sin( (0.0157*val7) * i) *(0.01*val8*(vx+vx2)) ) +1 ) ) ); break; case 1: /* ALGORITME 2 */ arr[i]=(int) (envelope* ( ( ( Math.sin(vib+(double)i* (0.1+(0.01*val9)) )*val1) + ( amp_mod*Math.sin((double)i* (usik+0.1+(0.05*val9) )-(vib/1.7) ) *val1) ) * ( 1 + ( Math.sin((double)i*(0.009963*val2) ) *(0.01*val3*(vx)) ) ) * ( 1 + ( Math.sin((vib/1.5)+(double)i*(0.019917*val7) ) *(0.01*val8*(vx2)) ) ) * ( ( 1 + ( Math.sin((double)i*(0.010071*val2) ) *(0.01*val3*(vx2)) ) ) * ( 1 + ( Math.sin((double)i*(0.020053*val7)-(vib/2) ) *(0.01*val8*(vx)) ) ) ) ) ); break; case 2: /* ALGORITME 3 */ arr[i]=(int) (envelope* ( ( ( Math.sin(vib/2.5+(double)i* (0.1+(0.01*val9)) ) *val1) + ( amp_mod*Math.sin(vib/3.5+(double)i* (usik+0.1+(0.01*val9) ) ) *val1) ) * ( 1 + ( Math.sin((double)i*(0.01*val2)+ ( Math.sin((double)i*(0.01*val7) ) *(0.08*val8) ) ) *(0.01*val3*(vx)) ) ) * ( 1 + ( Math.sin((double)i*((0.02+usik)*val2)+ ( Math.sin((double)i*(0.02*val7) ) *(0.05*val8) ) ) *((0.018-val2/5000)*val3*(vx2)) ) ) * ( 1 + ( Math.sin((double)i*((0.04+usik+usik2)*val2)+ ( Math.sin((double)i*(0.04*val7) ) *(0.03*val8) ) ) *((0.007-val2/8000)*val3*(vx+vx2)) ) ) ) ); break; case 3: /* ALGORITME 4 */ linearenvelope=((double)255-((double)255*i/arrlng))/255; shel2envelope= (1.05*((double)128-( Math.cos(((double)i/arrlng)*6.28)*128 )))/128; vib=vib+0.00001; arr[i]=(int) (0.5*envelope* /* algoritme 3 */ ( ( ( Math.sin(vib/2.5+(double)i* (0.1+(0.01*val9)) ) *val1) + ( amp_mod*Math.sin(vib/3.5+(double)i* (usik+0.1+(0.01*val9) ) ) *val1*shel2envelope) ) * ( 1 + ( Math.sin((double)i*(0.01*val2)+ ( Math.sin((double)i*(0.01001*val7) ) *(0.08*val8*shel2envelope) ) ) *(0.01*val3*linearenvelope*(vx)) ) ) * ( 1 + ( Math.sin((double)i*((0.02003+usik)*val2)+ ( Math.sin((double)i*(0.02*val7) ) *(0.05*val8*shel2envelope) ) ) *((0.018-val2/5000)*val3*linearenvelope*(vx2)) ) ) * ( 1 + ( Math.sin((double)i*((0.04+usik+usik2)*val2)+ ( Math.sin((double)i*(0.03998*val7) ) *(0.03*val8*shel2envelope) ) ) *((0.007-val2/8000)*val3*linearenvelope*(vx+vx2)) ) ) ) + (0.5*envelope* /* algoritme 1 */ ( ( ( Math.sin(vib+ (0.2+(0.01*val9)) * i )*val1) + ( amp_mod*Math.sin(vib+(usik+0.2001+(0.05*val9)) * i ) *val1) ) * ( ( Math.sin( (0.03*val2) * i) *(0.01*val3*(1-linearenvelope)*(vx+vx2)) ) +1 ) * ( ( Math.sin( (0.06*val7) * i) *(0.01*val8*(1-shel2envelope)*(vx+vx2)) ) +1 ) ) ) ); break; } /* algoritme switch slut */ } /* for i=0; til i=1) { lut=lut+1; exp_lut[i]=lut; rest=rest/2; } } if (loop) { while(austream.available()>5000) {} } /* indtil austream er ved enden - for at undgå kliklyde syncronisere beregner og afspiller */ B_comp.setLabel("---> ---> --->"); /* lyden overføres = spilles */ overload=false; for (int i=0; i> 8) & 0x80; /* finder fortegn */ if (sign != 0) {sample = -sample;} /* get magnitude */ if (sample > CLIP) {sample = CLIP; overload=true;} /* clip the magnitude */ /* Convert from 16 bit linear to ulaw. */ sample = sample + BIAS; exponent = exp_lut[(sample >> 7) & 0xFF]; mantissa = (sample >> (exponent + 3)) & 0x0F; ulawbyte = (byte) ~(sign | (exponent << 4) | mantissa); /* |=bitvis-or, ~=bitvis-invert */ if (ulawbyte == 0) {ulawbyte = 0x02;} if (overload) {slider4.setValue(slider4.getValue()+1); B_comp.setLabel("recomputing"); run(); } arrud[i]=ulawbyte; } B_comp.setLabel("make sound"); /* en ny lyd kan laves */ /* pfcanvas.canvaspaint(arr, arrlng, pfcanvas.getGraphics() ); */ /* tegn lyden på pfcanvasen */ if (loop == false) {soundplay();} /* start lyden hvis den ikke er i gang */ going=false; /* knapper kan igen opdaters */ varlng=(int)(r.nextDouble()*1000); try {player_th.sleep(varlng);} catch (InterruptedException e){} if (op) { if (count>=3) { op = false; if (r.nextDouble()>0.5) {slider3.setValue(slider3.getValue()+6); } if (r.nextDouble()>0.7) {slider2.setValue(slider2.getValue()-2); } if (r.nextDouble()>0.84) {slider2.setValue(slider2.getValue()+5); } } slider1.setValue(slider1.getValue()+10); count++; } else { if (count<=1) { op = true; if (r.nextDouble()>0.5) {slider3.setValue(slider3.getValue()-6); } if (r.nextDouble()>0.7) {slider2.setValue(slider2.getValue()+2); } if (r.nextDouble()>0.84) {slider2.setValue(slider2.getValue()-5); } } slider1.setValue(slider1.getValue()-10); count--; } botupdate(); } /* while løkke slut */ } /* enden på run metoden */ public void botupdate() { s1.setText(String.valueOf(slider1.getValue())); s2.setText(String.valueOf(slider2.getValue())); s3.setText(String.valueOf(slider3.getValue())); } public boolean handleEvent(Event e) { if (!going) { if (e.target == slider1) s1.setText(String.valueOf(slider1.getValue())); if (e.target == slider2) s2.setText(String.valueOf(slider2.getValue())); if (e.target == slider3) s3.setText(String.valueOf(slider3.getValue())); if ((e.target == B_comp) & (e.arg =="make sound")) { B_comp.setLabel(" computing "); player_th.resume(); } if ((e.target == B_play) & ((e.arg =="Stop sound") | (e.arg =="Play sound")) ) { soundplay(); } } return true; } } class asynth05canvas extends Applet{ /* FIELDS */ int w = 260; int h = 120; boolean one = false; int arrhold[] = new int[w]; public asynth05canvas() { } public Dimension minimumSize() { return new Dimension(w,h); } public Dimension preferredSize() { return minimumSize(); } /* METODER */ public void paint(Graphics g) { int lev1,lev2; g.setColor(Color.green.darker()); g.draw3DRect(0, 0, w - 1, h - 1,false); g.draw3DRect(1, 1, w - 3, h - 3,false); g.setColor(Color.blue); g.setFont(new Font("Helvetica", Font.PLAIN, 9)); g.drawString("Double Muffled Dolphin", (w+8 - g.getFontMetrics().stringWidth("Double Muffled Dolphin"))/2,12); if (one) { for (int i=3; i<(w-3);i++) { lev1=arrhold[i]; lev2=arrhold[i+1]; g.setColor(Color.blue); g.drawLine(i,lev1/510+h/2,i,lev2/510+h/2); /* 2 * 255= 510 */ } } } public void udskriv(String str, Graphics g) { g.clearRect(3, 3, 80, 24) ; g.setFont(new Font("Helvetica", Font.PLAIN, 11)); g.setColor(Color.red); g.drawString(str,6,14); } /* UDSKRIVNING AF LYDBØLGE */ public void canvaspaint(int[] arr, int arrlng, Graphics g) { one = true; int lev1,lev2; int frem = ((int) arrlng/w); /* udskriver kun hver samplelængde/vinduesbrede sample */ g.clearRect(3, 3, w-6, h-6) ; for (int i=3; i<(w-3);i++) { arrhold[i]=arr[i*frem]; lev1=arr[i*frem]; lev2=arr[(i+1)*frem]; g.setColor(Color.blue); g.drawLine(i,lev1/510+h/2,i,lev2/510+h/2); /* 2 * 255= 510 */ } } }