Update of /cvsroot/pure-data/externals/pdp/modules/generic
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18425
Added Files:
pdp_metro.c
Log Message:
added missing file pdp/pdp_metro.c
--- NEW FILE: pdp_metro.c ---
/*
* Pure Data Packet module. Standard sync rates.
* Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* pdp_metro
this is the main audio/video sync module. use this if
you need to produce synchronized raw output. this uses
'industry standard' integer sampling ratios.
it works like this. for example, the most awkward 30 * 999/1000 Hz rate.
*/
#include "pdp.h"
typedef struct _metro_struct
{
t_object x_obj;
t_float x_f;
t_clock *x_clock;
t_outlet *x_outlet;
t_int x_count; // current count for (upsampled) audio ticks
t_int x_den; // video framerate denominator and nominator
t_int x_nom;
} t_metro;
static t_int *metro_perform(t_int *w);
#define DSP_ARG(type, name, source) type name = (type)source
static void metro_dsp(t_metro *x, t_signal **sp)
{
dsp_add(metro_perform, 3, x, sp[0]->s_n, (int)sys_getsr());
}
static t_int *metro_perform(t_int *w){
DSP_ARG(t_metro*, x, w[1]);
DSP_ARG(t_int, n, w[2]);
DSP_ARG(t_int, sr, w[3]);
t_int period = sr * x->x_nom;
t_int upsample = x->x_den;
t_int dobang = 0;
//fprintf(stderr, "%d/%d\t%d\t%d\n", x->x_den, x->x_nom, x->x_count, period);
x->x_count += n * upsample;
while (x->x_count > period) {
dobang = 1;
x->x_count -= period;
}
if (dobang) clock_set(x->x_clock, 0);
return w+4;
}
static void metro_tick(t_metro *x)
{
outlet_bang(x->x_outlet);
}
static void metro_reset(t_metro *x){
x->x_count = 0;
}
static void metro_fps(t_metro *x, t_float fden, t_float fnom)
{
int den = (int)fden;
int nom = (int)fnom;
if (den < 1) den = 1;
if (nom < 1) nom = 1;
x->x_den = den;
x->x_nom = nom;
}
static void metro_free(t_metro *x)
{
clock_unset(x->x_clock);
}
static t_class *metro_class;
static void *metro_new(t_symbol *s, int argc, t_atom *argv)
{
t_metro *x = (t_metro *)pd_new(metro_class);
x->x_outlet = outlet_new(&x->x_obj, &s_bang);
x->x_clock = clock_new(x, (t_method)metro_tick);
x->x_count = 0;
metro_fps(x, 1, 1);
return (void *)x;
}
#ifdef __cplusplus
extern "C"
{
#endif
void pdp_metro_setup(void)
{
metro_class = class_new(gensym("pdp_metro~"), (t_newmethod)metro_new,
(t_method)metro_free, sizeof(t_metro), 0, A_NULL);
CLASS_MAINSIGNALIN(metro_class, t_metro, x_f);
class_addmethod(metro_class, (t_method)metro_tick, gensym("tick"), A_NULL);
class_addmethod(metro_class, (t_method)metro_dsp, gensym("dsp"), A_NULL);
class_addmethod(metro_class, (t_method)metro_fps, gensym("fps"), A_FLOAT, A_DEFFLOAT, A_NULL);
}
#ifdef __cplusplus
}
#endif