diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/x_time.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/x_time.c | 519 |
1 files changed, 0 insertions, 519 deletions
diff --git a/apps/plugins/pdbox/PDa/src/x_time.c b/apps/plugins/pdbox/PDa/src/x_time.c index 580a30b36d..4cab8bc364 100644 --- a/apps/plugins/pdbox/PDa/src/x_time.c +++ b/apps/plugins/pdbox/PDa/src/x_time.c | |||
@@ -518,523 +518,4 @@ void x_time_setup(void) | |||
518 | timer_setup(); | 518 | timer_setup(); |
519 | pipe_setup(); | 519 | pipe_setup(); |
520 | } | 520 | } |
521 | /* Copyright (c) 1997-1999 Miller Puckette. | ||
522 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
523 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
524 | |||
525 | /* clock objects */ | ||
526 | |||
527 | #include "m_pd.h" | ||
528 | #include <stdio.h> | ||
529 | /* -------------------------- delay ------------------------------ */ | ||
530 | static t_class *delay_class; | ||
531 | |||
532 | typedef struct _delay | ||
533 | { | ||
534 | t_object x_obj; | ||
535 | t_clock *x_clock; | ||
536 | double x_deltime; | ||
537 | } t_delay; | ||
538 | |||
539 | static void delay_bang(t_delay *x) | ||
540 | { | ||
541 | clock_delay(x->x_clock, x->x_deltime); | ||
542 | } | ||
543 | |||
544 | static void delay_stop(t_delay *x) | ||
545 | { | ||
546 | clock_unset(x->x_clock); | ||
547 | } | ||
548 | |||
549 | static void delay_ft1(t_delay *x, t_floatarg g) | ||
550 | { | ||
551 | if (g < 0) g = 0; | ||
552 | x->x_deltime = g; | ||
553 | } | ||
554 | |||
555 | static void delay_float(t_delay *x, t_float f) | ||
556 | { | ||
557 | delay_ft1(x, f); | ||
558 | delay_bang(x); | ||
559 | } | ||
560 | |||
561 | static void delay_tick(t_delay *x) | ||
562 | { | ||
563 | outlet_bang(x->x_obj.ob_outlet); | ||
564 | } | ||
565 | |||
566 | static void delay_free(t_delay *x) | ||
567 | { | ||
568 | clock_free(x->x_clock); | ||
569 | } | ||
570 | |||
571 | static void *delay_new(t_floatarg f) | ||
572 | { | ||
573 | t_delay *x = (t_delay *)pd_new(delay_class); | ||
574 | delay_ft1(x, f); | ||
575 | x->x_clock = clock_new(x, (t_method)delay_tick); | ||
576 | outlet_new(&x->x_obj, gensym("bang")); | ||
577 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); | ||
578 | return (x); | ||
579 | } | ||
580 | |||
581 | static void delay_setup(void) | ||
582 | { | ||
583 | delay_class = class_new(gensym("delay"), (t_newmethod)delay_new, | ||
584 | (t_method)delay_free, sizeof(t_delay), 0, A_DEFFLOAT, 0); | ||
585 | class_addcreator((t_newmethod)delay_new, gensym("del"), A_DEFFLOAT, 0); | ||
586 | class_addbang(delay_class, delay_bang); | ||
587 | class_addmethod(delay_class, (t_method)delay_stop, gensym("stop"), 0); | ||
588 | class_addmethod(delay_class, (t_method)delay_ft1, | ||
589 | gensym("ft1"), A_FLOAT, 0); | ||
590 | class_addfloat(delay_class, (t_method)delay_float); | ||
591 | } | ||
592 | |||
593 | /* -------------------------- metro ------------------------------ */ | ||
594 | static t_class *metro_class; | ||
595 | |||
596 | typedef struct _metro | ||
597 | { | ||
598 | t_object x_obj; | ||
599 | t_clock *x_clock; | ||
600 | double x_deltime; | ||
601 | int x_hit; | ||
602 | } t_metro; | ||
603 | |||
604 | static void metro_tick(t_metro *x) | ||
605 | { | ||
606 | x->x_hit = 0; | ||
607 | outlet_bang(x->x_obj.ob_outlet); | ||
608 | if (!x->x_hit) clock_delay(x->x_clock, x->x_deltime); | ||
609 | } | ||
610 | |||
611 | static void metro_float(t_metro *x, t_float f) | ||
612 | { | ||
613 | if (f != 0) metro_tick(x); | ||
614 | else clock_unset(x->x_clock); | ||
615 | x->x_hit = 1; | ||
616 | } | ||
617 | |||
618 | static void metro_bang(t_metro *x) | ||
619 | { | ||
620 | metro_float(x, 1); | ||
621 | } | ||
622 | |||
623 | static void metro_stop(t_metro *x) | ||
624 | { | ||
625 | metro_float(x, 0); | ||
626 | } | ||
627 | |||
628 | static void metro_ft1(t_metro *x, t_floatarg g) | ||
629 | { | ||
630 | if (g < 1) g = 1; | ||
631 | x->x_deltime = g; | ||
632 | } | ||
633 | |||
634 | static void metro_free(t_metro *x) | ||
635 | { | ||
636 | clock_free(x->x_clock); | ||
637 | } | ||
638 | |||
639 | static void *metro_new(t_floatarg f) | ||
640 | { | ||
641 | t_metro *x = (t_metro *)pd_new(metro_class); | ||
642 | metro_ft1(x, f); | ||
643 | x->x_hit = 0; | ||
644 | x->x_clock = clock_new(x, (t_method)metro_tick); | ||
645 | outlet_new(&x->x_obj, gensym("bang")); | ||
646 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); | ||
647 | return (x); | ||
648 | } | ||
649 | |||
650 | static void metro_setup(void) | ||
651 | { | ||
652 | metro_class = class_new(gensym("metro"), (t_newmethod)metro_new, | ||
653 | (t_method)metro_free, sizeof(t_metro), 0, A_DEFFLOAT, 0); | ||
654 | class_addbang(metro_class, metro_bang); | ||
655 | class_addmethod(metro_class, (t_method)metro_stop, gensym("stop"), 0); | ||
656 | class_addmethod(metro_class, (t_method)metro_ft1, gensym("ft1"), | ||
657 | A_FLOAT, 0); | ||
658 | class_addfloat(metro_class, (t_method)metro_float); | ||
659 | } | ||
660 | |||
661 | /* -------------------------- line ------------------------------ */ | ||
662 | static t_class *line_class; | ||
663 | |||
664 | typedef struct _line | ||
665 | { | ||
666 | t_object x_obj; | ||
667 | t_clock *x_clock; | ||
668 | double x_targettime; | ||
669 | t_float x_targetval; | ||
670 | double x_prevtime; | ||
671 | t_float x_setval; | ||
672 | int x_gotinlet; | ||
673 | t_float x_grain; | ||
674 | double x_1overtimediff; | ||
675 | double x_in1val; | ||
676 | } t_line; | ||
677 | |||
678 | static void line_tick(t_line *x) | ||
679 | { | ||
680 | double timenow = clock_getsystime(); | ||
681 | double msectogo = - clock_gettimesince(x->x_targettime); | ||
682 | if (msectogo < 1E-9) | ||
683 | { | ||
684 | outlet_float(x->x_obj.ob_outlet, x->x_targetval); | ||
685 | } | ||
686 | else | ||
687 | { | ||
688 | outlet_float(x->x_obj.ob_outlet, | ||
689 | x->x_setval + x->x_1overtimediff * (timenow - x->x_prevtime) | ||
690 | * (x->x_targetval - x->x_setval)); | ||
691 | clock_delay(x->x_clock, | ||
692 | (x->x_grain > msectogo ? msectogo : x->x_grain)); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | static void line_float(t_line *x, t_float f) | ||
697 | { | ||
698 | double timenow = clock_getsystime(); | ||
699 | if (x->x_gotinlet && x->x_in1val > 0) | ||
700 | { | ||
701 | if (timenow > x->x_targettime) x->x_setval = x->x_targetval; | ||
702 | else x->x_setval = x->x_setval + x->x_1overtimediff * | ||
703 | (timenow - x->x_prevtime) | ||
704 | * (x->x_targetval - x->x_setval); | ||
705 | x->x_prevtime = timenow; | ||
706 | x->x_targettime = clock_getsystimeafter(x->x_in1val); | ||
707 | x->x_targetval = f; | ||
708 | line_tick(x); | ||
709 | x->x_gotinlet = 0; | ||
710 | x->x_1overtimediff = 1./ (x->x_targettime - timenow); | ||
711 | clock_delay(x->x_clock, | ||
712 | (x->x_grain > x->x_in1val ? x->x_in1val : x->x_grain)); | ||
713 | |||
714 | } | ||
715 | else | ||
716 | { | ||
717 | clock_unset(x->x_clock); | ||
718 | x->x_targetval = x->x_setval = f; | ||
719 | outlet_float(x->x_obj.ob_outlet, f); | ||
720 | } | ||
721 | x->x_gotinlet = 0; | ||
722 | } | ||
723 | 521 | ||
724 | static void line_ft1(t_line *x, t_floatarg g) | ||
725 | { | ||
726 | x->x_in1val = g; | ||
727 | x->x_gotinlet = 1; | ||
728 | } | ||
729 | |||
730 | static void line_stop(t_line *x) | ||
731 | { | ||
732 | x->x_targetval = x->x_setval; | ||
733 | clock_unset(x->x_clock); | ||
734 | } | ||
735 | |||
736 | static void line_free(t_line *x) | ||
737 | { | ||
738 | clock_free(x->x_clock); | ||
739 | } | ||
740 | |||
741 | static void *line_new(t_floatarg f, t_floatarg grain) | ||
742 | { | ||
743 | t_line *x = (t_line *)pd_new(line_class); | ||
744 | x->x_targetval = x->x_setval = f; | ||
745 | x->x_gotinlet = 0; | ||
746 | x->x_1overtimediff = 1; | ||
747 | x->x_clock = clock_new(x, (t_method)line_tick); | ||
748 | x->x_targettime = x->x_prevtime = clock_getsystime(); | ||
749 | if (grain <= 0) grain = 20; | ||
750 | x->x_grain = grain; | ||
751 | outlet_new(&x->x_obj, gensym("float")); | ||
752 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); | ||
753 | return (x); | ||
754 | } | ||
755 | |||
756 | static void line_setup(void) | ||
757 | { | ||
758 | line_class = class_new(gensym("line"), (t_newmethod)line_new, | ||
759 | (t_method)line_free, sizeof(t_line), 0, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
760 | class_addmethod(line_class, (t_method)line_ft1, | ||
761 | gensym("ft1"), A_FLOAT, 0); | ||
762 | class_addmethod(line_class, (t_method)line_stop, | ||
763 | gensym("stop"), 0); | ||
764 | class_addfloat(line_class, (t_method)line_float); | ||
765 | } | ||
766 | |||
767 | /* -------------------------- timer ------------------------------ */ | ||
768 | static t_class *timer_class; | ||
769 | |||
770 | typedef struct _timer | ||
771 | { | ||
772 | t_object x_obj; | ||
773 | t_time x_settime; | ||
774 | } t_timer; | ||
775 | |||
776 | static void timer_bang(t_timer *x) | ||
777 | { | ||
778 | x->x_settime = clock_getsystime(); | ||
779 | } | ||
780 | |||
781 | static void timer_bang2(t_timer *x) | ||
782 | { | ||
783 | t_time diff = clock_gettimesince(x->x_settime); | ||
784 | outlet_float(x->x_obj.ob_outlet, diff); | ||
785 | } | ||
786 | |||
787 | static void *timer_new(t_floatarg f) | ||
788 | { | ||
789 | t_timer *x = (t_timer *)pd_new(timer_class); | ||
790 | timer_bang(x); | ||
791 | outlet_new(&x->x_obj, gensym("float")); | ||
792 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2")); | ||
793 | return (x); | ||
794 | } | ||
795 | |||
796 | static void timer_setup(void) | ||
797 | { | ||
798 | timer_class = class_new(gensym("timer"), (t_newmethod)timer_new, 0, | ||
799 | sizeof(t_timer), 0, A_DEFFLOAT, 0); | ||
800 | class_addbang(timer_class, timer_bang); | ||
801 | class_addmethod(timer_class, (t_method)timer_bang2, gensym("bang2"), 0); | ||
802 | } | ||
803 | |||
804 | |||
805 | /* -------------------------- pipe -------------------------- */ | ||
806 | |||
807 | static t_class *pipe_class; | ||
808 | |||
809 | typedef struct _hang | ||
810 | { | ||
811 | t_clock *h_clock; | ||
812 | struct _hang *h_next; | ||
813 | struct _pipe *h_owner; | ||
814 | t_gpointer *h_gp; | ||
815 | union word h_vec[1]; /* not the actual number. */ | ||
816 | } t_hang; | ||
817 | |||
818 | typedef struct pipeout | ||
819 | { | ||
820 | t_atom p_atom; | ||
821 | t_outlet *p_outlet; | ||
822 | } t_pipeout; | ||
823 | |||
824 | typedef struct _pipe | ||
825 | { | ||
826 | t_object x_obj; | ||
827 | int x_n; | ||
828 | int x_nptr; | ||
829 | float x_deltime; | ||
830 | t_pipeout *x_vec; | ||
831 | t_gpointer *x_gp; | ||
832 | t_hang *x_hang; | ||
833 | } t_pipe; | ||
834 | |||
835 | static void *pipe_new(t_symbol *s, int argc, t_atom *argv) | ||
836 | { | ||
837 | t_pipe *x = (t_pipe *)pd_new(pipe_class); | ||
838 | t_atom defarg, *ap; | ||
839 | t_pipeout *vec, *vp; | ||
840 | t_gpointer *gp; | ||
841 | int nptr = 0; | ||
842 | int i; | ||
843 | float deltime; | ||
844 | if (argc) | ||
845 | { | ||
846 | if (argv[argc-1].a_type != A_FLOAT) | ||
847 | { | ||
848 | char stupid[80]; | ||
849 | atom_string(&argv[argc-1], stupid, 79); | ||
850 | post("pipe: %s: bad time delay value", stupid); | ||
851 | deltime = 0; | ||
852 | } | ||
853 | else deltime = argv[argc-1].a_w.w_float; | ||
854 | argc--; | ||
855 | } | ||
856 | else deltime = 0; | ||
857 | if (!argc) | ||
858 | { | ||
859 | argv = &defarg; | ||
860 | argc = 1; | ||
861 | SETFLOAT(&defarg, 0); | ||
862 | } | ||
863 | x->x_n = argc; | ||
864 | vec = x->x_vec = (t_pipeout *)getbytes(argc * sizeof(*x->x_vec)); | ||
865 | |||
866 | for (i = argc, ap = argv; i--; ap++) | ||
867 | if (ap->a_type == A_SYMBOL && *ap->a_w.w_symbol->s_name == 'p') | ||
868 | nptr++; | ||
869 | |||
870 | gp = x->x_gp = (t_gpointer *)t_getbytes(nptr * sizeof (*gp)); | ||
871 | x->x_nptr = nptr; | ||
872 | |||
873 | for (i = 0, vp = vec, ap = argv; i < argc; i++, ap++, vp++) | ||
874 | { | ||
875 | if (ap->a_type == A_FLOAT) | ||
876 | { | ||
877 | vp->p_atom = *ap; | ||
878 | vp->p_outlet = outlet_new(&x->x_obj, &s_float); | ||
879 | if (i) floatinlet_new(&x->x_obj, &vp->p_atom.a_w.w_float); | ||
880 | } | ||
881 | else if (ap->a_type == A_SYMBOL) | ||
882 | { | ||
883 | char c = *ap->a_w.w_symbol->s_name; | ||
884 | if (c == 's') | ||
885 | { | ||
886 | SETSYMBOL(&vp->p_atom, &s_symbol); | ||
887 | vp->p_outlet = outlet_new(&x->x_obj, &s_symbol); | ||
888 | if (i) symbolinlet_new(&x->x_obj, &vp->p_atom.a_w.w_symbol); | ||
889 | } | ||
890 | else if (c == 'p') | ||
891 | { | ||
892 | vp->p_atom.a_type = A_POINTER; | ||
893 | vp->p_atom.a_w.w_gpointer = gp; | ||
894 | gpointer_init(gp); | ||
895 | vp->p_outlet = outlet_new(&x->x_obj, &s_pointer); | ||
896 | if (i) pointerinlet_new(&x->x_obj, gp); | ||
897 | gp++; | ||
898 | } | ||
899 | else | ||
900 | { | ||
901 | if (c != 'f') error("pack: %s: bad type", | ||
902 | ap->a_w.w_symbol->s_name); | ||
903 | SETFLOAT(&vp->p_atom, 0); | ||
904 | vp->p_outlet = outlet_new(&x->x_obj, &s_float); | ||
905 | if (i) floatinlet_new(&x->x_obj, &vp->p_atom.a_w.w_float); | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | floatinlet_new(&x->x_obj, &x->x_deltime); | ||
910 | x->x_hang = 0; | ||
911 | x->x_deltime = deltime; | ||
912 | return (x); | ||
913 | } | ||
914 | |||
915 | static void hang_free(t_hang *h) | ||
916 | { | ||
917 | t_pipe *x = h->h_owner; | ||
918 | t_gpointer *gp; | ||
919 | int i; | ||
920 | for (gp = h->h_gp, i = x->x_nptr; i--; gp++) | ||
921 | gpointer_unset(gp); | ||
922 | freebytes(h->h_gp, x->x_nptr * sizeof(*h->h_gp)); | ||
923 | clock_free(h->h_clock); | ||
924 | freebytes(h, sizeof(*h) + (x->x_n - 1) * sizeof(*h->h_vec)); | ||
925 | } | ||
926 | |||
927 | static void hang_tick(t_hang *h) | ||
928 | { | ||
929 | t_pipe *x = h->h_owner; | ||
930 | t_hang *h2, *h3; | ||
931 | t_pipeout *p; | ||
932 | int i; | ||
933 | union word *w; | ||
934 | if (x->x_hang == h) x->x_hang = h->h_next; | ||
935 | else for (h2 = x->x_hang; h3 = h2->h_next; h2 = h3) | ||
936 | { | ||
937 | if (h3 == h) | ||
938 | { | ||
939 | h2->h_next = h3->h_next; | ||
940 | break; | ||
941 | } | ||
942 | } | ||
943 | for (i = x->x_n, p = x->x_vec + (x->x_n - 1), w = h->h_vec + (x->x_n - 1); | ||
944 | i--; p--, w--) | ||
945 | { | ||
946 | switch (p->p_atom.a_type) | ||
947 | { | ||
948 | case A_FLOAT: outlet_float(p->p_outlet, w->w_float); break; | ||
949 | case A_SYMBOL: outlet_symbol(p->p_outlet, w->w_symbol); break; | ||
950 | case A_POINTER: | ||
951 | if (gpointer_check(w->w_gpointer, 1)) | ||
952 | outlet_pointer(p->p_outlet, w->w_gpointer); | ||
953 | else post("pipe: stale pointer"); | ||
954 | break; | ||
955 | } | ||
956 | } | ||
957 | hang_free(h); | ||
958 | } | ||
959 | |||
960 | static void pipe_list(t_pipe *x, t_symbol *s, int ac, t_atom *av) | ||
961 | { | ||
962 | t_hang *h = (t_hang *) | ||
963 | getbytes(sizeof(*h) + (x->x_n - 1) * sizeof(*h->h_vec)); | ||
964 | t_gpointer *gp, *gp2; | ||
965 | t_pipeout *p; | ||
966 | int i, n = x->x_n; | ||
967 | t_atom *ap; | ||
968 | t_word *w; | ||
969 | h->h_gp = (t_gpointer *)getbytes(x->x_nptr * sizeof(t_gpointer)); | ||
970 | if (ac > n) ac = n; | ||
971 | for (i = 0, gp = x->x_gp, p = x->x_vec, ap = av; i < ac; | ||
972 | i++, p++, ap++) | ||
973 | { | ||
974 | switch (p->p_atom.a_type) | ||
975 | { | ||
976 | case A_FLOAT: p->p_atom.a_w.w_float = atom_getfloat(ap); break; | ||
977 | case A_SYMBOL: p->p_atom.a_w.w_symbol = atom_getsymbol(ap); break; | ||
978 | case A_POINTER: | ||
979 | gpointer_unset(gp); | ||
980 | if (ap->a_type != A_POINTER) | ||
981 | post("pipe: bad pointer"); | ||
982 | else | ||
983 | { | ||
984 | *gp = *(ap->a_w.w_gpointer); | ||
985 | if (gp->gp_stub) gp->gp_stub->gs_refcount++; | ||
986 | } | ||
987 | gp++; | ||
988 | } | ||
989 | } | ||
990 | for (i = 0, gp = x->x_gp, gp2 = h->h_gp, p = x->x_vec, w = h->h_vec; | ||
991 | i < n; i++, p++, w++) | ||
992 | { | ||
993 | if (p->p_atom.a_type == A_POINTER) | ||
994 | { | ||
995 | if (gp->gp_stub) gp->gp_stub->gs_refcount++; | ||
996 | w->w_gpointer = gp2; | ||
997 | *gp2++ = *gp++; | ||
998 | } | ||
999 | else *w = p->p_atom.a_w; | ||
1000 | } | ||
1001 | h->h_next = x->x_hang; | ||
1002 | x->x_hang = h; | ||
1003 | h->h_owner = x; | ||
1004 | h->h_clock = clock_new(h, (t_method)hang_tick); | ||
1005 | clock_delay(h->h_clock, (x->x_deltime >= 0 ? x->x_deltime : 0)); | ||
1006 | } | ||
1007 | |||
1008 | static void pipe_flush(t_pipe *x) | ||
1009 | { | ||
1010 | while (x->x_hang) hang_tick(x->x_hang); | ||
1011 | } | ||
1012 | |||
1013 | static void pipe_clear(t_pipe *x) | ||
1014 | { | ||
1015 | t_hang *hang; | ||
1016 | while (hang = x->x_hang) | ||
1017 | { | ||
1018 | x->x_hang = hang->h_next; | ||
1019 | hang_free(hang); | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | static void pipe_setup(void) | ||
1024 | { | ||
1025 | pipe_class = class_new(gensym("pipe"), | ||
1026 | (t_newmethod)pipe_new, (t_method)pipe_clear, | ||
1027 | sizeof(t_pipe), 0, A_GIMME, 0); | ||
1028 | class_addlist(pipe_class, pipe_list); | ||
1029 | class_addmethod(pipe_class, (t_method)pipe_flush, gensym("flush"), 0); | ||
1030 | class_addmethod(pipe_class, (t_method)pipe_clear, gensym("clear"), 0); | ||
1031 | } | ||
1032 | |||
1033 | void x_time_setup(void) | ||
1034 | { | ||
1035 | delay_setup(); | ||
1036 | metro_setup(); | ||
1037 | line_setup(); | ||
1038 | timer_setup(); | ||
1039 | pipe_setup(); | ||
1040 | } | ||