void max_jit_openni_assist(t_max_jit_openni *x, void *b, long io, long index, char *s) { t_jit_openni *pJit_OpenNI = (t_jit_openni *)max_jit_obex_jitob_get(x); // I acknowledge the code below is redundant switch (io) { case 1: strncpy_zero(s, "(text) read filename.xml only", 512); break; case 2: switch (index) { case DEPTHMAP_OUTPUT_INDEX: snprintf_zero(s, 512, "%s out%d", DEPTHMAP_ASSIST_TEXT, index+1); break; case IMAGEMAP_OUTPUT_INDEX: snprintf_zero(s, 512, "%s out%d", IMAGEMAP_ASSIST_TEXT, index+1); break; case IRMAP_OUTPUT_INDEX: snprintf_zero(s, 512, "%s out%d", IRMAP_ASSIST_TEXT, index+1); break; case USERPIXELMAP_OUTPUT_INDEX: snprintf_zero(s, 512, "%s out%d", USERPIXELMAP_ASSIST_TEXT, index+1); break; case SKELETON_OUTPUT_INDEX: snprintf_zero(s, 512, "%s out%d", SKELETON_ASSIST_TEXT, index+1); break; case NUM_JITOPENNI_OUTPUTS: strncpy_zero(s, "dumpout", 512); } } }
void tralala_paintStrncatNote(char *dst, long argc, t_atom *argv) { char a[5]; char temp[32]; long p = atom_getlong(argv + 1); long v = atom_getlong(argv + 3); long d = atom_getlong(argv + 4); long c = atom_getlong(argv + 5); tralala_paintPitchAsString(a, atom_getlong(argv + 2), 5); snprintf_zero(temp, 32, "%ld %s %ld %ld %ld\n", p, a, v, d, c); strncat_zero(dst, temp, TLL_STRING_SIZE); }
void _dict_recurse_array(t_dict_recurse *x, t_atomarray *atomarray, t_int32 depth) { TRACE("_dict_recurse_array"); t_atom *value; // ==== Store the state variables on the beginning of the function t_int32 path_len = (t_int32)strlen(x->path); t_value_type type_iter_ini = x->type_iter; t_atomarray *array_iter_ini = x->array_iter; t_int32 index_iter_ini = x->index_iter; // ==== Add [ to the path strncat_zero(x->path, "[", x->path_len_max); // ==== Set the trailing variables before the recursions x->type_iter = VALUE_TYPE_ARRAY; x->array_iter = atomarray; // ==== Get the array of atoms associated with the atomarray long array_len; t_atom *atom_arr; atomarray_getatoms(atomarray, &array_len, &atom_arr); t_int32 test; // ==== Loop through the array for (t_int32 ind = 0; ind < array_len; ind++) { value = atom_arr + ind; x->index_iter = ind; // == Update the path snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "%i]", ind); strncat_zero(x->path, x->str_tmp, x->path_len_max); // == Recurse to the value test = _dict_recurse_value(x, value, depth); // == If there was a deletion reset the array and shift the index if (test == VALUE_DEL) { atomarray_getatoms(atomarray, &array_len, &atom_arr); ind--; } // == In loop resetting of the values that changed in this function x->path[path_len + 1] = '\0'; } // End of the loop through the array // ==== Restore the remaining state variables to their beginning values x->type_iter = type_iter_ini; x->array_iter = array_iter_ini; x->index_iter = index_iter_ini; }
void tralala_paintStrncatZone(char *dst, long argc, t_atom *argv, long status) { char a[5]; char b[5]; char temp[32]; tralala_paintPitchAsString(a, atom_getlong(argv + 3), 5); tralala_paintPitchAsString(b, atom_getlong(argv + 4), 5); if (status >= TLL_SELECTED_START) { // switch (status) { case TLL_SELECTED_START : snprintf_zero(temp, 32, "Start : %ld\n", atom_getlong(argv + 1)); break; case TLL_SELECTED_END : snprintf_zero(temp, 32, "End : %ld\n", atom_getlong(argv + 2)); break; case TLL_SELECTED_DOWN : snprintf_zero(temp, 32, "Down : %s\n", a); break; case TLL_SELECTED_UP : snprintf_zero(temp, 32, "Up : %s\n", b); break; } // } else { snprintf_zero(temp, 32, "%ld %ld %s %s\n", atom_getlong(argv + 1), atom_getlong(argv + 2), a, b); } strncat_zero(dst, temp, TLL_STRING_SIZE); }
// assist method (for help strings) void FMAssist(fmsynth *x, void *b, long m, long a, char *s) { if (m == ASSIST_INLET){ switch (a) { case 0: snprintf_zero(s, 256, "(signal/float Min frequency)"); break; case 1: snprintf_zero(s, 256, "(float Max frequency)"); break; case 2: snprintf_zero(s, 256, "(float Min Modulator Frequency)"); break; case 3: snprintf_zero(s, 256, "(float Max Modulator Frequency)"); break; case 4: snprintf_zero(s, 256, "(float Modulator Depth)"); break; case 5: snprintf_zero(s, 256, "(float Min grain duration in ms)"); break; case 6: snprintf_zero(s, 256, "(float Max grain duration in ms)"); break; } } else sprintf(s, "signal/float Grain FM frequency"); }
void polywave_assist(t_polywave *x, void *b, long m, long a, char *s) { if (m == ASSIST_INLET) { // inlets if(x->dims == ONE_D) switch (a) { case 0: snprintf_zero(s, 256, "(signal) Table Position (0 to 1)"); break; case 1: snprintf_zero(s, 256, "(signal) Buffer index in buffer name array"); break; } else if(x->dims == TWO_D) switch (a) { case 0: snprintf_zero(s, 256, "(signal) Table 1 Position (0 to 1)"); break; case 1: snprintf_zero(s, 256, "(signal) Table 2 Position (0 to 1), same as table 1 if not attached"); break; case 2: snprintf_zero(s, 256, "(signal) Interpolation weight (0 to 1)"); break; case 3: snprintf_zero(s, 256, "(signal) Buffer index 1"); break; case 4: snprintf_zero(s, 256, "(signal) Buffer index 2"); break; } } else { // outlet snprintf_zero(s, 256, "(signal) sample output", a+1); } }
void tralala_paintPitchAsString(char *dst, long k, long size) { long m = k % 12; long n = ((long)(k / 12.)) - 2; switch (m) { case 0 : snprintf_zero(dst, size, "%s%ld", "C", n); break; case 1 : snprintf_zero(dst, size, "%s%ld", "C#", n); break; case 2 : snprintf_zero(dst, size, "%s%ld", "D", n); break; case 3 : snprintf_zero(dst, size, "%s%ld", "D#", n); break; case 4 : snprintf_zero(dst, size, "%s%ld", "E", n); break; case 5 : snprintf_zero(dst, size, "%s%ld", "F", n); break; case 6 : snprintf_zero(dst, size, "%s%ld", "F#", n); break; case 7 : snprintf_zero(dst, size, "%s%ld", "G", n); break; case 8 : snprintf_zero(dst, size, "%s%ld", "G#", n); break; case 9 : snprintf_zero(dst, size, "%s%ld", "A", n); break; case 10 : snprintf_zero(dst, size, "%s%ld", "A#", n); break; case 11 : snprintf_zero(dst, size, "%s%ld", "B", n); break; } }
void max_jit_openni_outputmatrix(t_max_jit_openni *x) { long outputmode = max_jit_mop_getoutputmode(x); void *mop = max_jit_obex_adornment_get(x,_jit_sym_jit_mop); t_jit_openni *pJit_OpenNI = (t_jit_openni *)max_jit_obex_jitob_get(x); t_jit_err err; t_atom osc_argv[16]; // max number of atoms/values after the message selector char osc_string[MAX_LENGTH_STR_JOINT_NAME + 10]; // max joint string + 9 for "/skel/xx/" + terminating null char *msg_selector_string; int i, j, k; const char strSkelFormatOutput[3][12] = { "/skel/%u/%s", "skel", "/joint" }; // switchable skeleton output format selectors // the [2] format string below should be an unsigned %u, however OSCeleton codebase incorrectly uses %d so I also use it here for compatibility const char strUserCoMFormatOutput[3][9] = { "/user/%u", "user", "/user/%d" }; // switchable user CoM output format selectors const char strFloorFormatOutput[3][7] = { "/floor", "floor", "/floor" }; // switchable floor output format selectors LOG_DEBUG("starting custom outputmatrix()"); if (outputmode && mop) { //always output unless output mode is none if (outputmode==2) // pass input case, but since jit.openni has no input then this means no output { LOG_DEBUG("bypassing matrix_calc(), bypassing outputmatrix()"); return; } if (outputmode==1) { LOG_DEBUG("about to call matrix_calc from custom outputmatrix"); if (err = (t_jit_err)jit_object_method(max_jit_obex_jitob_get(x), _jit_sym_matrix_calc, jit_object_method(mop,_jit_sym_getinputlist), jit_object_method(mop,_jit_sym_getoutputlist))) { if (err != JIT_ERR_HW_UNAVAILABLE) jit_error_code(x,err); return; } } // output floor from scene generator if (pJit_OpenNI->hProductionNode[SCENE_GEN_INDEX] && pJit_OpenNI->bOutputSceneFloor) { msg_selector_string = (char *)strFloorFormatOutput[x->chrSkeletonOutputFormat]; atom_setfloat(&(osc_argv[0]), pJit_OpenNI->planeFloor.ptPoint.X); atom_setfloat(&(osc_argv[1]), pJit_OpenNI->planeFloor.ptPoint.Y); atom_setfloat(&(osc_argv[2]), pJit_OpenNI->planeFloor.ptPoint.Z); atom_setfloat(&(osc_argv[3]), pJit_OpenNI->planeFloor.vNormal.X); atom_setfloat(&(osc_argv[4]), pJit_OpenNI->planeFloor.vNormal.Y); atom_setfloat(&(osc_argv[5]), pJit_OpenNI->planeFloor.vNormal.Z); outlet_anything(x->osc_outlet, gensym(msg_selector_string), 6, osc_argv); } // output seen users' centers of mass and skeletons for (i=0; i<pJit_OpenNI->iNumUsersSeen; i++) { short iNumAtoms = 0; // output user center of mass switch (x->chrSkeletonOutputFormat) { case 0: // default jit.openni skeleton OSC output format case 2: // legacy OSCeleton format snprintf_zero(osc_string, sizeof(osc_string), strUserCoMFormatOutput[x->chrSkeletonOutputFormat], pJit_OpenNI->pUserSkeletonJoints[i].userID); msg_selector_string = osc_string; break; case 1: // native max route compatible format msg_selector_string = (char *)strUserCoMFormatOutput[1]; atom_setlong(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].userID); break; } atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].userCoM.X); atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].userCoM.Y); atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].userCoM.Z); outlet_anything(x->osc_outlet, gensym(msg_selector_string), iNumAtoms, osc_argv); // output skeletons if (pJit_OpenNI->pUserSkeletonJoints[i].bUserSkeletonTracked) { for (j=1; j<= NUM_OF_SKELETON_JOINT_TYPES; j++) { if (pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].position.fConfidence >= pJit_OpenNI->fPositionConfidenceFilter && ( pJit_OpenNI->bOutputSkeletonOrientation ? (pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].orientation.fConfidence >= pJit_OpenNI->fOrientConfidenceFilter) : true)) { iNumAtoms = 0; switch (x->chrSkeletonOutputFormat) { case 0: // default jit.openni skeleton output format "/skel/%u/%s" snprintf_zero(osc_string, sizeof(osc_string), strSkelFormatOutput[0], pJit_OpenNI->pUserSkeletonJoints[i].userID, strJointNames[j]); msg_selector_string = osc_string; break; case 1: // skeleton output "skel %u %s" to easily use with standard max route object msg_selector_string = (char *)strSkelFormatOutput[1]; atom_setlong(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].userID); atom_setsym(osc_argv + (iNumAtoms++), gensym(strJointNames[j])); break; case 2: // skeleton output "/joint %s %u" same format as OSCeleton's default output with no orientation and no OSCeleton's legacy "normalized" values msg_selector_string = (char *)strSkelFormatOutput[2]; atom_setsym(osc_argv + (iNumAtoms++), gensym(strJointNames[j])); atom_setlong(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].userID); break; } atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].position.position.X); atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].position.position.Y); atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].position.position.Z); if (x->chrSkeletonOutputFormat != 2) { atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].position.fConfidence); } if (pJit_OpenNI->bOutputSkeletonOrientation && (x->chrSkeletonOutputFormat != 2)) { // General belief and https://groups.google.com/forum/#!topic/openni-dev/-ib1yX-o0lk say that OpenNI stores the // orientation matrix in row-major order. // X axis = (elements[0], elements[3], elements[6]) // Y axis = (elements[1], elements[4], elements[7]) // Z axis = (elements[2], elements[5], elements[8]) // Just in case, column major order is easy to substitute with: for (k=0; k<9; k++) atom_setfloat(osc_argv + iAtomOffset + 4 + k, pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].orientation.orientation.elements[k]); for (k=0; k<3; k++) { atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].orientation.orientation.elements[k]); atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].orientation.orientation.elements[k+3]); atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].orientation.orientation.elements[k+6]); } if (x->chrSkeletonOutputFormat != 2) { atom_setfloat(osc_argv + (iNumAtoms++), pJit_OpenNI->pUserSkeletonJoints[i].jointTransform[j].orientation.fConfidence); } } outlet_anything(x->osc_outlet, gensym(msg_selector_string), iNumAtoms, osc_argv); } } } } LOG_DEBUG("now calling outputmatrix()"); max_jit_mop_outputmatrix(x); LOG_DEBUG("called outputmatrix()"); } }
void cmgrainlabs_assist(t_cmgrainlabs *x, void *b, long msg, long arg, char *dst) { if (msg == ASSIST_INLET) { switch (arg) { case 0: snprintf_zero(dst, 256, "(signal) trigger in"); break; case 1: snprintf_zero(dst, 256, "(signal/float) start min"); break; case 2: snprintf_zero(dst, 256, "(signal/float) start max"); break; case 3: snprintf_zero(dst, 256, "(signal/float) min grain length"); break; case 4: snprintf_zero(dst, 256, "(signal/float) max grain length"); break; case 5: snprintf_zero(dst, 256, "(signal/float) pitch min"); break; case 6: snprintf_zero(dst, 256, "(signal/float) pitch max"); break; case 7: snprintf_zero(dst, 256, "(signal/float) pan min"); break; case 8: snprintf_zero(dst, 256, "(signal/float) pan max"); break; case 9: snprintf_zero(dst, 256, "(signal/float) gain min"); break; case 10: snprintf_zero(dst, 256, "(signal/float) gain max"); break; } } else if (msg == ASSIST_OUTLET) { switch (arg) { case 0: snprintf_zero(dst, 256, "(signal) output ch1"); break; case 1: snprintf_zero(dst, 256, "(signal) output ch2"); break; case 2: snprintf_zero(dst, 256, "(int) current grain count"); break; } } }
/** Called by _dict_recurse_dict() for each entry and _dict_recurse_array() for each index */ t_int32 _dict_recurse_value(t_dict_recurse *x, t_atom *value, t_int32 depth) { TRACE("_dict_recurse_value"); long type = atom_gettype(value); // ==== INT ==== if (type == A_LONG) { snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "%i", atom_getlong(value)); _dict_recurse_value_find(x, value, x->str_tmp); } // ==== FLOAT ==== else if (type == A_FLOAT) { snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "%i", atom_getfloat(value)); _dict_recurse_value_find(x, value, x->str_tmp); } // ==== SYMBOL / STRING ==== // NB: values in arrays are not A_SYM but A_OBJ else if ((type == A_SYM) || atomisstring(value)) { t_symbol *value_sym = atom_getsym(value); switch (x->command) { // == FIND A SYMBOL VALUE case CMD_FIND_VALUE_SYM: if (regexpr_match(x->search_val_expr, value_sym)) { POST(" %s \"%s\"", x->path, value_sym->s_name); x->count++; } break; // == FIND AN ENTRY case CMD_FIND_ENTRY: if (regexpr_match(x->search_key_expr, x->key_iter) && regexpr_match(x->search_val_expr, value_sym) && (x->type_iter == VALUE_TYPE_DICT)) { POST(" %s \"%s\"", x->path, value_sym->s_name); x->count++; } break; // == REPLACE A SYMBOL VALUE case CMD_REPLACE_VALUE_SYM: if (regexpr_match(x->search_val_expr, value_sym)) { // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_chuckentry(x->dict_iter, x->key_iter); dictionary_appendsym(x->dict_iter, x->key_iter, x->replace_val_sym); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { atom_setsym(value, x->replace_val_sym); } x->count++; if (x->a_verbose) { POST(" %s \"%s\" replaced by \"%s\"", x->path, value_sym->s_name, x->replace_val_sym->s_name); } } break; // == REPLACE AN ENTRY case CMD_REPLACE_ENTRY: if (regexpr_match(x->search_key_expr, x->key_iter) && regexpr_match(x->search_val_expr, value_sym) && (x->type_iter == VALUE_TYPE_DICT)) { dictionary_chuckentry(x->dict_iter, x->key_iter); dictionary_appendsym(x->dict_iter, x->replace_key_sym, x->replace_val_sym); x->count++; if (x->a_verbose) { POST(" %s \"%s\" replaced by (%s : %s)", x->path, value_sym->s_name, x->replace_key_sym->s_name, x->replace_val_sym->s_name); } } break; // == DELETE A SYMBOL VALUE case CMD_DELETE_VALUE_SYM: if (regexpr_match(x->search_val_expr, value_sym)) { // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_deleteentry(x->dict_iter, x->key_iter); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { atomarray_chuckindex(x->array_iter, x->index_iter); } x->count++; if (x->a_verbose) { POST(" %s \"%s\" deleted", x->path, value_sym->s_name); } return VALUE_DEL; } break; // == DELETE A SYMBOL VALUE case CMD_DELETE_ENTRY: if (regexpr_match(x->search_key_expr, x->key_iter) && regexpr_match(x->search_val_expr, value_sym) && (x->type_iter == VALUE_TYPE_DICT)) { dictionary_deleteentry(x->dict_iter, x->key_iter); x->count++; if (x->a_verbose) { POST(" %s \"%s\" deleted", x->path, value_sym->s_name); } return VALUE_DEL; } break; // == DEFAULT: CMD_FIND_KEY or CMD_FIND_KEY_IN default: snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "\"%s\"", atom_getsym(value)->s_name); _dict_recurse_value_find(x, value, x->str_tmp); break; } } // ==== DICTIONARY ==== else if (atomisdictionary(value)) { t_dictionary *sub_dict = (t_dictionary *)atom_getobj(value); t_symbol *key_match = gensym(""); t_symbol *value_match = gensym(""); switch (x->command) { case CMD_FIND_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { x->count++; POST(" %s: dict containing (%s : %s)", x->path, key_match->s_name, value_match->s_name); } break; case CMD_REPLACE_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { t_dictionary *dict_cpy = dictionary_new(); dictionary_clone_to_existing(x->replace_dict, dict_cpy); // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_deleteentry(x->dict_iter, x->key_iter); dictionary_appenddictionary(x->dict_iter, x->key_iter, (t_object *)dict_cpy); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { long array_len; t_atom *atom_arr; atomarray_getatoms(x->array_iter, &array_len, &atom_arr); atom_setobj(atom_arr + x->index_iter, dict_cpy); } x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): replaced by \"%s\"", x->path, key_match->s_name, value_match->s_name, x->replace_dict_sym->s_name); } return VALUE_NO_DEL; } break; case CMD_DELETE_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_deleteentry(x->dict_iter, x->key_iter); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { atomarray_chuckindex(x->array_iter, x->index_iter); object_free(sub_dict); } x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): deleted", x->path, key_match->s_name, value_match->s_name); } return VALUE_DEL; } break; case CMD_APPEND_IN_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { dictionary_appendsym(sub_dict, x->replace_key_sym, x->replace_val_sym); x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): appended (%s : %s)", x->path, key_match->s_name, value_match->s_name, x->replace_key_sym->s_name, x->replace_val_sym->s_name); } } break; case CMD_APPEND_IN_DICT_CONT_ENTRY_D: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match) && dictionary_hasentry(x->replace_dict, x->replace_key_sym)) { t_symbol *key[2]; key[0] = x->replace_key_sym; key[1] = NULL; dictionary_copyentries(x->replace_dict, sub_dict, key); // NB: Strange it does not require the array size x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): appended entry (%s : ...) from \"%s\"", x->path, key_match->s_name, value_match->s_name, x->replace_key_sym->s_name, x->replace_dict_sym->s_name); } } break; case CMD_APPEND_IN_DICT_FROM_KEY: if (regexpr_match(x->search_key_expr, x->key_iter) && (x->type_iter == VALUE_TYPE_DICT) && dictionary_hasentry(x->replace_dict, x->replace_key_sym)) { t_symbol *key[2]; key[0] = x->replace_key_sym; key[1] = NULL; dictionary_copyentries(x->replace_dict, sub_dict, key); // NB: Strange it does not require the array size x->count++; if (x->a_verbose) { POST(" %s: dict value: appended entry (%s : ...) from \"%s\"", x->path, x->replace_key_sym->s_name, x->replace_dict_sym->s_name); } } break; default: _dict_recurse_value_find(x, value, "_DICT_"); } // End of command "switch ..." _dict_recurse_dict(x, sub_dict, depth); } // End of dictionary "else if ..." // ==== ARRAY ==== else if (atomisatomarray(value)) { _dict_recurse_value_find(x, value, "_ARRAY_"); t_atomarray *atomarray = (t_atomarray *)atom_getobj(value); _dict_recurse_array(x, atomarray, depth); } return VALUE_NO_DEL; }