Bill Allombert on Mon, 14 Jul 2025 13:07:22 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
playing music with GP v2 |
Dear PARI lovers, I have a made a new attempt at music, this one in stereo. If you prefer to use ffplay, just change the first line to START="start_aplay"; Most of the code is a converter from lilypond notation to frequencies. The instrument is playsound. It includes the enveloppe code by Hans. The tune is a request from John Cremona :) Cheers, Bill
START="start_aplay"; FREQ=8000; A=440; TEMPO=60/100*4; CHANNEL=2; start_aplay(fifo="/tmp/parififo")= { system(Str("test -p ",fifo" || mkfifo ",fifo,"; aplay -r",FREQ," -q -traw -c",CHANNEL," < ",fifo," &")); fileopen(fifo,"w"); } start_ffplay(fifo="/tmp/parififo")= { system(Str("test -p ",fifo" || mkfifo ",fifo,"; ffplay -i pipe: -f u8 -ar ",FREQ," -ac ",CHANNEL," -hide_banner -autoexit -v 0 < ",fifo," &")); fileopen(fifo,"w"); } start_ffplaygit() = fileextern(Str("ffplay -i pipe: -f u8 -ar ",FREQ," -ac ",CHANNEL," -hide_banner -autoexit -v 0"),"w"); start_aplaygit() = fileextern(Str("aplay -r",FREQ," -q -traw -c",CHANNEL),"w"); freq(n)= 2^(n/12)*A; lerp(a,b,t) = a*(1-t)+b*t; adsr(i,l,a,d,s,r) = { if(i<a, i/a, i<a+d, lerp(1,s,(i-a)/d), i>l-r, lerp(0,s,(l-i)/r), s); } playsound(f,freq,t,amp)= { my(l=FREQ*TEMPO*t,a=FREQ*0.025,d=FREQ*0.05,s=0.66,r=FREQ*0.05); for(i=1,round(l), my(c=2*Pi*freq*i/FREQ); my(r=round(128+adsr(i,l,a,d,s,r)*(amp*sin(c)))); filewrite1(f,strchr(r)); if (CHANNEL==1, next()); my(r=round(128+adsr(i,l,a,d,s,r)*(amp*cos(c)))); filewrite1(f,strchr(r)); ); print1("."); fileflush(f); } ode_to_joy="b4 b c' d' d' c' b a g g a b b4. a8 a2 b4 b c' d' d' c' b a g g a b a4. g8 g2 a4 a b g a b8 c' b4 g a b8 c' b4 a g a d2 b4 b c' d' d' c' b a g g a b a4. g8 g2"; la_marseillaise="r2 r8 r16 d16 d8. d16 g4 g a a d4. b8 g r16 g b8. g16 e4 c'2 a8. fis16 g2 r4 g8. a16 b4 b b c8. b16 b4 a r4 a8. b16 c4 c c d8. c16 b2 r4 d8. d16 d4 b8. g16 d'4 b8. g16 d2 r8 r16 d16 d8. fis16 a2 c4 a8. fis16 a4 g f2 e4 g8. g16 g4 fis8. g16 a2. r8 a8 bes4. bes8 bes bes c d a2. bes8 a g4. g8 g bes a g g4 fis8 r8 r4 r8 r16 d' d2 d8. d16 b8. g16 a2. r8 r16 d16 d2 d8. d16 b8. g16 a2 a8 r8 d,4 g2 r4 a4 b2 r2 c2 d4 e a,2 a8 r8 e'4 d2 d8. b16 c8. a16 g2. r4"; play(S,rl=0,rel)= { my(mode=Map([0,0;1,2;2,3;3,5;4,7;5,9;6,10])); /*G major */ my(f = call(eval(START),[]), T=4,d); foreach(strsplit(S," "), s, my(p=0,m=1,V=Vec(s),amp=120,nt=0,di=0); if (V[1]=="r", amp=0; , p=vecsearch(Vec("abcdefg"),V[1])-1; if (p<0,error(V)); p=rel+centerlift(Mod(p-rel,7)); ); for(i=2,#V, my(c=V[i]); if(c=="i" && V[i+1]=="s",di++;i++ ,c=="e" && V[i+1]=="s",di--;i++ ,c=="'",p+=7 ,c==",",p-=7 ,c==".",m=3/2 ,d=vecsearch(Vec("0123456789"),c), nt+=10*nt+d-1, ,error(V); )); if (nt,T = nt); if (amp, if(rl,rel = p); p = mapget(mode,p%7)+12*(p\7) + di); playsound(f,freq(p),m/T,amp)); fileclose(f); } \\play(ode_to_joy,0,-2); play(la_marseillaise,1,-7);