Mercurial > hg > forks > pwpunix
view pwplib/gb.c @ 71:a87eb778f225
Improvements to the MinGW crossbuild. Should now build with default tools
from Debian mingw packages, though you need Win32 version of libSDL with the
necessary headers and so on in addition. 64-bit builds not tested and
probably won't work. Tested on Debian 7.0, earlier won't work.
binutils-mingw-w64-i686 gcc-mingw-w64-i686 mingw-w64-i686-dev
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 14 Aug 2012 03:08:10 +0300 |
parents | 85671798fdb3 |
children |
line wrap: on
line source
/* * PWP Generic Beep (PWPbeep) engine for digital audio. * */ #include "config.h" #ifdef DRIVE_GB #include <math.h> #include "pwplib.h" struct { struct { int wvlgt; int wvleft; int wvphase; int wvlgt1; } ch[3]; int freq; }pwpgb; void gb_sound(int chan,int freq,int volume,int ratio) { if(volume&&freq){ int wvlgt= ((double)(pwpgb.freq*12)/pow(1.059465,freq/256.0)); if(ratio<1)ratio=1;else if(ratio>255)ratio=255; pwpgb.ch[chan].wvlgt=(wvlgt*ratio)>>7; pwpgb.ch[chan].wvlgt1=2*pwpgb.ch[chan].wvlgt-wvlgt; pwpgb.ch[chan].wvleft=pwpgb.ch[chan].wvlgt/(chan+2); pwpgb.ch[chan].wvphase=volume; }else{ pwpgb.ch[chan].wvphase=0; pwpgb.ch[chan].wvleft=pwpgb.ch[chan].wvlgt=32123; } } void gb_init(int freq) { int i; pwpgb.freq = freq; for(i = 0; i < 3; i++) gb_sound(i,0,0,0); } static void gb_gen1chan(u8 *d, int l, int freq) { int ph=128*256; while(l--){ *d++=64+((ph>>8)&0x80); ph+=freq; } } #define CH pwpgb.ch static void gb_beepemu(u8 *d, int l) { static int pf=0; int fq0=CH[0].wvlgt, fq1=CH[1].wvlgt, fq2=CH[2].wvlgt,fq; if(CH[0].wvphase==0)fq0=32768; if(CH[1].wvphase==0)fq1=32768; if(CH[2].wvphase==0)fq2=32768; if(fq0>fq1){int tmp=fq0;fq0=fq1;fq1=tmp;} if(fq0>fq2){int tmp=fq0;fq0=fq2;fq2=tmp;} if(fq1>fq2){int tmp=fq1;fq1=fq2;fq2=tmp;} if(pf&1){ if(pf&2)fq=fq1;else fq=fq2; if(!fq)fq=fq0; }else{ fq=fq0; if(fq==32768){fq=fq1; if(fq==32768)fq=fq2;} } if(fq==32768)memset(d,128,l);else { fq=(65536*256)/fq; gb_gen1chan(d,l,fq); } pf++; } void gb_genwave(u8 *d, int l) { int remain=0; l<<=8; while(l) { int min=CH[0].wvleft,w,sum; w=CH[1].wvleft;if(w<min)min=w; w=CH[2].wvleft;if(w<min)min=w; sum=CH[0].wvphase+CH[1].wvphase+CH[2].wvphase+128; if(sum<0)sum=0;else if(sum>255)sum=255; if(min>l)min=l; l-=min; memset(d,sum,(min+remain)>>8); d+=((min+remain)>>8); remain=(min+remain)&255; {int i=0; for(;i<3;i++){ w=CH[i].wvleft-=min; if(!w) { CH[i].wvleft=CH[i].wvlgt1; CH[i].wvlgt1=CH[i].wvlgt; CH[i].wvlgt=CH[i].wvleft; CH[i].wvphase=0-CH[i].wvphase; } } } } } /* my_memset, ... */ /* gb_genwave_opt(char*buf,int endptr) { #define SETTILL(a) \ {int bord=w##a,rs;if(bord>endptr)goto last;\ rs=sum;if(rs&~0xff){if(rs<0)rs=0;else rs=255;}\ memset(buf+(ptr>>8),rs,2+((bord-ptr)>>8));ptr=bord;\ CH[a].wvphase=0-CH[a].wvphase;\ sum+=(CH[a].wvphase)<<1;\ w##a=ptr+CH[a].wvlgt;} #define HANDLE(s0,s1,s2) \ {SETTILL(s0); \ if(w##s0<=w##s1)goto w##s0##w##s1##w##s2;else \ if(w##s0<=w##s2)goto w##s1##w##s0##w##s2;else \ goto w##s1##w##s2##w##s0;} int ptr=0,sum=CH[0].wvphase+ CH[1].wvphase+ CH[2].wvphase; int w0=CH[0].wvleft, w1=CH[1].wvleft, w2=CH[2].wvleft; endptr<<=8; w1w2w0:HANDLE(1,2,0); w2w1w0:HANDLE(2,1,0); w0w2w1:HANDLE(0,2,1); w2w0w1:HANDLE(2,0,1); w0w1w2:HANDLE(0,1,2); w1w0w2:HANDLE(1,0,2); last: {int rs=sum; if(rs&~0xff){if(rs<0)rs=0;else rs=255;} memset(buf+(ptr>>8),rs,(endptr-ptr)>>8);} CH[0].wvleft=w0-endptr; CH[1].wvleft=w1-endptr; CH[2].wvleft=w2-endptr; #undef SETTILL } */ #if (0) gb_genwave_opt(char*buf,int endptr) { int ptr=0,sum=CH[0].wvphase+ CH[1].wvphase+ CH[2].wvphase; #define w0 CH[0].wvleft #define w1 CH[1].wvleft #define w2 CH[2].wvleft /* volatile int w0=CH[0].wvleft, w1=CH[1].wvleft, w2=CH[2].wvleft;*/ endptr<<=8; #define SETTILL(a) \ {int bord=w##a,rs;if(bord>endptr)goto last;\ rs=sum;if(rs&~0xff){if(rs<0)rs=0;else rs=255;}\ memset(buf+(ptr>>8),rs,2+((bord-(ptr&~0xff))>>8));ptr=bord;\ CH[a].wvphase=0-CH[a].wvphase;\ sum+=(CH[a].wvphase)<<1;\ w##a=ptr+CH[a].wvlgt;} if(w0<=w1){ if(w1<=w2)goto w0w1w2;else if(w2<=w0)goto w2w0w1;else goto w0w2w1; }else{ if(w0<=w2)goto w1w0w2;else if(w2<=w1)goto w2w1w0; //.. else w1w2w0 (next) } w1w2w0: SETTILL(1); if(w1<=w2)goto w1w2w0;else if(w1<=w0)goto w2w1w0;else //.. if(w1>w0)goto w2w0w1; goto w2w0w1; w2w1w0: SETTILL(2); if(w2<=w1)goto w2w1w0;else if(w2<=w0)goto w1w2w0;else goto w1w0w2; w0w2w1: SETTILL(0); if(w0<=w2)goto w0w2w1;else if(w0<=w1)goto w2w0w1;else //.. if(w0>w1)goto w2w1w0; goto w2w1w0; w2w0w1: SETTILL(2); if(w2<=w0)goto w2w0w1;else if(w2<=w1)goto w0w2w1;else goto w0w1w2; //.. not reqd w0w1w2: SETTILL(0); if(w0<=w1)goto w0w1w2;else if(w0<=w2)goto w1w0w2;else //.. if(w0>w2)goto w1w2w0; goto w1w2w0; w1w0w2: SETTILL(1); if(w1<=w0)goto w1w0w2;else if(w1<=w2)goto w0w1w2;else goto w0w2w1; last: {int rs=sum; if(rs&~0xff){if(rs<0)rs=0;else rs=255;} memset(buf+(ptr>>8),rs,2+((endptr-ptr)>>8));} CH[0].wvleft=w0-endptr; CH[1].wvleft=w1-endptr; CH[2].wvleft=w2-endptr; #undef SETTILL } #endif #endif