/* Rhythm estimation in real time -- PD wrapper Copyright (C) 2000 Jarno Seppänen and Piotr Majdak $Id: pd_rhythm_quantum.c,v 1.1 2002-11-19 11:39:55 ggeiger Exp $ This file is part of rhythm_estimator. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "m_pd.h" #include "pd_rhythm_estimator.h" #include "pd_rhythm_quantum.h" #include "rhythm_quantum.h" static t_class* pd_rhythm_quantum_class = NULL; void rhythm_quantum_setup (void) { pd_rhythm_quantum_class = class_new (gensym ("rhythm_quantum"), (t_newmethod)pd_rhythm_quantum_new, (t_method)pd_rhythm_quantum_free, sizeof (pd_t_rhythm_quantum), 0, A_DEFSYM, 0); assert (pd_rhythm_quantum_class != NULL); /* Set the callback for bang messages */ class_addbang (pd_rhythm_quantum_class, pd_rhythm_quantum_bang); /* SET-Message */ class_addmethod(pd_rhythm_quantum_class, (t_method)pd_rhythm_quantum_set, gensym("set"), A_SYMBOL, A_FLOAT, 0); /* PRINT-Message */ class_addmethod(pd_rhythm_quantum_class, (t_method)pd_rhythm_quantum_print, gensym("print"), 0); } static void* pd_rhythm_quantum_new (t_symbol* s) { pd_t_rhythm_quantum* x = NULL; /* Allocate object struct */ x = (pd_t_rhythm_quantum*)pd_new (pd_rhythm_quantum_class); assert (x != NULL); /* Construct rhythm_quantum */ x->rhythm_quantum = rhythm_quantum_new (); assert (x->rhythm_quantum != NULL); rhythm_quantum_initialize (x->rhythm_quantum); /* Initialize debug array */ pd_rhythm_quantum_array_initialize (x, s); /* Create outlet(s) */ /* Bang message outlet */ outlet_new (&x->x_obj, gensym ("float")); return x; } static void pd_rhythm_quantum_free (pd_t_rhythm_quantum* x) { /* precondition(s) */ assert (x != NULL); pd_rhythm_quantum_array_finish (x); /* Destruct rhythm_quantum */ rhythm_quantum_finish (x->rhythm_quantum); rhythm_quantum_delete (x->rhythm_quantum); x->rhythm_quantum = NULL; } static void pd_rhythm_quantum_bang (pd_t_rhythm_quantum* x) { float *vector; unsigned len; unsigned i; #if RHYTHM_ESTIMATOR_DEBUG_PROFILE double time; #endif /* precondition(s) */ assert (x != NULL); /* Invoke rhythm_quantum onset event */ pd_rhythm_quantum_array_read(x, &vector, &len); #if RHYTHM_ESTIMATOR_DEBUG_PROFILE time = sys_getrealtime(); #endif outlet_float(x->x_obj.ob_outlet, rhythm_quantum_compute_quantum (x->rhythm_quantum, vector, len)); #if RHYTHM_ESTIMATOR_DEBUG_PROFILE printf("quantum: Used time: %f\n", (sys_getrealtime()- time)*1000.); #endif /* FIXME - Only for debugging: copy error function to histogram array */ #if RHYTHM_ESTIMATOR_DEBUG_QUANTUM for(i=0; irhythm_quantum->gcd_re_length; i++) vector[i]=x->rhythm_quantum->gcd_remainder_error[i]; garray_redraw ((t_garray*)pd_findbyclass (x->array_symbol, garray_class)); #endif } static void pd_rhythm_quantum_set (pd_t_rhythm_quantum* x, t_symbol* s, t_float value) { /* Format: s value */ if(strlen(s->s_name)) { /* Check for IOI_RESOLUTION */ if (!strncmp( s->s_name, RHYTHM_ESTIMATOR_IOI_RESOLUTION_STR , strlen(RHYTHM_ESTIMATOR_IOI_RESOLUTION_STR))) { /* rhythm_ioi_quantum_set_ioi_resolution(x, value);*/ x->rhythm_quantum->ioi_resolution = ParameterCheck(RHYTHM_ESTIMATOR_IOI_RESOLUTION_STR, value, RHYTHM_ESTIMATOR_IOI_RESOLUTION_MIN, RHYTHM_ESTIMATOR_IOI_RESOLUTION_MAX); return; } else /* Check for MIN_QUANTUM */ if (!strncmp(s->s_name, RHYTHM_ESTIMATOR_MIN_QUANTUM_STR , strlen(RHYTHM_ESTIMATOR_MIN_QUANTUM_STR))) { x->rhythm_quantum->min_quantum = ParameterCheck(RHYTHM_ESTIMATOR_MIN_QUANTUM_STR, value, RHYTHM_ESTIMATOR_MIN_QUANTUM_MIN, RHYTHM_ESTIMATOR_MIN_QUANTUM_MAX); return; } else /* Check for MAX_QUANTUM */ if (!strncmp(s->s_name, RHYTHM_ESTIMATOR_MAX_QUANTUM_STR , strlen(RHYTHM_ESTIMATOR_MAX_QUANTUM_STR))) { x->rhythm_quantum->max_quantum = ParameterCheck(RHYTHM_ESTIMATOR_MAX_QUANTUM_STR, value, RHYTHM_ESTIMATOR_MAX_QUANTUM_MIN, RHYTHM_ESTIMATOR_MAX_QUANTUM_MAX); return; } else /* Check for GCD_PERC */ if (!strncmp(s->s_name,RHYTHM_QUANTUM_GCD_PERC_STR , strlen(RHYTHM_QUANTUM_GCD_PERC_STR))) { x->rhythm_quantum->gcd_perc = ParameterCheck(RHYTHM_QUANTUM_GCD_PERC_STR, value, RHYTHM_QUANTUM_GCD_PERC_MIN, RHYTHM_QUANTUM_GCD_PERC_MAX); return; } } printf("Error, use format like: 'parameter value'\n"); printf("Valid 'parameter' for rhythm_quantum:\n "); printf(RHYTHM_ESTIMATOR_IOI_RESOLUTION_STR); printf("\n "); printf(RHYTHM_ESTIMATOR_MIN_QUANTUM_STR); printf("\n "); printf(RHYTHM_ESTIMATOR_MAX_QUANTUM_STR); printf("\n "); printf(RHYTHM_QUANTUM_GCD_PERC_STR); printf("\n\n"); } static void pd_rhythm_quantum_print (pd_t_rhythm_quantum* x) { printf("QUANTUM-Paramater:\n %s: %0.1f", RHYTHM_ESTIMATOR_IOI_RESOLUTION_STR, x->rhythm_quantum->ioi_resolution); printf("\n "); printf("%s: %0.1f",RHYTHM_ESTIMATOR_MIN_QUANTUM_STR, x->rhythm_quantum->min_quantum); printf("\n "); printf("%s: %0.1f",RHYTHM_ESTIMATOR_MAX_QUANTUM_STR, x->rhythm_quantum->max_quantum); printf("\n "); printf("%s: %0.1f",RHYTHM_QUANTUM_GCD_PERC_STR, x->rhythm_quantum->gcd_perc); printf("\n\n"); } static void pd_rhythm_quantum_array_initialize (pd_t_rhythm_quantum* x, t_symbol* s) { t_garray *a; x->array_symbol = s; /* Find the array by name */ a = (t_garray*)pd_findbyclass (x->array_symbol, garray_class); if (a == 0) { if (s->s_name != NULL) { pd_error(x, "rhythm_quantum: %s: no such array", x->array_symbol->s_name); } x->array_vec = 0; } /* Get array buffer length and pointer */ else if (!garray_getfloatarray (a, &x->array_nsampsintab, &x->array_vec)) { error("rhythm_quantum: %s: bad array", x->array_symbol->s_name); x->array_vec = 0; } else garray_usedindsp (a); if (x->array_vec == NULL) { printf ("rhythm_quantum: array %s not given\n", x->array_symbol->s_name); } } static void pd_rhythm_quantum_array_read (pd_t_rhythm_quantum* x, float** vector, unsigned* length) { t_garray *a; /* Find the array by name and test if we still have an array */ a = (t_garray*)pd_findbyclass (x->array_symbol, garray_class); if (a == 0) { if (x->array_symbol->s_name != NULL) { pd_error(x, "rhythm_quantum: %s: no such array", x->array_symbol->s_name); } x->array_vec = 0; } /* Initialize array buffer length and pointer */ else if (!garray_getfloatarray (a, &x->array_nsampsintab, &x->array_vec)) { error("rhythm_quantum: %s: bad array", x->array_symbol->s_name); x->array_vec = 0; } else { garray_usedindsp (a); *vector = x->array_vec; *length = x->array_nsampsintab; } } static void pd_rhythm_quantum_array_finish (pd_t_rhythm_quantum* x) { } /* EOF */