t_max_err offset_set(t_meter *x, t_object *attr, long argc, t_atom *argv)
{
    if(argc && argv && atom_isNumber(argv))
    {
        const double offset = atom_getfloat(argv) / 360. * HOA_2PI;
        x->f_vector->setPlanewavesRotation(offset, 0., 0.);
        x->f_meter->setPlanewavesRotation(offset, 0., 0.);
        x->f_vector->computeRendering();
        x->f_meter->computeRendering();
        
        jbox_invalidate_layer((t_object *)x, NULL, hoa_sym_skeleton_layer);
        jbox_invalidate_layer((t_object *)x, NULL, hoa_sym_separator_layer);
        jbox_invalidate_layer((t_object *)x, NULL, hoa_sym_leds_layer);
        jbox_invalidate_layer((t_object *)x, NULL, hoa_sym_vectors_layer);
        jbox_redraw((t_jbox *)x);
    }
    
    return MAX_ERR_NONE;
}
void *play_new(t_symbol *s, int argc, t_atom *argv)
{
    // @arg 0 @ambisonic-order @optional 0 @type int @digest The ambisonic order
    // @description The ambisonic order, must be at least equal to 1

	t_atom arguments[1];
	ulong order = 1;
	ulong channels = 1;
    
	if(atom_isNumber(argv))
		order = max<ulong>(atom_getlong(argv), 1);
	
	if (s == gensym("hoa.play~") || s == gensym("hoa.2d.play~"))
		channels = order * 2 + 1;
	else if (s == gensym("hoa.3d.play~"))
		channels = (order+1) * (order+1);
    
	return object_new_typed(CLASS_BOX, gensym("sfplay~"), 1, arguments);
}
t_max_err channel_set(t_hoa_3d_decoder *x, t_object *attr, long argc, t_atom *argv)
{
	if(argc && argv && atom_isNumber(argv))
	{
        if (x->f_mode == hoa_sym_regular)
        {
            object_method(hoa_sym_dsp->s_thing, hoa_sym_stop);
            long channels = Math<long>::clip(atom_getlong(argv), 4, HOA_MAX_PLANEWAVES);
            ulong order = x->f_decoder->getDecompositionOrder();
            x->f_decoder = SharedPtr<Decoder<Hoa3d, float>>(new Decoder<Hoa3d, float>::Regular(order, channels));
            x->f_number_of_angles = x->f_decoder->getNumberOfPlanewaves() * 2;
        }
        
        x->f_number_of_channels = x->f_decoder->getNumberOfPlanewaves();
        
        object_attr_touch((t_object *)x, hoa_sym_angles);
        hoa_3d_decoder_resize_outlets(x);
    }
    return MAX_ERR_NONE;
}