Skip to content

Commit

Permalink
fix regression bug in 1.5.2.2 regarding array of ugens
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Apr 4, 2024
1 parent 0202493 commit f9749df
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 90 deletions.
7 changes: 7 additions & 0 deletions VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
ChucK VERSIONS log
------------------

1.5.2.3 (April 2024)
=======
- (fixed) regression issue with connecting arrays of mono UGens to non-mono ugens;
e.g., `Gain a[2] => dac;`
FYI examples/stereo/ugen-array.ck now works once again


1.5.2.2 (March 2024)
=======
- (added) Open Sound Control (OSC) address wildcard support
Expand Down
12 changes: 12 additions & 0 deletions examples/array/array_ugens.ck
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,15 @@ for( int i; i < greater; i++ )
// 4) LHS => RHS[X]: LHS => to each element in RHS
Gain G => Gain H[3];
for( UGen h : H ) <<< "4) connected:", G.isConnectedTo(h) >>>;

// array of mono ugens => stereo ugen
Gain I[2] => Pan2 J;
// should be 1 0 0 1
<<< "5) connected:", I[0].isConnectedTo(J.left), I[0].isConnectedTo(J.right),
I[1].isConnectedTo(J.left), I[1].isConnectedTo(J.right) >>>;

// stereo ugen => array of mono ugens
Pan2 K => Gain L[2];
// should be 1 0 0 1
<<< "6) connected:", K.left.isConnectedTo(L[0]), K.right.isConnectedTo(L[0]),
K.left.isConnectedTo(L[1]), K.right.isConnectedTo(L[1]) >>>;
21 changes: 11 additions & 10 deletions src/core/chuck_instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8352,33 +8352,34 @@ void Chuck_Instr_UGen_Array_Link::execute( Chuck_VM * vm, Chuck_VM_Shred * shred
// go for it
// 1.5.2.2 (ge) semantic update: default num_out and num_in to 1,
// only update if actually an array; let ugen->add() sort out channels
num_out = ugen_generic_num_out_nochan( src_obj, m_srcIsArray );
num_in = ugen_generic_num_in_nochan( dst_obj, m_dstIsArray );
// 1.5.2.3 (pr-lab, ge, nick, eito, terry) un-break case of array => non-mono ugen
num_out = ugen_generic_num_out( src_obj, m_srcIsArray );
num_in = ugen_generic_num_in( dst_obj, m_dstIsArray );

// check for different combos, similar to ugen->add() | 1.5.2.2 (ge)
if( num_out == 1 && num_in == 1 )
{
Chuck_UGen * dst_ugen = ugen_generic_get_dst_nochan( dst_obj, 0, m_dstIsArray );
Chuck_UGen * src_ugen = ugen_generic_get_src_nochan( src_obj, 0, m_srcIsArray );
Chuck_UGen * dst_ugen = ugen_generic_get_dst( dst_obj, 0, m_dstIsArray );
Chuck_UGen * src_ugen = ugen_generic_get_src( src_obj, 0, m_srcIsArray );
if( dst_ugen == NULL || src_ugen == NULL ) goto null_pointer;
dst_ugen->add( src_ugen, m_isUpChuck );
}
else if( num_out == 1 && num_in > 1 )
{
Chuck_UGen * src_ugen = ugen_generic_get_src_nochan( src_obj, 0, m_srcIsArray );
Chuck_UGen * src_ugen = ugen_generic_get_src( src_obj, 0, m_srcIsArray );
for( t_CKINT i = 0; i < num_in; i++ )
{
Chuck_UGen * dst_ugen = ugen_generic_get_dst_nochan( dst_obj, i, m_dstIsArray );
Chuck_UGen * dst_ugen = ugen_generic_get_dst( dst_obj, i, m_dstIsArray );
if( dst_ugen == NULL || src_ugen == NULL ) goto null_pointer;
dst_ugen->add( src_ugen, m_isUpChuck );
}
}
else if( num_out > 1 && num_in == 1 )
{
Chuck_UGen * dst_ugen = ugen_generic_get_dst_nochan( dst_obj, 0, m_dstIsArray );
Chuck_UGen * dst_ugen = ugen_generic_get_dst( dst_obj, 0, m_dstIsArray );
for( t_CKINT i = 0; i < num_out; i++ )
{
Chuck_UGen * src_ugen = ugen_generic_get_src_nochan( src_obj, i, m_srcIsArray );
Chuck_UGen * src_ugen = ugen_generic_get_src( src_obj, i, m_srcIsArray );
if( dst_ugen == NULL || src_ugen == NULL ) goto null_pointer;
dst_ugen->add( src_ugen, m_isUpChuck );
}
Expand All @@ -8390,8 +8391,8 @@ void Chuck_Instr_UGen_Array_Link::execute( Chuck_VM * vm, Chuck_VM_Shred * shred
// map one to one, up to greater (lesser should modulo)
for( t_CKINT i = 0; i < greater; i++ )
{
Chuck_UGen * src_ugen = ugen_generic_get_src_nochan( src_obj, i, m_srcIsArray );
Chuck_UGen * dst_ugen = ugen_generic_get_dst_nochan( dst_obj, i, m_dstIsArray );
Chuck_UGen * src_ugen = ugen_generic_get_src( src_obj, i, m_srcIsArray );
Chuck_UGen * dst_ugen = ugen_generic_get_dst( dst_obj, i, m_dstIsArray );
if( dst_ugen == NULL || src_ugen == NULL ) goto null_pointer;
dst_ugen->add( src_ugen, m_isUpChuck );
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/chuck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2654,7 +2654,7 @@ t_CKTYPE type_engine_check_op_chuck( Chuck_Env * env, a_Exp lhs, a_Exp rhs,
{
// error
EM_error2( lhs->where,
"array ugen type '%s' has more than one output channel - can only => one-dimensional array of mono ugens",
"array ugen type '%s' has more than one output channel; can only => one-dimensional array of mono ugens",
left_ugen_type->c_name() );
return NULL;
}
Expand Down
69 changes: 0 additions & 69 deletions src/core/chuck_ugen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,72 +1695,3 @@ Chuck_UGen * ugen_generic_get_dst( Chuck_Object * obj, t_CKINT chan, t_CKBOOL is
return ((Chuck_UGen *) obj)->dst_for_src_chan( chan );
}
}




//-----------------------------------------------------------------------------
// name: ugen_generic_num_in_nochan()
// dsec: get number of input channels for ugen or ugen array
//-----------------------------------------------------------------------------
t_CKINT ugen_generic_num_in_nochan( Chuck_Object * obj, t_CKBOOL isArray )
{
if( isArray ) return ((Chuck_ArrayInt *)obj)->size();
else return 1;
}




//-----------------------------------------------------------------------------
// name: ugen_generic_num_out_nochan()
// dsec: get number of output channels for ugen or ugen array | 1.5.2.2 (ge)
//-----------------------------------------------------------------------------
t_CKINT ugen_generic_num_out_nochan( Chuck_Object * obj, t_CKBOOL isArray )
{
if( isArray ) return ((Chuck_ArrayInt *)obj)->size();
else return 1;
}




//-----------------------------------------------------------------------------
// name: ugen_generic_get_src_nochan()
// dsec: get source channel given a ugen or ugen array
//-----------------------------------------------------------------------------
Chuck_UGen * ugen_generic_get_src_nochan( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray )
{
if( isArray )
{
Chuck_ArrayInt *arr = (Chuck_ArrayInt *) obj;
Chuck_UGen *src = NULL;
arr->get( chan%arr->size(), (t_CKUINT *)(&src) );
return src;
}
else
{
return ((Chuck_UGen *)obj);
}
}



//-----------------------------------------------------------------------------
// name: ugen_generic_get_dst_nochan()
// dsec: get destination channel given a ugen or array object
//-----------------------------------------------------------------------------
Chuck_UGen * ugen_generic_get_dst_nochan( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray )
{
if( isArray )
{
Chuck_ArrayInt *arr = (Chuck_ArrayInt *) obj;
Chuck_UGen *dst = NULL;
((Chuck_ArrayInt *)obj)->get( chan%arr->size(), (t_CKUINT *)(&dst) );
return dst;
}
else
{
return ((Chuck_UGen *)obj);
}
}
16 changes: 6 additions & 10 deletions src/core/chuck_ugen.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,12 @@ struct Chuck_UAna : public Chuck_UGen


// helper functions for abstracting input/output between arrays and multichan
//t_CKINT ugen_generic_num_out( Chuck_Object * obj, t_CKBOOL isArray );
//t_CKINT ugen_generic_num_in( Chuck_Object * obj, t_CKBOOL isArray );
//Chuck_UGen *ugen_generic_get_src( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray );
//Chuck_UGen *ugen_generic_get_dst( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray );

// helper functions for abstracting input/output between arrays and ugen (no channel distinction)
t_CKINT ugen_generic_num_out_nochan( Chuck_Object * obj, t_CKBOOL isArray );
t_CKINT ugen_generic_num_in_nochan( Chuck_Object * obj, t_CKBOOL isArray );
Chuck_UGen *ugen_generic_get_src_nochan( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray );
Chuck_UGen *ugen_generic_get_dst_nochan( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray );
t_CKINT ugen_generic_num_out( Chuck_Object * obj, t_CKBOOL isArray );
t_CKINT ugen_generic_num_in( Chuck_Object * obj, t_CKBOOL isArray );
Chuck_UGen *ugen_generic_get_src( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray );
Chuck_UGen *ugen_generic_get_dst( Chuck_Object * obj, t_CKINT chan, t_CKBOOL isArray );




#endif
12 changes: 12 additions & 0 deletions src/test/01-Basic/250-ugen-arrays.ck
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,15 @@ for( int i; i < greater; i++ )
// 4) LHS => RHS[X]: LHS => to each element in RHS
Gain G => Gain H[3];
for( UGen h : H ) <<< "4) connected:", G.isConnectedTo(h) >>>;

// OVERTIME; 1.5.2.3 fix
Gain I[2] => Pan2 J;
// should be 1 0 0 1
<<< "5) connected:", I[0].isConnectedTo(J.left), I[0].isConnectedTo(J.right),
I[1].isConnectedTo(J.left), I[1].isConnectedTo(J.right) >>>;

// OVERTIME; 1.5.2.3 fix
Pan2 K => Gain L[2];
// should be 1 0 0 1
<<< "6) connected:", K.left.isConnectedTo(L[0]), K.right.isConnectedTo(L[0]),
K.left.isConnectedTo(L[1]), K.right.isConnectedTo(L[1]) >>>;
2 changes: 2 additions & 0 deletions src/test/01-Basic/250-ugen-arrays.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
4) connected: 1
4) connected: 1
4) connected: 1
5) connected: 1 0 0 1
6) connected: 1 0 0 1

0 comments on commit f9749df

Please sign in to comment.