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);
			}
	}
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
// 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");
}
Exemple #6
0
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);
	}
}
Exemple #7
0
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;
		}
	}
}
Exemple #10
0
/**
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;
}