g_vumeter.c 25.4 KB
Newer Older
Miller Puckette's avatar
Miller Puckette committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Copyright (c) 1997-1999 Miller Puckette.
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */

/* g_7_guis.c written by Thomas Musil (c) IEM KUG Graz Austria 2000-2001 */
/* thanks to Miller Puckette, Guenther Geiger and Krzystof Czaja */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "m_pd.h"
#include "g_canvas.h"
#include "g_all_guis.h"
#include <math.h>

Hans-Christoph Steiner's avatar
Hans-Christoph Steiner committed
16
#ifdef HAVE_UNISTD_H
Miller Puckette's avatar
Miller Puckette committed
17
18
19
#include <unistd.h>
#endif

Hans-Christoph Steiner's avatar
Hans-Christoph Steiner committed
20
21
22
23
#ifdef HAVE_IO_H
#include <io.h>
#endif

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
char *iemgui_vu_scale_str[]=
{
    "", "<-99", "", "",
    "",  "-50",  "", "",
    "",  "-30", "", "",
    "",  "-20", "", "",
    "",  "-12", "", "",
    "",   "-6", "", "",
    "",   "-2", "", "",
    "", "-0dB", "", "",
    "",   "+2", "", "",
    "",   "+6", "", "",
    "", ">+12", "", "",
    "",     "", "",
};

int iemgui_vu_db2i[]=
{
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
    9, 9, 9, 9, 9,10,10,10,10,10,
    11,11,11,11,11,12,12,12,12,12,
    13,13,13,13,14,14,14,14,15,15,
    15,15,16,16,16,16,17,17,17,18,
    18,18,19,19,19,20,20,20,21,21,
    22,22,23,23,24,24,25,26,27,28,
    29,30,31,32,33,33,34,34,35,35,
    36,36,37,37,37,38,38,38,39,39,
    39,39,39,39,40,40
};

int iemgui_vu_col[]=
{
    0,17,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
    15,15,15,15,15,15,15,15,15,15,14,14,13,13,13,13,13,13,13,13,13,13,13,19,19,19
};

73
static t_class *scalehandle_class;
74
75
76
77
extern int gfxstub_haveproperties(void *key);
static void vu_draw_select(t_vu* x, t_glist* glist);
void vu_check_height(t_vu *x, int h);

Miller Puckette's avatar
Miller Puckette committed
78
79
80
/* ----- vu  gui-peak- & rms- vu-meter-display ---------- */

t_widgetbehavior vu_widgetbehavior;
81
t_class *vu_class;
Miller Puckette's avatar
Miller Puckette committed
82
83
84
85
86

/* widget helper functions */

static void vu_update_rms(t_vu *x, t_glist *glist)
{
87
    if (glist_isvisible(glist))
Miller Puckette's avatar
Miller Puckette committed
88
    {
89
90
91
        int w4 = x->x_gui.x_w / 4, off=text_ypix(&x->x_gui.x_obj, glist) - 1;
        int xpos = text_xpix(&x->x_gui.x_obj, glist),
            quad1 = xpos + w4 + 1, quad3 = xpos + x->x_gui.x_w-w4 - 1;
Miller Puckette's avatar
Miller Puckette committed
92
93

        sys_vgui(".x%lx.c coords %lxRCOVER %d %d %d %d\n",
94
95
            glist_getcanvas(glist), x, quad1 + 1, off + 2, quad3 + 1,
            off + (x->x_led_size + 1) * (IEM_VU_STEPS - x->x_rms) + 2);
Miller Puckette's avatar
Miller Puckette committed
96
97
98
99
100
101
102
103
104
    }
}

static void vu_update_peak(t_vu *x, t_glist *glist)
{
    t_canvas *canvas=glist_getcanvas(glist);

    if(glist_isvisible(glist))
    {
105
106
        int xpos = text_xpix(&x->x_gui.x_obj, glist);
        int ypos = text_ypix(&x->x_gui.x_obj, glist);
Miller Puckette's avatar
Miller Puckette committed
107
108
109

        if(x->x_peak)
        {
110
111
112
113
114
115
116
117
            int i = iemgui_vu_col[x->x_peak];
            int j = ypos + (x->x_led_size + 1) * (IEM_VU_STEPS + 1 - x->x_peak)
                - (x->x_led_size + 1) / 2;

            sys_vgui(".x%lx.c coords %lxPLED %d %d %d %d\n",
                canvas, x, xpos + 1, j + 2, xpos + x->x_gui.x_w + 2, j + 2);
            sys_vgui(".x%lx.c itemconfigure %lxPLED -fill #%6.6x\n",
                canvas, x, iemgui_color_hex[i]);
Miller Puckette's avatar
Miller Puckette committed
118
119
120
        }
        else
        {
121
            int mid = xpos + x->x_gui.x_w / 2;
Miller Puckette's avatar
Miller Puckette committed
122
123
124
125

            sys_vgui(".x%lx.c itemconfigure %lxPLED -fill #%6.6x\n",
                     canvas, x, x->x_gui.x_bcol);
            sys_vgui(".x%lx.c coords %lxPLED %d %d %d %d\n",
126
                     canvas, x, mid+1, ypos+22, mid+1, ypos+22);
Miller Puckette's avatar
Miller Puckette committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
        }
    }
}

static void vu_draw_update(t_gobj *client, t_glist *glist)
{
    t_vu *x = (t_vu *)client;
    if (x->x_updaterms)
    {
        vu_update_rms(x, glist);
        x->x_updaterms = 0;
    }
    if (x->x_updatepeak)
    {
        vu_update_peak(x, glist);
        x->x_updatepeak = 0;
    }
}
145
146
147
148
149
150

void vu_draw_io(t_vu *x, t_glist* glist, int old_snd_rcv_flags)
{
    t_canvas *canvas=glist_getcanvas(glist);
    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags);
}
Miller Puckette's avatar
Miller Puckette committed
151
152
153
154
static void vu_draw_new(t_vu *x, t_glist *glist)
{
    t_canvas *canvas=glist_getcanvas(glist);

155
156
157
158
159
160
    int x1=text_xpix(&x->x_gui.x_obj, glist);
    int y1=text_ypix(&x->x_gui.x_obj, glist);
    int w4=x->x_gui.x_w/4, mid=x1+x->x_gui.x_w/2,
        quad1=x1+w4+1;
    int quad3=x1+x->x_gui.x_w-w4,
        end=x1+x->x_gui.x_w+4;
Miller Puckette's avatar
Miller Puckette committed
161
    int k1=x->x_led_size+1, k2=IEM_VU_STEPS+1, k3=k1/2;
162
    int led_col, yyy, i, k4=y1-k3;
Miller Puckette's avatar
Miller Puckette committed
163

164
165
    char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
    iemgui_base_draw_new(&x->x_gui, canvas, nlet_tag);
166
167
    scalehandle_draw_new(x->x_gui. x_handle,canvas);
    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
168

169
170
171
172
    for(i = 1; i <= IEM_VU_STEPS+1; i++)
    {
        yyy = k4 + k1 * (k2-i);
        if(((i+2) & 3) && (x->x_scale))
173
            sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
                "-font {{%s} -%d %s} -fill #%6.6x "
                "-tags {%lxSCALEN %lxSCALE%d %lxOBJ %s text iemgui}\n",
                canvas, end+1, yyy+k3+2, iemgui_vu_scale_str[i], 
                iemgui_font(&x->x_gui), x->x_gui.x_fontsize,
                sys_fontweight, x->x_gui.x_lcol, x, x, i, x, nlet_tag);

        led_col = iemgui_vu_col[i];
        if (i<=IEM_VU_STEPS) sys_vgui(".x%lx.c create polyline %d %d %d %d "
            "-strokewidth %d -stroke #%6.6x "
            "-tags {%lxRLED%d %lxOBJ %s text iemgui}\n",
            canvas, quad1+1, yyy+2, quad3, yyy+2,
            x->x_led_size, iemgui_color_hex[led_col], x, i, x, nlet_tag);
    }
    sys_vgui(".x%lx.c create prect %d %d %d %d -fill #%6.6x "
        "-stroke #%6.6x -tags {%lxRCOVER %lxOBJ %s text iemgui}\n",
        canvas, quad1+1, y1+1, quad3, y1+1 + k1*IEM_VU_STEPS,
        x->x_gui.x_bcol, x->x_gui.x_bcol, x, x, nlet_tag);
    sys_vgui(".x%lx.c create polyline %d %d %d %d "
        "-strokewidth %d -fill #%6.6x "
        "-tags {%lxPLED %lxOBJ %s text iemgui}\n",
        canvas, mid+1, y1+12,
        mid+1, y1+12, x->x_led_size, x->x_gui.x_bcol, x, x, nlet_tag);
    iemgui_label_draw_new(&x->x_gui,canvas,x1,y1,nlet_tag);
    vu_draw_io(x,glist,7);
    x->x_updaterms = x->x_updatepeak = 1;
    sys_queuegui(x, x->x_gui.x_glist, vu_draw_update);
Miller Puckette's avatar
Miller Puckette committed
200
201
202
203
204
205
}


static void vu_draw_move(t_vu *x, t_glist *glist)
{
    t_canvas *canvas=glist_getcanvas(glist);
206
    if (!glist_isvisible(canvas)) return;
Miller Puckette's avatar
Miller Puckette committed
207

208
209
210
211
212
213
214
215
216
217
218
    char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
    int xpos=text_xpix(&x->x_gui.x_obj, glist);
    int ypos=text_ypix(&x->x_gui.x_obj, glist);
    int w4=x->x_gui.x_w/4, quad1=xpos+w4+1;
    int quad3=xpos+x->x_gui.x_w-w4,
          end=xpos+x->x_gui.x_w+4;
    int k1=x->x_led_size+1, k2=IEM_VU_STEPS+1, k3=k1/2;
    int yyy, i, k4=ypos-k3;
    sys_vgui(".x%lx.c coords %lxBASE %d %d %d %d\n",
        canvas, x, xpos, ypos, xpos+x->x_gui.x_w+2,ypos+x->x_gui.x_h+4);
    for(i=1; i<=IEM_VU_STEPS; i++)
219
    {
220
221
222
223
        yyy = k4 + k1*(k2-i);
        sys_vgui(".x%lx.c coords %lxRLED%d %d %d %d %d\n",
            canvas, x, i, quad1+1, yyy+2, quad3, yyy+2);
        if(((i+2)&3) && (x->x_scale))
224
            sys_vgui(".x%lx.c coords %lxSCALE%d %d %d\n",
225
                canvas, x, i, end+1, yyy+k3+2);
Miller Puckette's avatar
Miller Puckette committed
226
227
228
    }
    if(x->x_scale)
    {
229
230
231
232
        i=IEM_VU_STEPS+1;
        yyy = k4 + k1*(k2-i);
        sys_vgui(".x%lx.c coords %lxSCALE%d %d %d\n",
            canvas, x, i, end+1, yyy+k3+2);
Miller Puckette's avatar
Miller Puckette committed
233
    }
234
235
236
237
238
    x->x_updaterms = x->x_updatepeak = 1;
    sys_queuegui(x, glist, vu_draw_update);
    iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
    iemgui_io_draw_move(&x->x_gui,canvas,nlet_tag);
    if (x->x_gui.x_selected) vu_draw_select(x, x->x_gui.x_glist);
Miller Puckette's avatar
Miller Puckette committed
239
240
}

241
static void vu_draw_config(t_vu* x, t_glist* glist)
Miller Puckette's avatar
Miller Puckette committed
242
{
243
    int i;
Miller Puckette's avatar
Miller Puckette committed
244
    t_canvas *canvas=glist_getcanvas(glist);
245
246
    char lcol[8]; sprintf(lcol, "%6.6x", x->x_gui.x_lcol);
    for(i = 1; i <= IEM_VU_STEPS+1; i++)
247
    {
248
249
250
251
252
253
254
255
        if (i <= IEM_VU_STEPS)
            sys_vgui(".x%lx.c itemconfigure %lxRLED%d -strokewidth %d\n",
                canvas, x, i, x->x_led_size);
        sys_vgui(".x%lx.c itemconfigure %lxSCALE%d -text {%s} "
            "-font {{%s} -%d %s} -fill %s\n",
            canvas, x, i, iemgui_vu_scale_str[i], iemgui_font(&x->x_gui), 
            x->x_gui.x_fontsize, sys_fontweight,
            ((i + 2) & 3) && (x->x_scale) ? selection_color : lcol);
256
    }
257
258
259
260
261
262
    iemgui_label_draw_config(&x->x_gui,canvas);
    sys_vgui(".x%lx.c itemconfigure %lxRCOVER -fill #%6.6x -stroke #%6.6x\n",
             canvas, x, x->x_gui.x_bcol, x->x_gui.x_bcol);
    sys_vgui(".x%lx.c itemconfigure %lxPLED -strokewidth %d\n",
             canvas, x, x->x_led_size);
    iemgui_base_draw_config(&x->x_gui,canvas);
Miller Puckette's avatar
Miller Puckette committed
263
264
265
266
267
}

static void vu_draw_select(t_vu* x,t_glist* glist)
{
    t_canvas *canvas=glist_getcanvas(glist);
268
269
270
271
272
    iemgui_base_draw_config(&x->x_gui,canvas);
    char lcol[8]; sprintf(lcol,"#%6.6x", x->x_gui.x_lcol);
    int issel = x->x_gui.x_selected && x->x_gui.x_glist==canvas;
    sys_vgui(".x%lx.c itemconfigure %lxSCALEN "
        "-fill %s\n", canvas, x, issel ? selection_color : lcol);
273
274
    if(issel)
        scalehandle_draw_select2(&x->x_gui,glist);
275
276
277
    else
        scalehandle_draw_erase2(&x->x_gui,glist);
    iemgui_label_draw_select(&x->x_gui,canvas);
278
    iemgui_tag_selected(&x->x_gui,canvas);
279
280
}

281
282
static void vu__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
    t_floatarg yyy)
283
{
284
    t_vu *x = (t_vu *)(sh->h_master);
285
    int newstate = (int)f;
286
    if (sh->h_dragon && newstate == 0  && sh->h_scale)
Miller Puckette's avatar
Miller Puckette committed
287
    {
288
289
290
        canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x);
        if (sh->h_dragx || sh->h_dragy)
        {
291
292
            x->x_gui.x_w += sh->h_dragx;
            x->x_gui.x_h += sh->h_dragy;
293
294
295
296
297
298
299
300
            canvas_dirty(x->x_gui.x_glist, 1);
        }
        if (glist_isvisible(x->x_gui.x_glist))
        {
            vu_check_height(x, x->x_gui.x_h);
            vu_draw_move(x, x->x_gui.x_glist);
            vu_draw_config(x, x->x_gui.x_glist);
            vu_draw_update((t_gobj *)x, x->x_gui.x_glist);
301
            scalehandle_unclick_scale(sh);
302
        }
Miller Puckette's avatar
Miller Puckette committed
303
    }
304
    iemgui__clickhook3(sh,newstate);
305
306
}

307
static void vu__motionhook(t_scalehandle *sh, t_floatarg f1, t_floatarg f2)
308
{
309
    if (sh->h_dragon && sh->h_scale)
310
    {
311
312
        t_vu *x = (t_vu *)(sh->h_master);
        int dx = (int)f1, dy = (int)f2;
313
314
        dx = maxi(dx, 8-x->x_gui.x_w);
        dy = maxi(dy,80-x->x_gui.x_h);        
315
316
        sh->h_dragx = dx;
        sh->h_dragy = dy;
317
        scalehandle_drag_scale(sh);
318
319
320
321

        int properties = gfxstub_haveproperties((void *)x);
        if (properties)
        {
322
323
            int new_w = x->x_gui.x_w + sh->h_dragx;
            int new_h = x->x_gui.x_h + sh->h_dragy;
324
325
            properties_set_field_int(properties,"dim.w_ent",new_w);
            properties_set_field_int(properties,"dim.h_ent",new_h);
326
        }
327
    }
328
    scalehandle_dragon_label(sh,f1,f2);
Miller Puckette's avatar
Miller Puckette committed
329
330
331
332
}

void vu_draw(t_vu *x, t_glist *glist, int mode)
{
333
    if(mode == IEM_GUI_DRAW_MODE_UPDATE)
334
        sys_queuegui((t_gobj*)x, x->x_gui.x_glist, vu_draw_update);
Miller Puckette's avatar
Miller Puckette committed
335
336
    if(mode == IEM_GUI_DRAW_MODE_MOVE)
        vu_draw_move(x, glist);
337
338
    else if(mode == IEM_GUI_DRAW_MODE_NEW)
    {
Miller Puckette's avatar
Miller Puckette committed
339
        vu_draw_new(x, glist);
340
341
        sys_vgui(".x%lx.c raise all_cords\n", glist_getcanvas(glist));
    }
Miller Puckette's avatar
Miller Puckette committed
342
343
344
    else if(mode == IEM_GUI_DRAW_MODE_SELECT)
        vu_draw_select(x, glist);
    else if(mode == IEM_GUI_DRAW_MODE_ERASE)
345
        iemgui_draw_erase(&x->x_gui, glist);
Miller Puckette's avatar
Miller Puckette committed
346
347
348
349
350
351
352
353
    else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
        vu_draw_config(x, glist);
    else if(mode >= IEM_GUI_DRAW_MODE_IO)
        vu_draw_io(x, glist, mode - IEM_GUI_DRAW_MODE_IO);
}

/* ------------------------ vu widgetbehaviour----------------------------- */

354
355
static void vu_scale_getrect(t_iemgui x_gui, t_glist *x, int *xp1, int *yp1,
    int *xp2, int *yp2, int scale_x, int scale_y)
356
{
357
358
359
360
361
362
363
364
365
366
367
368
369
    t_float width_multiplier;
    int scale_length;    
    int scale_x1;
    int scale_y1;
    int scale_x2;
    int scale_y2;
    int actual_fontsize; //seems tk does its own thing when it comes to rendering
    int actual_height;

    if (x->gl_isgraph && !glist_istoplevel(x))
    {
        //fprintf(stderr,"vu_scale_getrect\n");

370
        switch(x_gui.x_font_style)
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
        {
            case 1:
                width_multiplier = 0.83333;
                break;
            case 2:
                width_multiplier = 0.735;
                break;
            default:
                width_multiplier = 1.0;
                break;
        }
        if (x_gui.x_fontsize % 2 == 0)
        {
            actual_fontsize = x_gui.x_fontsize;
        }
        else
        {
            actual_fontsize = x_gui.x_fontsize;
        }
        actual_height = actual_fontsize;
        //exceptions
392
        if (x_gui.x_font_style == 0 &&
393
394
395
396
397
398
399
            (actual_fontsize == 8 || actual_fontsize == 13 ||
             actual_fontsize % 10 == 1 || actual_fontsize % 10 == 6 ||
             (actual_fontsize > 48 && actual_fontsize < 100 &&
              (actual_fontsize %10 == 4 || actual_fontsize %10 == 9))) )
        {
            actual_fontsize += 1;
        }
400
        else if (x_gui.x_font_style == 1 &&
401
402
403
404
405
406
            actual_fontsize >= 5 &&
            actual_fontsize < 13 &&
            actual_fontsize % 2 == 1)
        {
            actual_fontsize += 1;
        }
407
        else if (x_gui.x_font_style == 2 &&
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
            actual_fontsize >= 5 &&
            actual_fontsize % 2 == 1)
        {
            actual_fontsize += 1;
        }
        if (actual_height == 9)
            actual_height += 1;
        //done with exceptions

        width_multiplier = width_multiplier * (actual_fontsize * 0.6);

        scale_length = 4;
        scale_x1 = scale_x;
        scale_y1 = scale_y - actual_height/2;
        scale_x2 = scale_x1 + (scale_length * width_multiplier);
        scale_y2 = scale_y1 + actual_height*1.1;

        //DEBUG
        //fprintf(stderr,"%f %d %d\n",
427
        //    width_multiplier, scale_length, x_gui.x_font_style);
428
429
430
431
432
433
434
435
436
437
438
439
        //sys_vgui(".x%lx.c delete iemguiDEBUG\n", x);
        //sys_vgui(".x%lx.c create rectangle %d %d %d %d -tags iemguiDEBUG\n",
        //    x, scale_x1, scale_y1, scale_x2, scale_y2);
        if (scale_x1 < *xp1) *xp1 = scale_x1;
        if (scale_x2 > *xp2) *xp2 = scale_x2;
        if (scale_y1 < *yp1) *yp1 = scale_y1;
        if (scale_y2 > *yp2) *yp2 = scale_y2;
        //DEBUG
        //sys_vgui(".x%lx.c delete iemguiDEBUG\n", glist_getcanvas(x));
        //sys_vgui(".x%lx.c create rectangle %d %d %d %d -tags iemguiDEBUG\n",
        //    glist_getcanvas(x), *xp1, *yp1, *xp2, *yp2);
    }
440
}
Miller Puckette's avatar
Miller Puckette committed
441
442

static void vu_getrect(t_gobj *z, t_glist *glist,
443
    int *xp1, int *yp1, int *xp2, int *yp2)
Miller Puckette's avatar
Miller Puckette committed
444
445
446
{
    t_vu* x = (t_vu*)z;

447
448
449
    int yyy, end;
    int xpos=text_xpix(&x->x_gui.x_obj, glist);
    int ypos=text_ypix(&x->x_gui.x_obj, glist);
450
    int k1=x->x_led_size+1, k2=IEM_VU_STEPS+1, k3=k1/2, k4=ypos-k3;
451

452
    *xp1 = text_xpix(&x->x_gui.x_obj, glist);
453
    *yp1 = text_ypix(&x->x_gui.x_obj, glist);
454
    *xp2 = *xp1 + x->x_gui.x_w + 2;
455
    *yp2 = *yp1 + x->x_gui.x_h + 4;
456

457
    iemgui_label_getrect(x->x_gui, glist, xp1, yp1, xp2, yp2);
458

459
460
461
462
463
464
465
466
467
    if (x->x_scale)
    {
        //vu has custom scale all labels unlike other iemgui object
        end=xpos+x->x_gui.x_w+4;
        yyy = k4 + k1*(k2-1);
        vu_scale_getrect(x->x_gui, glist, xp1, yp1, xp2, yp2, end+1, yyy+k3+2);
        yyy = k4;
        vu_scale_getrect(x->x_gui, glist, xp1, yp1, xp2, yp2, end+1, yyy+k3+2);
    }
Miller Puckette's avatar
Miller Puckette committed
468
469
470
471
472
473
474
475
476
477
478
479
480
481
}

static void vu_save(t_gobj *z, t_binbuf *b)
{
    t_vu *x = (t_vu *)z;
    int bflcol[3];
    t_symbol *srl[3];

    iemgui_save(&x->x_gui, srl, bflcol);
    binbuf_addv(b, "ssiisiissiiiiiiii", gensym("#X"),gensym("obj"),
                (int)x->x_gui.x_obj.te_xpix, (int)x->x_gui.x_obj.te_ypix,
                gensym("vu"), x->x_gui.x_w, x->x_gui.x_h,
                srl[1], srl[2],
                x->x_gui.x_ldx, x->x_gui.x_ldy,
482
                iem_fstyletoint(&x->x_gui), x->x_gui.x_fontsize,
Miller Puckette's avatar
Miller Puckette committed
483
                bflcol[0], bflcol[2], x->x_scale,
484
                iem_symargstoint(&x->x_gui));
Miller Puckette's avatar
Miller Puckette committed
485
486
487
488
489
    binbuf_addv(b, ";");
}

void vu_check_height(t_vu *x, int h)
{
490
    int n = maxi(h / IEM_VU_STEPS, IEM_VU_MINSIZE);
Miller Puckette's avatar
Miller Puckette committed
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
    x->x_led_size = n-1;
    x->x_gui.x_h = IEM_VU_STEPS * n;
}

static void vu_scale(t_vu *x, t_floatarg fscale)
{
    int i, scale = (int)fscale;

    if(scale != 0) scale = 1;
    if(x->x_scale && !scale)
    {
        t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);

        x->x_scale = (int)scale;
        if(glist_isvisible(x->x_gui.x_glist))
        {
            for(i=1; i<=IEM_VU_STEPS; i++)
            {
                if((i+2)&3)
                    sys_vgui(".x%lx.c delete %lxSCALE%d\n", canvas, x, i);
            }
            i=IEM_VU_STEPS+1;
            sys_vgui(".x%lx.c delete %lxSCALE%d\n", canvas, x, i);
        }
    }
    if(!x->x_scale && scale)
    {
Mathieu L Bouchard's avatar
Mathieu L Bouchard committed
518
        int end=text_xpix(&x->x_gui.x_obj,
519
            x->x_gui.x_glist)+x->x_gui.x_w+4;
Miller Puckette's avatar
Miller Puckette committed
520
521
522
523
524
525
526
527
528
529
        int k1=x->x_led_size+1, k2=IEM_VU_STEPS+1, k3=k1/2;
        int yyy, k4=text_ypix(&x->x_gui.x_obj, x->x_gui.x_glist)-k3;
        t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);

        x->x_scale = (int)scale;
        if(glist_isvisible(x->x_gui.x_glist))
        {
            for(i=1; i<=IEM_VU_STEPS; i++)
            {
                yyy = k4 + k1*(k2-i);
530
531
532
                if((i + 2) & 3)
                    sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
                             "-font {{%s} -%d %s} -fill #%6.6x "
533
                             "-tags {%lxSCALE%d %lxOBJ %lx}\n",
534
                        canvas, end+1, yyy+k3+2, iemgui_vu_scale_str[i], 
535
                        iemgui_font(&x->x_gui), x->x_gui.x_fontsize,
536
                        sys_fontweight, x->x_gui.x_lcol, x, i, x, x);
Miller Puckette's avatar
Miller Puckette committed
537
            }
538
            i = IEM_VU_STEPS + 1;
Miller Puckette's avatar
Miller Puckette committed
539
            yyy = k4 + k1*(k2-i);
540
541
            sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
                     "-font {{%s} -%d %s} -fill #%6.6x "
542
                     "-tags {%lxSCALE%d %lxOBJ %lx}\n",
543
                canvas, end+1, yyy+k3+2, iemgui_vu_scale_str[i], 
544
                iemgui_font(&x->x_gui), x->x_gui.x_fontsize,
545
                sys_fontweight, x->x_gui.x_lcol, x, i, x, x);
Miller Puckette's avatar
Miller Puckette committed
546
547
548
549
550
551
552
553
554
555
556
        }
    }
}

static void vu_properties(t_gobj *z, t_glist *owner)
{
    t_vu *x = (t_vu *)z;
    char buf[800];
    t_symbol *srl[3];

    iemgui_properties(&x->x_gui, srl);
Miller Puckette's avatar
Miller Puckette committed
557
    sprintf(buf, "pdtk_iemgui_dialog %%s |vu| \
Miller Puckette's avatar
Miller Puckette committed
558
559
560
            --------dimensions(pix)(pix):-------- %d %d width: %d %d height: \
            empty 0.0 empty 0.0 empty %d \
            %d no_scale scale %d %d empty %d \
Ivica Ico Bukvic's avatar
Ivica Ico Bukvic committed
561
562
            {%s} {%s} \
            {%s} %d %d \
Miller Puckette's avatar
Miller Puckette committed
563
564
            %d %d \
            %d %d %d\n",
565
566
            x->x_gui.x_w, IEM_GUI_MINSIZE, x->x_gui.x_h,
            IEM_VU_STEPS*IEM_VU_MINSIZE,
Miller Puckette's avatar
Miller Puckette committed
567
568
569
570
            0,/*no_schedule*/
            x->x_scale, -1, -1, -1,/*no linlog, no init, no multi*/
            "nosndno", srl[1]->s_name,/*no send*/
            srl[2]->s_name, x->x_gui.x_ldx, x->x_gui.x_ldy,
571
            x->x_gui.x_font_style, x->x_gui.x_fontsize,
572
573
            0xffffff & x->x_gui.x_bcol, -1/*no front-color*/,
            0xffffff & x->x_gui.x_lcol);
Miller Puckette's avatar
Miller Puckette committed
574
575
576
577
578
    gfxstub_new(&x->x_gui.x_obj.ob_pd, x, buf);
}

static void vu_dialog(t_vu *x, t_symbol *s, int argc, t_atom *argv)
{
579
    canvas_apply_setundo(x->x_gui.x_glist, (t_gobj *)x);
580

Miller Puckette's avatar
Miller Puckette committed
581
582
583
584
585
586
    t_symbol *srl[3];
    int w = (int)atom_getintarg(0, argc, argv);
    int h = (int)atom_getintarg(1, argc, argv);
    int scale = (int)atom_getintarg(4, argc, argv);
    int sr_flags;

587
    srl[0] = s_empty;
Miller Puckette's avatar
Miller Puckette committed
588
    sr_flags = iemgui_dialog(&x->x_gui, srl, argc, argv);
589
    x->x_gui.x_loadinit = 0;
Miller Puckette's avatar
Miller Puckette committed
590
591
592
593
    x->x_gui.x_w = iemgui_clip_size(w);
    vu_check_height(x, h);
    if(scale != 0)
        scale = 1;
594
    vu_scale(x, (t_float)scale);
Miller Puckette's avatar
Miller Puckette committed
595
596
    (*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_CONFIG);
    (*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_IO + sr_flags);
597
598
    //(*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_MOVE);
    //canvas_fixlinesfor(glist_getcanvas(x->x_gui.x_glist), (t_text*)x);
599
    iemgui_shouldvis(&x->x_gui, IEM_GUI_DRAW_MODE_MOVE);
600

601
602
    if (x->x_gui.x_selected) vu_draw_select(x, x->x_gui.x_glist);
    scrollbar_update(x->x_gui.x_glist);
Miller Puckette's avatar
Miller Puckette committed
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
}

static void vu_size(t_vu *x, t_symbol *s, int ac, t_atom *av)
{
    x->x_gui.x_w = iemgui_clip_size((int)atom_getintarg(0, ac, av));
    if(ac > 1)
        vu_check_height(x, (int)atom_getintarg(1, ac, av));
    if(glist_isvisible(x->x_gui.x_glist))
    {
        (*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_MOVE);
        (*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_CONFIG);
        canvas_fixlinesfor(glist_getcanvas(x->x_gui.x_glist), (t_text*)x);
    }
}

static void vu_float(t_vu *x, t_floatarg rms)
{
    int i;

    if(rms <= IEM_VU_MINDB)
        x->x_rms = 0;
    else if(rms >= IEM_VU_MAXDB)
        x->x_rms = IEM_VU_STEPS;
    else
    {
        int i = (int)(2.0*(rms + IEM_VU_OFFSET));
        x->x_rms = iemgui_vu_db2i[i];
    }
    i = (int)(100.0*rms + 10000.5);
632
    rms = 0.01*(t_float)(i - 10000);
Miller Puckette's avatar
Miller Puckette committed
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
    x->x_fr = rms;
    outlet_float(x->x_out_rms, rms);
    x->x_updaterms = 1;
    sys_queuegui(x, x->x_gui.x_glist, vu_draw_update);
}

static void vu_ft1(t_vu *x, t_floatarg peak)
{
    int i;

    if(peak <= IEM_VU_MINDB)
        x->x_peak = 0;
    else if(peak >= IEM_VU_MAXDB)
        x->x_peak = IEM_VU_STEPS;
    else
    {
        int i = (int)(2.0*(peak + IEM_VU_OFFSET));
        x->x_peak = iemgui_vu_db2i[i];
    }
    i = (int)(100.0*peak + 10000.5);
653
    peak = 0.01*(t_float)(i - 10000);
Miller Puckette's avatar
Miller Puckette committed
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
    x->x_fp = peak;
    x->x_updatepeak = 1;
    sys_queuegui(x, x->x_gui.x_glist, vu_draw_update);
    outlet_float(x->x_out_peak, peak);
}

static void vu_bang(t_vu *x)
{
    outlet_float(x->x_out_peak, x->x_fp);
    outlet_float(x->x_out_rms, x->x_fr);
    x->x_updaterms = x->x_updatepeak = 1;
    sys_queuegui(x, x->x_gui.x_glist, vu_draw_update);
}

static void *vu_new(t_symbol *s, int argc, t_atom *argv)
{
    t_vu *x = (t_vu *)pd_new(vu_class);
671
672
    int bflcol[] = {-66577, -1, -1};
    int w = IEM_GUI_DEFAULTSIZE, h = IEM_VU_STEPS*IEM_VU_DEFAULTSIZE;
Mathieu L Bouchard's avatar
Mathieu L Bouchard committed
673
    int ldx = -1, ldy = -8, fs = 10, scale = 1;
Miller Puckette's avatar
Miller Puckette committed
674

675
676
    iem_inttosymargs(&x->x_gui, 0);
    iem_inttofstyle(&x->x_gui, 0);
Miller Puckette's avatar
Miller Puckette committed
677
678
679
680
681
682
683
684
685
686
687
688
689

    if((argc >= 11)&&IS_A_FLOAT(argv,0)&&IS_A_FLOAT(argv,1)
       &&(IS_A_SYMBOL(argv,2)||IS_A_FLOAT(argv,2))
       &&(IS_A_SYMBOL(argv,3)||IS_A_FLOAT(argv,3))
       &&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,5)
       &&IS_A_FLOAT(argv,6)&&IS_A_FLOAT(argv,7)
       &&IS_A_FLOAT(argv,8)&&IS_A_FLOAT(argv,9)&&IS_A_FLOAT(argv,10))
    {
        w = (int)atom_getintarg(0, argc, argv);
        h = (int)atom_getintarg(1, argc, argv);
        iemgui_new_getnames(&x->x_gui, 1, argv);
        ldx = (int)atom_getintarg(4, argc, argv);
        ldy = (int)atom_getintarg(5, argc, argv);
690
        iem_inttofstyle(&x->x_gui, atom_getintarg(6, argc, argv));
Miller Puckette's avatar
Miller Puckette committed
691
692
693
694
695
696
697
        fs = (int)atom_getintarg(7, argc, argv);
        bflcol[0] = (int)atom_getintarg(8, argc, argv);
        bflcol[2] = (int)atom_getintarg(9, argc, argv);
        scale = (int)atom_getintarg(10, argc, argv);
    }
    else iemgui_new_getnames(&x->x_gui, 1, 0);
    if((argc == 12)&&IS_A_FLOAT(argv,11))
698
        iem_inttosymargs(&x->x_gui, atom_getintarg(11, argc, argv));
Miller Puckette's avatar
Miller Puckette committed
699
700
701
    x->x_gui.x_draw = (t_iemfunptr)vu_draw;

    x->x_gui.x_glist = (t_glist *)canvas_getcurrent();
702
703
    if (x->x_gui.x_font_style<0 || x->x_gui.x_font_style>2) x->x_gui.x_font_style=0;
    if(iemgui_has_rcv(&x->x_gui))
Miller Puckette's avatar
Miller Puckette committed
704
705
706
707
        pd_bind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
    x->x_gui.x_ldx = ldx;
    x->x_gui.x_ldy = ldy;

708
709
    x->x_gui.x_snd = s_empty;

Miller Puckette's avatar
Miller Puckette committed
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
    if(fs < 4)
        fs = 4;
    x->x_gui.x_fontsize = fs;
    x->x_gui.x_w = iemgui_clip_size(w);
    vu_check_height(x, h);
    iemgui_all_colfromload(&x->x_gui, bflcol);
    if(scale != 0)
        scale = 1;
    x->x_scale = scale;
    x->x_peak = 0;
    x->x_rms = 0;
    x->x_fp = -101.0;
    x->x_fr = -101.0;
    iemgui_verify_snd_ne_rcv(&x->x_gui);
    inlet_new(&x->x_gui.x_obj, &x->x_gui.x_obj.ob_pd, &s_float, gensym("ft1"));
    x->x_out_rms = outlet_new(&x->x_gui.x_obj, &s_float);
    x->x_out_peak = outlet_new(&x->x_gui.x_obj, &s_float);
727

728
729
    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
730
    x->x_gui.x_obj.te_iemgui = 1;
731

Miller Puckette's avatar
Miller Puckette committed
732
733
734
735
736
    return (x);
}

static void vu_free(t_vu *x)
{
737
    if(iemgui_has_rcv(&x->x_gui))
Miller Puckette's avatar
Miller Puckette committed
738
739
        pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
    gfxstub_deleteforkey(x);
740

741
742
    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
Miller Puckette's avatar
Miller Puckette committed
743
744
745
746
747
}

void g_vumeter_setup(void)
{
    vu_class = class_new(gensym("vu"), (t_newmethod)vu_new, (t_method)vu_free,
748
        sizeof(t_vu), 0, A_GIMME, 0);
Miller Puckette's avatar
Miller Puckette committed
749
750
751
752
    class_addbang(vu_class,vu_bang);
    class_addfloat(vu_class,vu_float);
    class_addmethod(vu_class, (t_method)vu_ft1, gensym("ft1"), A_FLOAT, 0);
    class_addmethod(vu_class, (t_method)vu_dialog, gensym("dialog"),
753
        A_GIMME, 0);
Miller Puckette's avatar
Miller Puckette committed
754
    class_addmethod(vu_class, (t_method)vu_size, gensym("size"), A_GIMME, 0);
755
756
    class_addmethod(vu_class, (t_method)vu_scale,
        gensym("scale"), A_DEFFLOAT, 0);
757
    iemgui_class_addmethods(vu_class);
758
    scalehandle_class = class_new(gensym("_scalehandle"), 0, 0,
759
                  sizeof(t_scalehandle), CLASS_PD, 0);
760
    class_addmethod(scalehandle_class, (t_method)vu__clickhook,
761
            gensym("_click"), A_FLOAT, A_FLOAT, A_FLOAT, 0);
762
    class_addmethod(scalehandle_class, (t_method)vu__motionhook,
763
            gensym("_motion"), A_FLOAT, A_FLOAT, 0);
764

765
    wb_init(&vu_widgetbehavior,vu_getrect,0);
Miller Puckette's avatar
Miller Puckette committed
766
767
768
769
770
    class_setwidget(vu_class,&vu_widgetbehavior);
    class_sethelpsymbol(vu_class, gensym("vu"));
    class_setsavefn(vu_class, vu_save);
    class_setpropertiesfn(vu_class, vu_properties);
}