diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
commit | 526b5580dabbfed7cfe5439dc3a90ec727f563c2 (patch) | |
tree | 22b1af92348785daad16714ee5e2b633017e0e48 /apps/plugins/pdbox/PDa/src/d_ctl.c | |
parent | 4f2dfcc01b260d946044ef2b6af5fe36cb772c8d (diff) | |
download | rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.gz rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.zip |
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_ctl.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/d_ctl.c | 783 |
1 files changed, 0 insertions, 783 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_ctl.c b/apps/plugins/pdbox/PDa/src/d_ctl.c index d3262af800..809899addf 100644 --- a/apps/plugins/pdbox/PDa/src/d_ctl.c +++ b/apps/plugins/pdbox/PDa/src/d_ctl.c | |||
@@ -782,787 +782,4 @@ void d_ctl_setup(void) | |||
782 | } | 782 | } |
783 | 783 | ||
784 | #endif | 784 | #endif |
785 | /* Copyright (c) 1997-1999 Miller Puckette. | ||
786 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
787 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
788 | |||
789 | /* sig~ and line~ control-to-signal converters; | ||
790 | snapshot~ signal-to-control converter. | ||
791 | */ | ||
792 | |||
793 | #include "m_pd.h" | ||
794 | #include "math.h" | ||
795 | |||
796 | /* -------------------------- sig~ ------------------------------ */ | ||
797 | static t_class *sig_tilde_class; | ||
798 | |||
799 | typedef struct _sig | ||
800 | { | ||
801 | t_object x_obj; | ||
802 | float x_f; | ||
803 | } t_sig; | ||
804 | |||
805 | static t_int *sig_tilde_perform(t_int *w) | ||
806 | { | ||
807 | t_float f = *(t_float *)(w[1]); | ||
808 | t_float *out = (t_float *)(w[2]); | ||
809 | int n = (int)(w[3]); | ||
810 | while (n--) | ||
811 | *out++ = f; | ||
812 | return (w+4); | ||
813 | } | ||
814 | |||
815 | static t_int *sig_tilde_perf8(t_int *w) | ||
816 | { | ||
817 | t_float f = *(t_float *)(w[1]); | ||
818 | t_float *out = (t_float *)(w[2]); | ||
819 | int n = (int)(w[3]); | ||
820 | |||
821 | for (; n; n -= 8, out += 8) | ||
822 | { | ||
823 | out[0] = f; | ||
824 | out[1] = f; | ||
825 | out[2] = f; | ||
826 | out[3] = f; | ||
827 | out[4] = f; | ||
828 | out[5] = f; | ||
829 | out[6] = f; | ||
830 | out[7] = f; | ||
831 | } | ||
832 | return (w+4); | ||
833 | } | ||
834 | |||
835 | void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n) | ||
836 | { | ||
837 | if (n&7) | ||
838 | dsp_add(sig_tilde_perform, 3, in, out, n); | ||
839 | else | ||
840 | dsp_add(sig_tilde_perf8, 3, in, out, n); | ||
841 | } | ||
842 | |||
843 | static void sig_tilde_float(t_sig *x, t_float f) | ||
844 | { | ||
845 | x->x_f = f; | ||
846 | } | ||
847 | |||
848 | static void sig_tilde_dsp(t_sig *x, t_signal **sp) | ||
849 | { | ||
850 | dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n); | ||
851 | } | ||
852 | |||
853 | static void *sig_tilde_new(t_floatarg f) | ||
854 | { | ||
855 | t_sig *x = (t_sig *)pd_new(sig_tilde_class); | ||
856 | x->x_f = f; | ||
857 | outlet_new(&x->x_obj, gensym("signal")); | ||
858 | return (x); | ||
859 | } | ||
860 | |||
861 | static void sig_tilde_setup(void) | ||
862 | { | ||
863 | sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0, | ||
864 | sizeof(t_sig), 0, A_DEFFLOAT, 0); | ||
865 | class_addfloat(sig_tilde_class, (t_method)sig_tilde_float); | ||
866 | class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0); | ||
867 | } | ||
868 | |||
869 | |||
870 | #ifndef FIXEDPOINT | ||
871 | |||
872 | /* -------------------------- line~ ------------------------------ */ | ||
873 | static t_class *line_tilde_class; | ||
874 | |||
875 | typedef struct _line | ||
876 | { | ||
877 | t_object x_obj; | ||
878 | float x_target; | ||
879 | float x_value; | ||
880 | float x_biginc; | ||
881 | float x_inc; | ||
882 | float x_1overn; | ||
883 | float x_dspticktomsec; | ||
884 | float x_inletvalue; | ||
885 | float x_inletwas; | ||
886 | int x_ticksleft; | ||
887 | int x_retarget; | ||
888 | } t_line; | ||
889 | |||
890 | static t_int *line_tilde_perform(t_int *w) | ||
891 | { | ||
892 | t_line *x = (t_line *)(w[1]); | ||
893 | t_float *out = (t_float *)(w[2]); | ||
894 | int n = (int)(w[3]); | ||
895 | float f = x->x_value; | ||
896 | |||
897 | if (PD_BIGORSMALL(f)) | ||
898 | x->x_value = f = 0; | ||
899 | if (x->x_retarget) | ||
900 | { | ||
901 | int nticks = x->x_inletwas * x->x_dspticktomsec; | ||
902 | if (!nticks) nticks = 1; | ||
903 | x->x_ticksleft = nticks; | ||
904 | x->x_biginc = (x->x_target - x->x_value)/(float)nticks; | ||
905 | x->x_inc = x->x_1overn * x->x_biginc; | ||
906 | x->x_retarget = 0; | ||
907 | } | ||
908 | if (x->x_ticksleft) | ||
909 | { | ||
910 | float f = x->x_value; | ||
911 | while (n--) *out++ = f, f += x->x_inc; | ||
912 | x->x_value += x->x_biginc; | ||
913 | x->x_ticksleft--; | ||
914 | } | ||
915 | else | ||
916 | { | ||
917 | x->x_value = x->x_target; | ||
918 | while (n--) *out++ = x->x_value; | ||
919 | } | ||
920 | return (w+4); | ||
921 | } | ||
922 | |||
923 | static void line_tilde_float(t_line *x, t_float f) | ||
924 | { | ||
925 | if (x->x_inletvalue <= 0) | ||
926 | { | ||
927 | x->x_target = x->x_value = f; | ||
928 | x->x_ticksleft = x->x_retarget = 0; | ||
929 | } | ||
930 | else | ||
931 | { | ||
932 | x->x_target = f; | ||
933 | x->x_retarget = 1; | ||
934 | x->x_inletwas = x->x_inletvalue; | ||
935 | x->x_inletvalue = 0; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | static void line_tilde_stop(t_line *x) | ||
940 | { | ||
941 | x->x_target = x->x_value; | ||
942 | x->x_ticksleft = x->x_retarget = 0; | ||
943 | } | ||
944 | |||
945 | static void line_tilde_dsp(t_line *x, t_signal **sp) | ||
946 | { | ||
947 | dsp_add(line_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
948 | x->x_1overn = 1./sp[0]->s_n; | ||
949 | x->x_dspticktomsec = sp[0]->s_sr / (1000 * sp[0]->s_n); | ||
950 | } | ||
951 | |||
952 | static void *line_tilde_new(void) | ||
953 | { | ||
954 | t_line *x = (t_line *)pd_new(line_tilde_class); | ||
955 | outlet_new(&x->x_obj, gensym("signal")); | ||
956 | floatinlet_new(&x->x_obj, &x->x_inletvalue); | ||
957 | x->x_ticksleft = x->x_retarget = 0; | ||
958 | x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0; | ||
959 | return (x); | ||
960 | } | ||
961 | |||
962 | static void line_tilde_setup(void) | ||
963 | { | ||
964 | line_tilde_class = class_new(gensym("line~"), line_tilde_new, 0, | ||
965 | sizeof(t_line), 0, 0); | ||
966 | class_addfloat(line_tilde_class, (t_method)line_tilde_float); | ||
967 | class_addmethod(line_tilde_class, (t_method)line_tilde_dsp, | ||
968 | gensym("dsp"), 0); | ||
969 | class_addmethod(line_tilde_class, (t_method)line_tilde_stop, | ||
970 | gensym("stop"), 0); | ||
971 | } | ||
972 | |||
973 | /* -------------------------- vline~ ------------------------------ */ | ||
974 | static t_class *vline_tilde_class; | ||
975 | |||
976 | typedef struct _vseg | ||
977 | { | ||
978 | double s_targettime; | ||
979 | double s_starttime; | ||
980 | float s_target; | ||
981 | struct _vseg *s_next; | ||
982 | } t_vseg; | ||
983 | |||
984 | typedef struct _vline | ||
985 | { | ||
986 | t_object x_obj; | ||
987 | double x_value; | ||
988 | double x_inc; | ||
989 | double x_referencetime; | ||
990 | double x_samppermsec; | ||
991 | double x_msecpersamp; | ||
992 | double x_targettime; | ||
993 | float x_target; | ||
994 | float x_inlet1; | ||
995 | float x_inlet2; | ||
996 | t_vseg *x_list; | ||
997 | } t_vline; | ||
998 | |||
999 | static t_int *vline_tilde_perform(t_int *w) | ||
1000 | { | ||
1001 | t_vline *x = (t_vline *)(w[1]); | ||
1002 | t_float *out = (t_float *)(w[2]); | ||
1003 | int n = (int)(w[3]), i; | ||
1004 | double f = x->x_value; | ||
1005 | double inc = x->x_inc; | ||
1006 | double msecpersamp = x->x_msecpersamp; | ||
1007 | double samppermsec = x->x_samppermsec; | ||
1008 | double timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp; | ||
1009 | t_vseg *s = x->x_list; | ||
1010 | for (i = 0; i < n; i++) | ||
1011 | { | ||
1012 | double timenext = timenow + msecpersamp; | ||
1013 | checknext: | ||
1014 | if (s) | ||
1015 | { | ||
1016 | /* has starttime elapsed? If so update value and increment */ | ||
1017 | if (s->s_starttime < timenext) | ||
1018 | { | ||
1019 | if (x->x_targettime <= timenext) | ||
1020 | f = x->x_target, inc = 0; | ||
1021 | /* if zero-length segment bash output value */ | ||
1022 | if (s->s_targettime <= s->s_starttime) | ||
1023 | { | ||
1024 | f = s->s_target; | ||
1025 | inc = 0; | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | double incpermsec = (s->s_target - f)/ | ||
1030 | (s->s_targettime - s->s_starttime); | ||
1031 | f = f + incpermsec * (timenext - s->s_starttime); | ||
1032 | inc = incpermsec * msecpersamp; | ||
1033 | } | ||
1034 | x->x_inc = inc; | ||
1035 | x->x_target = s->s_target; | ||
1036 | x->x_targettime = s->s_targettime; | ||
1037 | x->x_list = s->s_next; | ||
1038 | t_freebytes(s, sizeof(*s)); | ||
1039 | s = x->x_list; | ||
1040 | goto checknext; | ||
1041 | } | ||
1042 | } | ||
1043 | if (x->x_targettime <= timenext) | ||
1044 | f = x->x_target, inc = x->x_inc = 0, x->x_targettime = 1e20; | ||
1045 | *out++ = f; | ||
1046 | f = f + inc; | ||
1047 | timenow = timenext; | ||
1048 | } | ||
1049 | x->x_value = f; | ||
1050 | return (w+4); | ||
1051 | } | ||
1052 | |||
1053 | static void vline_tilde_stop(t_vline *x) | ||
1054 | { | ||
1055 | t_vseg *s1, *s2; | ||
1056 | for (s1 = x->x_list; s1; s1 = s2) | ||
1057 | s2 = s1->s_next, t_freebytes(s1, sizeof(*s1)); | ||
1058 | x->x_list = 0; | ||
1059 | x->x_inc = 0; | ||
1060 | x->x_inlet1 = x->x_inlet2 = 0; | ||
1061 | x->x_target = x->x_value; | ||
1062 | x->x_targettime = 1e20; | ||
1063 | } | ||
1064 | |||
1065 | static void vline_tilde_float(t_vline *x, t_float f) | ||
1066 | { | ||
1067 | double timenow = clock_gettimesince(x->x_referencetime); | ||
1068 | float inlet1 = (x->x_inlet1 < 0 ? 0 : x->x_inlet1); | ||
1069 | float inlet2 = x->x_inlet2; | ||
1070 | double starttime = timenow + inlet2; | ||
1071 | t_vseg *s1, *s2, *deletefrom = 0, *snew; | ||
1072 | if (PD_BIGORSMALL(f)) | ||
1073 | f = 0; | ||
1074 | |||
1075 | /* negative delay input means stop and jump immediately to new value */ | ||
1076 | if (inlet2 < 0) | ||
1077 | { | ||
1078 | x->x_value = f; | ||
1079 | vline_tilde_stop(x); | ||
1080 | return; | ||
1081 | } | ||
1082 | snew = (t_vseg *)t_getbytes(sizeof(*snew)); | ||
1083 | /* check if we supplant the first item in the list. We supplant | ||
1084 | an item by having an earlier starttime, or an equal starttime unless | ||
1085 | the equal one was instantaneous and the new one isn't (in which case | ||
1086 | we'll do a jump-and-slide starting at that time.) */ | ||
1087 | if (!x->x_list || x->x_list->s_starttime > starttime || | ||
1088 | (x->x_list->s_starttime == starttime && | ||
1089 | (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0))) | ||
1090 | { | ||
1091 | deletefrom = x->x_list; | ||
1092 | x->x_list = snew; | ||
1093 | } | ||
1094 | else | ||
1095 | { | ||
1096 | for (s1 = x->x_list; s2 = s1->s_next; s1 = s2) | ||
1097 | { | ||
1098 | if (s2->s_starttime > starttime || | ||
1099 | (s2->s_starttime == starttime && | ||
1100 | (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) | ||
1101 | { | ||
1102 | deletefrom = s2; | ||
1103 | s1->s_next = snew; | ||
1104 | goto didit; | ||
1105 | } | ||
1106 | } | ||
1107 | s1->s_next = snew; | ||
1108 | deletefrom = 0; | ||
1109 | didit: ; | ||
1110 | } | ||
1111 | while (deletefrom) | ||
1112 | { | ||
1113 | s1 = deletefrom->s_next; | ||
1114 | t_freebytes(deletefrom, sizeof(*deletefrom)); | ||
1115 | deletefrom = s1; | ||
1116 | } | ||
1117 | snew->s_next = 0; | ||
1118 | snew->s_target = f; | ||
1119 | snew->s_starttime = starttime; | ||
1120 | snew->s_targettime = starttime + inlet1; | ||
1121 | x->x_inlet1 = x->x_inlet2 = 0; | ||
1122 | } | ||
1123 | |||
1124 | static void vline_tilde_dsp(t_vline *x, t_signal **sp) | ||
1125 | { | ||
1126 | dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
1127 | x->x_samppermsec = ((double)(sp[0]->s_sr)) / 1000; | ||
1128 | x->x_msecpersamp = ((double)1000) / sp[0]->s_sr; | ||
1129 | } | ||
1130 | 785 | ||
1131 | static void *vline_tilde_new(void) | ||
1132 | { | ||
1133 | t_vline *x = (t_vline *)pd_new(vline_tilde_class); | ||
1134 | outlet_new(&x->x_obj, gensym("signal")); | ||
1135 | floatinlet_new(&x->x_obj, &x->x_inlet1); | ||
1136 | floatinlet_new(&x->x_obj, &x->x_inlet2); | ||
1137 | x->x_inlet1 = x->x_inlet2 = 0; | ||
1138 | x->x_value = x->x_inc = 0; | ||
1139 | x->x_referencetime = clock_getlogicaltime(); | ||
1140 | x->x_list = 0; | ||
1141 | x->x_samppermsec = 0; | ||
1142 | x->x_targettime = 1e20; | ||
1143 | return (x); | ||
1144 | } | ||
1145 | |||
1146 | static void vline_tilde_setup(void) | ||
1147 | { | ||
1148 | vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new, | ||
1149 | (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0); | ||
1150 | class_addfloat(vline_tilde_class, (t_method)vline_tilde_float); | ||
1151 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp, | ||
1152 | gensym("dsp"), 0); | ||
1153 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop, | ||
1154 | gensym("stop"), 0); | ||
1155 | } | ||
1156 | |||
1157 | /* -------------------------- snapshot~ ------------------------------ */ | ||
1158 | static t_class *snapshot_tilde_class; | ||
1159 | |||
1160 | typedef struct _snapshot | ||
1161 | { | ||
1162 | t_object x_obj; | ||
1163 | t_sample x_value; | ||
1164 | float x_f; | ||
1165 | } t_snapshot; | ||
1166 | |||
1167 | static void *snapshot_tilde_new(void) | ||
1168 | { | ||
1169 | t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class); | ||
1170 | x->x_value = 0; | ||
1171 | outlet_new(&x->x_obj, &s_float); | ||
1172 | x->x_f = 0; | ||
1173 | return (x); | ||
1174 | } | ||
1175 | |||
1176 | static t_int *snapshot_tilde_perform(t_int *w) | ||
1177 | { | ||
1178 | t_float *in = (t_float *)(w[1]); | ||
1179 | t_float *out = (t_float *)(w[2]); | ||
1180 | *out = *in; | ||
1181 | return (w+3); | ||
1182 | } | ||
1183 | |||
1184 | static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp) | ||
1185 | { | ||
1186 | dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1), | ||
1187 | &x->x_value); | ||
1188 | } | ||
1189 | |||
1190 | static void snapshot_tilde_bang(t_snapshot *x) | ||
1191 | { | ||
1192 | outlet_float(x->x_obj.ob_outlet, x->x_value); | ||
1193 | } | ||
1194 | |||
1195 | static void snapshot_tilde_set(t_snapshot *x, t_floatarg f) | ||
1196 | { | ||
1197 | x->x_value = f; | ||
1198 | } | ||
1199 | |||
1200 | static void snapshot_tilde_setup(void) | ||
1201 | { | ||
1202 | snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0, | ||
1203 | sizeof(t_snapshot), 0, 0); | ||
1204 | CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f); | ||
1205 | class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp, | ||
1206 | gensym("dsp"), 0); | ||
1207 | class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set, | ||
1208 | gensym("set"), A_DEFFLOAT, 0); | ||
1209 | class_addbang(snapshot_tilde_class, snapshot_tilde_bang); | ||
1210 | } | ||
1211 | |||
1212 | /* -------------------------- vsnapshot~ ------------------------------ */ | ||
1213 | static t_class *vsnapshot_tilde_class; | ||
1214 | |||
1215 | typedef struct _vsnapshot | ||
1216 | { | ||
1217 | t_object x_obj; | ||
1218 | int x_n; | ||
1219 | int x_gotone; | ||
1220 | t_sample *x_vec; | ||
1221 | float x_f; | ||
1222 | float x_sampspermsec; | ||
1223 | double x_time; | ||
1224 | } t_vsnapshot; | ||
1225 | |||
1226 | static void *vsnapshot_tilde_new(void) | ||
1227 | { | ||
1228 | t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class); | ||
1229 | outlet_new(&x->x_obj, &s_float); | ||
1230 | x->x_f = 0; | ||
1231 | x->x_n = 0; | ||
1232 | x->x_vec = 0; | ||
1233 | x->x_gotone = 0; | ||
1234 | return (x); | ||
1235 | } | ||
1236 | |||
1237 | static t_int *vsnapshot_tilde_perform(t_int *w) | ||
1238 | { | ||
1239 | t_float *in = (t_float *)(w[1]); | ||
1240 | t_vsnapshot *x = (t_vsnapshot *)(w[2]); | ||
1241 | t_float *out = x->x_vec; | ||
1242 | int n = x->x_n, i; | ||
1243 | for (i = 0; i < n; i++) | ||
1244 | out[i] = in[i]; | ||
1245 | x->x_time = clock_getlogicaltime(); | ||
1246 | x->x_gotone = 1; | ||
1247 | return (w+3); | ||
1248 | } | ||
1249 | |||
1250 | static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp) | ||
1251 | { | ||
1252 | int n = sp[0]->s_n; | ||
1253 | if (n != x->x_n) | ||
1254 | { | ||
1255 | if (x->x_vec) | ||
1256 | t_freebytes(x->x_vec, x->x_n * sizeof(t_sample)); | ||
1257 | x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample)); | ||
1258 | x->x_gotone = 0; | ||
1259 | x->x_n = n; | ||
1260 | } | ||
1261 | x->x_sampspermsec = sp[0]->s_sr / 1000; | ||
1262 | dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x); | ||
1263 | } | ||
1264 | |||
1265 | static void vsnapshot_tilde_bang(t_vsnapshot *x) | ||
1266 | { | ||
1267 | float val; | ||
1268 | if (x->x_gotone) | ||
1269 | { | ||
1270 | int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec; | ||
1271 | if (indx < 0) | ||
1272 | indx = 0; | ||
1273 | else if (indx >= x->x_n) | ||
1274 | indx = x->x_n - 1; | ||
1275 | val = x->x_vec[indx]; | ||
1276 | } | ||
1277 | else val = 0; | ||
1278 | outlet_float(x->x_obj.ob_outlet, val); | ||
1279 | } | ||
1280 | |||
1281 | static void vsnapshot_tilde_ff(t_vsnapshot *x) | ||
1282 | { | ||
1283 | if (x->x_vec) | ||
1284 | t_freebytes(x->x_vec, x->x_n * sizeof(t_sample)); | ||
1285 | } | ||
1286 | |||
1287 | static void vsnapshot_tilde_setup(void) | ||
1288 | { | ||
1289 | vsnapshot_tilde_class = class_new(gensym("vsnapshot~"), | ||
1290 | vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff, | ||
1291 | sizeof(t_vsnapshot), 0, 0); | ||
1292 | CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f); | ||
1293 | class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0); | ||
1294 | class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang); | ||
1295 | } | ||
1296 | |||
1297 | |||
1298 | /* ---------------- env~ - simple envelope follower. ----------------- */ | ||
1299 | |||
1300 | #define MAXOVERLAP 10 | ||
1301 | #define MAXVSTAKEN 64 | ||
1302 | |||
1303 | typedef struct sigenv | ||
1304 | { | ||
1305 | t_object x_obj; /* header */ | ||
1306 | void *x_outlet; /* a "float" outlet */ | ||
1307 | void *x_clock; /* a "clock" object */ | ||
1308 | float *x_buf; /* a Hanning window */ | ||
1309 | int x_phase; /* number of points since last output */ | ||
1310 | int x_period; /* requested period of output */ | ||
1311 | int x_realperiod; /* period rounded up to vecsize multiple */ | ||
1312 | int x_npoints; /* analysis window size in samples */ | ||
1313 | float x_result; /* result to output */ | ||
1314 | float x_sumbuf[MAXOVERLAP]; /* summing buffer */ | ||
1315 | float x_f; | ||
1316 | } t_sigenv; | ||
1317 | |||
1318 | t_class *env_tilde_class; | ||
1319 | static void env_tilde_tick(t_sigenv *x); | ||
1320 | |||
1321 | static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod) | ||
1322 | { | ||
1323 | int npoints = fnpoints; | ||
1324 | int period = fperiod; | ||
1325 | t_sigenv *x; | ||
1326 | float *buf; | ||
1327 | int i; | ||
1328 | |||
1329 | if (npoints < 1) npoints = 1024; | ||
1330 | if (period < 1) period = npoints/2; | ||
1331 | if (period < npoints / MAXOVERLAP + 1) | ||
1332 | period = npoints / MAXOVERLAP + 1; | ||
1333 | if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN)))) | ||
1334 | { | ||
1335 | error("env: couldn't allocate buffer"); | ||
1336 | return (0); | ||
1337 | } | ||
1338 | x = (t_sigenv *)pd_new(env_tilde_class); | ||
1339 | x->x_buf = buf; | ||
1340 | x->x_npoints = npoints; | ||
1341 | x->x_phase = 0; | ||
1342 | x->x_period = period; | ||
1343 | for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0; | ||
1344 | for (i = 0; i < npoints; i++) | ||
1345 | buf[i] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints; | ||
1346 | for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0; | ||
1347 | x->x_clock = clock_new(x, (t_method)env_tilde_tick); | ||
1348 | x->x_outlet = outlet_new(&x->x_obj, gensym("float")); | ||
1349 | x->x_f = 0; | ||
1350 | return (x); | ||
1351 | } | ||
1352 | |||
1353 | static t_int *env_tilde_perform(t_int *w) | ||
1354 | { | ||
1355 | t_sigenv *x = (t_sigenv *)(w[1]); | ||
1356 | t_float *in = (t_float *)(w[2]); | ||
1357 | int n = (int)(w[3]); | ||
1358 | int count; | ||
1359 | float *sump; | ||
1360 | in += n; | ||
1361 | for (count = x->x_phase, sump = x->x_sumbuf; | ||
1362 | count < x->x_npoints; count += x->x_realperiod, sump++) | ||
1363 | { | ||
1364 | float *hp = x->x_buf + count; | ||
1365 | float *fp = in; | ||
1366 | float sum = *sump; | ||
1367 | int i; | ||
1368 | |||
1369 | for (i = 0; i < n; i++) | ||
1370 | { | ||
1371 | fp--; | ||
1372 | sum += *hp++ * (*fp * *fp); | ||
1373 | } | ||
1374 | *sump = sum; | ||
1375 | } | ||
1376 | sump[0] = 0; | ||
1377 | x->x_phase -= n; | ||
1378 | if (x->x_phase < 0) | ||
1379 | { | ||
1380 | x->x_result = x->x_sumbuf[0]; | ||
1381 | for (count = x->x_realperiod, sump = x->x_sumbuf; | ||
1382 | count < x->x_npoints; count += x->x_realperiod, sump++) | ||
1383 | sump[0] = sump[1]; | ||
1384 | sump[0] = 0; | ||
1385 | x->x_phase = x->x_realperiod - n; | ||
1386 | clock_delay(x->x_clock, 0L); | ||
1387 | } | ||
1388 | return (w+4); | ||
1389 | } | ||
1390 | |||
1391 | static void env_tilde_dsp(t_sigenv *x, t_signal **sp) | ||
1392 | { | ||
1393 | if (x->x_period % sp[0]->s_n) x->x_realperiod = | ||
1394 | x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n); | ||
1395 | else x->x_realperiod = x->x_period; | ||
1396 | dsp_add(env_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
1397 | if (sp[0]->s_n > MAXVSTAKEN) bug("env_tilde_dsp"); | ||
1398 | } | ||
1399 | |||
1400 | static void env_tilde_tick(t_sigenv *x) /* callback function for the clock */ | ||
1401 | { | ||
1402 | outlet_float(x->x_outlet, powtodb(x->x_result)); | ||
1403 | } | ||
1404 | |||
1405 | static void env_tilde_ff(t_sigenv *x) /* cleanup on free */ | ||
1406 | { | ||
1407 | clock_free(x->x_clock); | ||
1408 | freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float)); | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | void env_tilde_setup(void ) | ||
1413 | { | ||
1414 | env_tilde_class = class_new(gensym("env~"), (t_newmethod)env_tilde_new, | ||
1415 | (t_method)env_tilde_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
1416 | CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, x_f); | ||
1417 | class_addmethod(env_tilde_class, (t_method)env_tilde_dsp, gensym("dsp"), 0); | ||
1418 | } | ||
1419 | |||
1420 | /* --------------------- threshold~ ----------------------------- */ | ||
1421 | |||
1422 | static t_class *threshold_tilde_class; | ||
1423 | |||
1424 | typedef struct _threshold_tilde | ||
1425 | { | ||
1426 | t_object x_obj; | ||
1427 | t_outlet *x_outlet1; /* bang out for high thresh */ | ||
1428 | t_outlet *x_outlet2; /* bang out for low thresh */ | ||
1429 | t_clock *x_clock; /* wakeup for message output */ | ||
1430 | float x_f; /* scalar inlet */ | ||
1431 | int x_state; /* 1 = high, 0 = low */ | ||
1432 | float x_hithresh; /* value of high threshold */ | ||
1433 | float x_lothresh; /* value of low threshold */ | ||
1434 | float x_deadwait; /* msec remaining in dead period */ | ||
1435 | float x_msecpertick; /* msec per DSP tick */ | ||
1436 | float x_hideadtime; /* hi dead time in msec */ | ||
1437 | float x_lodeadtime; /* lo dead time in msec */ | ||
1438 | } t_threshold_tilde; | ||
1439 | |||
1440 | static void threshold_tilde_tick(t_threshold_tilde *x); | ||
1441 | static void threshold_tilde_set(t_threshold_tilde *x, | ||
1442 | t_floatarg hithresh, t_floatarg hideadtime, | ||
1443 | t_floatarg lothresh, t_floatarg lodeadtime); | ||
1444 | |||
1445 | static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh, | ||
1446 | t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime) | ||
1447 | { | ||
1448 | t_threshold_tilde *x = (t_threshold_tilde *) | ||
1449 | pd_new(threshold_tilde_class); | ||
1450 | x->x_state = 0; /* low state */ | ||
1451 | x->x_deadwait = 0; /* no dead time */ | ||
1452 | x->x_clock = clock_new(x, (t_method)threshold_tilde_tick); | ||
1453 | x->x_outlet1 = outlet_new(&x->x_obj, &s_bang); | ||
1454 | x->x_outlet2 = outlet_new(&x->x_obj, &s_bang); | ||
1455 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); | ||
1456 | x->x_msecpertick = 0.; | ||
1457 | x->x_f = 0; | ||
1458 | threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime); | ||
1459 | return (x); | ||
1460 | } | ||
1461 | |||
1462 | /* "set" message to specify thresholds and dead times */ | ||
1463 | static void threshold_tilde_set(t_threshold_tilde *x, | ||
1464 | t_floatarg hithresh, t_floatarg hideadtime, | ||
1465 | t_floatarg lothresh, t_floatarg lodeadtime) | ||
1466 | { | ||
1467 | if (lothresh > hithresh) | ||
1468 | lothresh = hithresh; | ||
1469 | x->x_hithresh = hithresh; | ||
1470 | x->x_hideadtime = hideadtime; | ||
1471 | x->x_lothresh = lothresh; | ||
1472 | x->x_lodeadtime = lodeadtime; | ||
1473 | } | ||
1474 | |||
1475 | /* number in inlet sets state -- note incompatible with JMAX which used | ||
1476 | "int" message for this, impossible here because of auto signal conversion */ | ||
1477 | static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f) | ||
1478 | { | ||
1479 | x->x_state = (f != 0); | ||
1480 | x->x_deadwait = 0; | ||
1481 | } | ||
1482 | |||
1483 | static void threshold_tilde_tick(t_threshold_tilde *x) | ||
1484 | { | ||
1485 | if (x->x_state) | ||
1486 | outlet_bang(x->x_outlet1); | ||
1487 | else outlet_bang(x->x_outlet2); | ||
1488 | } | ||
1489 | |||
1490 | static t_int *threshold_tilde_perform(t_int *w) | ||
1491 | { | ||
1492 | float *in1 = (float *)(w[1]); | ||
1493 | t_threshold_tilde *x = (t_threshold_tilde *)(w[2]); | ||
1494 | int n = (t_int)(w[3]); | ||
1495 | if (x->x_deadwait > 0) | ||
1496 | x->x_deadwait -= x->x_msecpertick; | ||
1497 | else if (x->x_state) | ||
1498 | { | ||
1499 | /* we're high; look for low sample */ | ||
1500 | for (; n--; in1++) | ||
1501 | { | ||
1502 | if (*in1 < x->x_lothresh) | ||
1503 | { | ||
1504 | clock_delay(x->x_clock, 0L); | ||
1505 | x->x_state = 0; | ||
1506 | x->x_deadwait = x->x_lodeadtime; | ||
1507 | goto done; | ||
1508 | } | ||
1509 | } | ||
1510 | } | ||
1511 | else | ||
1512 | { | ||
1513 | /* we're low; look for high sample */ | ||
1514 | for (; n--; in1++) | ||
1515 | { | ||
1516 | if (*in1 >= x->x_hithresh) | ||
1517 | { | ||
1518 | clock_delay(x->x_clock, 0L); | ||
1519 | x->x_state = 1; | ||
1520 | x->x_deadwait = x->x_hideadtime; | ||
1521 | goto done; | ||
1522 | } | ||
1523 | } | ||
1524 | } | ||
1525 | done: | ||
1526 | return (w+4); | ||
1527 | } | ||
1528 | |||
1529 | void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp) | ||
1530 | { | ||
1531 | x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr; | ||
1532 | dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); | ||
1533 | } | ||
1534 | |||
1535 | static void threshold_tilde_ff(t_threshold_tilde *x) | ||
1536 | { | ||
1537 | clock_free(x->x_clock); | ||
1538 | } | ||
1539 | |||
1540 | static void threshold_tilde_setup( void) | ||
1541 | { | ||
1542 | threshold_tilde_class = class_new(gensym("threshold~"), | ||
1543 | (t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff, | ||
1544 | sizeof(t_threshold_tilde), 0, | ||
1545 | A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
1546 | CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f); | ||
1547 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set, | ||
1548 | gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); | ||
1549 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1, | ||
1550 | gensym("ft1"), A_FLOAT, 0); | ||
1551 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp, | ||
1552 | gensym("dsp"), 0); | ||
1553 | } | ||
1554 | |||
1555 | /* ------------------------ global setup routine ------------------------- */ | ||
1556 | |||
1557 | void d_ctl_setup(void) | ||
1558 | { | ||
1559 | sig_tilde_setup(); | ||
1560 | line_tilde_setup(); | ||
1561 | vline_tilde_setup(); | ||
1562 | snapshot_tilde_setup(); | ||
1563 | vsnapshot_tilde_setup(); | ||
1564 | env_tilde_setup(); | ||
1565 | threshold_tilde_setup(); | ||
1566 | } | ||
1567 | |||
1568 | #endif | ||