00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <UT/UT_DSOVersion.h>
00028 #include <OP/OP_OperatorTable.h>
00029
00030 #include <CH/CH_LocalVariable.h>
00031 #include <PRM/PRM_Include.h>
00032 #include <CHOP/PRM_ChopShared.h>
00033
00034 #include <CHOP/CHOP_Handle.h>
00035 #include <OP/OP_Channels.h>
00036 #include "CHOP_Stair.h"
00037
00038 using namespace HDK_Sample;
00039
00040 CHOP_SWITCHER2(4, "Stair", 7, "Channel");
00041
00042
00043 static PRM_Name names[] =
00044 {
00045 PRM_Name("number", "Number of Stairs"),
00046 PRM_Name("height", "Stair Height"),
00047 PRM_Name("offset", "Offset"),
00048 PRM_Name("direction", "Direction"),
00049
00050 PRM_Name("channelname", "Channel Name"),
00051 PRM_Name("start", "Start"),
00052 PRM_Name("end", "End"),
00053
00054
00055
00056
00057 };
00058
00059
00060 static PRM_Name CHOPstairMenu[] = {
00061 PRM_Name("up", "Up"),
00062 PRM_Name("down", "Down"),
00063 PRM_Name(0),
00064 };
00065
00066 static PRM_ChoiceList stairMenu((PRM_ChoiceListType)(PRM_CHOICELIST_EXCLUSIVE
00067 | PRM_CHOICELIST_REPLACE),CHOPstairMenu);
00068
00069
00070 static PRM_Default nameDefault(0,"chan1");
00071 static PRM_Range stairRange(PRM_RANGE_RESTRICTED, 0, PRM_RANGE_UI, 10);
00072
00073 PRM_Template
00074 CHOP_Stair::myTemplateList[] =
00075 {
00076 PRM_Template(PRM_SWITCHER, 3, &PRMswitcherName, switcher),
00077
00078
00079 PRM_Template(PRM_INT_J, 1, &names[0], PRMoneDefaults, 0, &stairRange),
00080 PRM_Template(PRM_FLT_J, 1, &names[1], PRMoneDefaults, 0,
00081 &CHOP_DefaultValueRange),
00082 PRM_Template(PRM_FLT_J, 1, &names[2], PRMzeroDefaults, 0,
00083 &CHOP_DefaultValueRange),
00084 PRM_Template(PRM_ORD, 1, &names[3], PRMzeroDefaults, &stairMenu),
00085
00086
00087 PRM_Template(PRM_STRING, 1, &names[4], &nameDefault,0),
00088 PRM_Template(PRM_FLT_J, 1, &names[5], &CHOP_StartDefault,0,
00089 &CHOP_FrameRange),
00090 PRM_Template(PRM_FLT_J, 1, &names[6], &CHOP_EndDefault, 0,
00091 &CHOP_FrameRange),
00092 PRM_Template(PRM_FLT_J, 1, &CHOP_SampleRateName,
00093 &CHOP_SampleRateDefault,0,&CHOP_SampleRateRange),
00094 PRM_Template(PRM_ORD, 1, &CHOP_ExtendLeftName,0, &CHOP_ExtendMenu),
00095 PRM_Template(PRM_ORD, 1, &CHOP_ExtendRightName,0,&CHOP_ExtendMenu),
00096 PRM_Template(PRM_FLT_J, 1, &CHOP_DefaultValueName, PRMzeroDefaults,0,
00097 &CHOP_DefaultValueRange),
00098
00099 PRM_Template(),
00100 };
00101 OP_TemplatePair CHOP_Stair::myTemplatePair(
00102 CHOP_Stair::myTemplateList, &CHOP_Node::myTemplatePair);
00103
00104
00105
00106 enum
00107 {
00108 VAR_C = 200,
00109 VAR_NC = 201
00110 };
00111
00112 CH_LocalVariable
00113 CHOP_Stair::myVariableList[] = {
00114 { "C", VAR_C, 0 },
00115 { "NC", VAR_NC, 0 },
00116 { 0, 0, 0 }
00117 };
00118 OP_VariablePair CHOP_Stair::myVariablePair(
00119 CHOP_Stair::myVariableList, &CHOP_Node::myVariablePair);
00120
00121 float
00122 CHOP_Stair::getVariableValue(int index, int thread)
00123 {
00124 switch( index )
00125 {
00126 case VAR_C:
00127 return my_C;
00128
00129 case VAR_NC:
00130 return my_NC;
00131
00132 default:
00133 return CHOP_Node::getVariableValue(index, thread);
00134 }
00135 }
00136
00137 OP_Node *
00138 CHOP_Stair::myConstructor(OP_Network *net,
00139 const char *name,
00140 OP_Operator *op)
00141 {
00142 return new CHOP_Stair(net, name, op);
00143 }
00144
00145 CHOP_Stair::CHOP_Stair( OP_Network *net,
00146 const char *name,
00147 OP_Operator *op)
00148 : CHOP_Node(net, name, op),
00149 myExpandArray()
00150 {
00151 myParmBase = getParmList()->getParmIndex( names[0].getToken() );
00152 my_C = 0;
00153 my_NC = 0;
00154 }
00155
00156 CHOP_Stair::~CHOP_Stair()
00157 {
00158 }
00159
00160 unsigned
00161 CHOP_Stair::disableParms()
00162 {
00163 unsigned changes = CHOP_Node::disableParms();
00164
00165 if(LEXTEND() == CL_TRACK_DEFAULT || REXTEND() == CL_TRACK_DEFAULT)
00166 changes += enableParm(CHOP_DefaultValueName.getToken(),1);
00167 else
00168 changes += enableParm(CHOP_DefaultValueName.getToken(),0);
00169
00170 return changes;
00171 }
00172
00173
00174 void
00175 CHOP_Stair::getInterval(float t, float *start, float *end)
00176 {
00177 *start = START(t);
00178 *end = END(t);
00179
00180 if (*start >= *end)
00181 {
00182 float temp = *start;
00183 *start = *end;
00184 *end = temp;
00185 }
00186
00187 *start = ::SYSrint(*start);
00188 *end = ::SYSrint(*end);
00189 }
00190
00191 #define START_HANDLE 1
00192 #define END_HANDLE 2
00193 #define OFFSET_HANDLE 3
00194
00195 void
00196 CHOP_Stair::cookMyHandles(OP_Context &context)
00197 {
00198 CHOP_Handle *handle;
00199 CHOP_HandleLook hlook;
00200 float start, end;
00201 float xoffset, yoffset;
00202
00203 destroyHandles();
00204
00205
00206 getInterval(context.myTime, &start, &end);
00207 xoffset = (end - start) * 0.75 + start;
00208 yoffset = OFFSET(context.myTime);
00209
00210
00211 hlook = myChannels->getChannel("start") ? HANDLE_GUIDE : HANDLE_BOX;
00212
00213
00214
00215
00216
00217 handle = new CHOP_Handle(this, "start", START_HANDLE, start, 0.0,
00218 hlook, HANDLE_HORIZONTAL, (HANDLE_BAR |
00219 HANDLE_LABEL_RIGHT | HANDLE_LABEL_BOTTOM));
00220 myHandles.append(handle);
00221
00222
00223
00224 hlook = myChannels->getChannel("end") ? HANDLE_GUIDE : HANDLE_BOX;
00225 handle = new CHOP_Handle(this, "end", END_HANDLE, end, 0.0,
00226 hlook, HANDLE_HORIZONTAL, (HANDLE_BAR |
00227 HANDLE_LABEL_RIGHT | HANDLE_LABEL_BOTTOM |
00228 HANDLE_WIDTH_END));
00229 myHandles.append(handle);
00230
00231
00232
00233 hlook = myChannels->getChannel("offset") ? HANDLE_GUIDE : HANDLE_BOX;
00234 handle = new CHOP_Handle(this, "offset", OFFSET_HANDLE, xoffset, yoffset,
00235 hlook, HANDLE_VERTICAL,
00236 (HANDLE_LABEL_RIGHT | HANDLE_LABEL_BOTTOM));
00237 myHandles.append(handle);
00238 }
00239
00240 float
00241 CHOP_Stair::handleChanged(CHOP_Handle *handle, CHOP_HandleData *hdata)
00242 {
00243 float result = 0.0f;
00244 OP_Network *net = 0;
00245 float offset;
00246
00247 if (hdata->shift)
00248 {
00249 setCurrent(1);
00250 if (net = getParent())
00251 net->pickRequest(this, 0);
00252 }
00253
00254 switch(handle->getId())
00255 {
00256 case START_HANDLE:
00257 offset = CL_RINT(hdata->xoffset);
00258 if (!hdata->shift)
00259 SET_START(myHandleCookTime, offset);
00260 result = toUnit(offset, hdata->unit);
00261 break;
00262
00263 case END_HANDLE:
00264 offset = CL_RINT(hdata->xoffset);
00265 if (!hdata->shift)
00266 SET_END(myHandleCookTime, offset);
00267 result = toUnit(offset, hdata->unit, 1);
00268 break;
00269
00270 case OFFSET_HANDLE:
00271 if (!hdata->shift)
00272 SET_OFFSET(myHandleCookTime, hdata->yoffset);
00273 result = hdata->yoffset;
00274 break;
00275 }
00276
00277 return result;
00278 }
00279
00280
00281 float
00282 CHOP_Stair::shiftStart(float new_offset, float t)
00283 {
00284 SET_START(t, new_offset);
00285 return new_offset;
00286 }
00287
00288 OP_ERROR
00289 CHOP_Stair::cookMyChop(OP_Context &context)
00290 {
00291 CL_Track *track;
00292 float samplerate;
00293 float start, end;
00294 int left, right;
00295 float *data;
00296 UT_String name;
00297 float value;
00298 float defvalue;
00299 int nchan;
00300 float stepheight;
00301 float index, idxstep;
00302 int i;
00303
00304 destroyClip();
00305 samplerate = RATE(context.myTime);
00306 if(UTequalZero(samplerate))
00307 {
00308 addError(CHOP_ERROR_ZERO_SAMPLE_RATE);
00309 return error();
00310 }
00311 myClip->setSampleRate(samplerate);
00312
00313
00314
00315 CHAN_NAME(name, context.myTime);
00316 nchan = myExpandArray.setPattern(name);
00317
00318 my_NC = nchan;
00319
00320 getInterval(context.myTime, &start, &end);
00321
00322 left = LEXTEND();
00323 right = REXTEND();
00324
00325 myClip->setTrackLength((int)(end-start+1));
00326 myClip->setStart(start);
00327
00328
00329
00330 for (my_C=0; my_C < nchan; my_C++)
00331 {
00332 defvalue = DEFAULT(context.myTime);
00333 value = OFFSET(context.myTime);
00334 idxstep = (end-start+1) / (NUMBER(context.myTime) + 1);
00335 stepheight = HEIGHT(context.myTime);
00336 if (DIRECTION() == 1)
00337 stepheight *= -1;
00338
00339 track = myClip->addTrack(myExpandArray(my_C));
00340
00341 track->setLeft((CL_TrackOutside)left);
00342 track->setRight((CL_TrackOutside)right);
00343 if(left == CL_TRACK_DEFAULT || right == CL_TRACK_DEFAULT)
00344 track->setDefault(defvalue);
00345
00346 data = track->getData();
00347 track->constant(0);
00348 index = idxstep;
00349
00350 for(i=0; i < (end-start+1); i++)
00351 {
00352 if (i && i > index)
00353 {
00354 value += stepheight;
00355 index += idxstep;
00356 }
00357
00358 data[i] = value;
00359 }
00360 }
00361
00362 my_C = 0;
00363
00364 return error();
00365 }
00366
00367
00368
00369 void
00370 newChopOperator(OP_OperatorTable *table)
00371 {
00372 table->addOperator(
00373 new OP_Operator("hdk_stair",
00374 "HDK Stair",
00375 CHOP_Stair::myConstructor,
00376 &CHOP_Stair::myTemplatePair,
00377 0,
00378 0,
00379 &CHOP_Stair::myVariablePair,
00380 OP_FLAG_GENERATOR)
00381 );
00382 }