1 /*
2  *  Jakdaw's XMMS Plugin.
3  *  Copyright (C) 1999, 2000, Christopher Wilson.
4  *
5  *  Email: <Jakdaw@usa.net>
6  *  Project Homepage: <http://www.jakdaw.ucam.org/xmms/>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
21  *  USA
22  */
23 #include <stdlib.h>
24 #include <math.h>
25 
26 #include "plotter.h"
27 
28 static void vert_line(JakdawPrivate *priv, int x, int a, int b, uint32_t col, uint32_t *vscr);
29 static int no_of_shifts(int val);
30 static int p2(int val);
31 
_jakdaw_plotter_draw(JakdawPrivate * priv,float * pcm_data,float * freq_data,uint32_t * vscr)32 void _jakdaw_plotter_draw(JakdawPrivate *priv, float *pcm_data, float *freq_data, uint32_t *vscr)
33 {
34 	int x, y;
35 	int oy;
36 	uint32_t col;
37 
38 	switch (priv->plotter_colortype)
39 	{
40 		case PLOTTER_COLOUR_SOLID: col=priv->plotter_scopecolor; break;
41 		case PLOTTER_COLOUR_RANDOM: col=visual_random_context_int (priv->rcontext); break;
42 		case PLOTTER_COLOUR_MUSICTRIG:
43 		default:
44 					    {
45 						    float d;
46 						    int c;
47 						    d=0;
48 						    for(c=0;c<16;c++)
49 							    d=d+freq_data[c];
50 						    col=(int)((double) d*(256.0 * 16.0));
51 
52 						    d=0;
53 						    for(c=16;c<108;c++)
54 							    d=d+freq_data[c];
55 						    col|=((int)((double) d*(256.0 * 64.0)))<<8;
56 
57 						    d=0;
58 						    for(c=108;c<255;c++)
59 							    d=d+freq_data[c];
60 						    col|=((int)((double) d*(256.0 * 128.0)))<<16;
61 
62 					    }
63 	}
64 
65 	oy = (priv->yres / 2) + ((pcm_data[0] * priv->plotter_amplitude) * (priv->yres / 2));
66 
67 	oy=oy<0 ? 0 : oy>=priv->yres ? priv->yres -1 : oy;
68 
69 	for(x=0;x<priv->xres;x++)
70 	{
71 		y = (priv->yres / 2) + ((pcm_data[x % 512] * priv->plotter_amplitude) * (priv->yres / 2));
72 
73 		if(y<0) y=0;
74 		if(y>=priv->yres) y=priv->yres-1;
75 		if(priv->plotter_scopetype==PLOTTER_SCOPE_LINES)
76 		{
77 			vert_line(priv, x, oy, y, col, vscr);
78 			oy=y;
79 		}
80 		else if(priv->plotter_scopetype==PLOTTER_SCOPE_DOTS)
81 		{
82 			if(x>0 && x<priv->xres && y>0 && y<priv->yres)
83 				vscr[(y*priv->xres)+x]=col;
84 		}
85 		else if(priv->plotter_scopetype==PLOTTER_SCOPE_SOLID)
86 		{
87 			vert_line(priv, x, (priv->yres>>1), y, col, vscr);
88 		}
89 	}
90 }
91 
vert_line(JakdawPrivate * priv,int x,int a,int b,uint32_t col,uint32_t * vscr)92 static void vert_line(JakdawPrivate *priv, int x,int a, int b, uint32_t col, uint32_t *vscr)
93 {
94 	int y, ptr;
95 
96 	if(b<a)
97 	{
98 		y=a; a=b; b=y;
99 	}
100 
101 	if(a<0 || a>=priv->yres || b<0 || b>=priv->yres)
102 		return;
103 
104 	ptr=(a*priv->xres)+x;
105 
106 	for(y=a;y<=b;y++)
107 	{
108 		vscr[ptr]=col;
109 		ptr+=priv->xres;
110 	}
111 }
112 
113 // Calculate maximum no of right shifts that can be applied to a sample so
114 // that val can still be represented.
115 
no_of_shifts(int val)116 static int no_of_shifts(int val)
117 {
118 
119 	int a=1, b=0;
120 
121 	while(a<val)
122 	{
123 		b++;
124 		a*=2;
125 	}
126 
127 	return 16-b;
128 }
129 
130 // Calc a power of 2
131 
p2(int val)132 static int p2(int val)
133 {
134 	int a=1;
135 
136 	for(;val>0;val--)
137 		a*=2;
138 
139 	return a;
140 }
141