t_qri * add_q2trace( t_obj *cue_obj) /* * Add the given cue to the cue trace for its parent cue list */ { GSList **qtrace; /* Cue trace list */ t_qri *qri; /* New Cue Run Instance */ qri = NEW(t_qri); if(!qri) { E("Failed to MALLOC new cue trace node - cannot run cue"); return NULL; } qri->cue_obj = cue_obj; qri->status = am_cue_loaded; qri->actions = 0; qri->chains = 0; qtrace = &(QSHEET(CUE(cue_obj)->qsheet)->agent->qai.qtrace); *qtrace = g_slist_prepend(*qtrace, qri); return qri; } /* add_q2trace */
void trg_cue_goto(t_obj *cue_obj) /* * Trigger a cue, going to that in the cue sheet - ie changing the * running order. */ { t_am_args *args; /* Message arguments */ args = am_pool_get(); args->cue.cue_obj = cue_obj; client2agent_tx(QSHEET(CUE(cue_obj)->qsheet)->client, am_cue_goto, args); } /* cue_trg_goto() */
void tracelessU(int n, double **U, long *iseed) /* In U[][] returns traceless unitary matrix of size n. */ /* U=V D V+, where D is diagonal with l,-l pairs. */ { double **tmp,**tmp1,*tmpp; int i,j; tmp=(double**)malloc(sizeof(double*)*n); for(i=0;i<n;i++) tmp[i]=(double*)malloc(sizeof(double)*2*n); tmp1=(double**)malloc(sizeof(double*)*n); for(i=0;i<n;i++) tmp1[i]=(double*)malloc(sizeof(double)*2*n); /* get n/2 random real eigenvalues */ tmpp=(double *)malloc(sizeof(double)*n); for(i=0;i<n/2;i++) { tmpp[i]=(double)rand()/RAND_MAX; tmpp[n-1-i]=M_PI+tmpp[i]; } /* shuffle a bit */ for(i=0;i<n;i++) { j=rand() % n; /* switch i-th and j-th */ if (i!=j) { tmpp[j]+=tmpp[i]; tmpp[i]=tmpp[j]-tmpp[i]; tmpp[j]-=tmpp[i]; } } /* get random unitary */ CUE(n,tmp,iseed); /* multiply by diagonal - exponential */ for(i=0;i<n;i++) for(j=0;j<n;j++) { tmp1[i][2*j]=cos(tmpp[j])*tmp[i][2*j]-sin(tmpp[j])*tmp[i][2*j+1]; tmp1[i][2*j+1]=cos(tmpp[j])*tmp[i][2*j+1]+sin(tmpp[j])*tmp[i][2*j]; } /* multiply by U[][] */ adjungate_matrix(n,tmp); cmultiply(n,tmp1,tmp,U); for(i=0;i<n;i++) free(tmp[i]); free(tmp); for(i=0;i<n;i++) free(tmp1[i]); free(tmp1); free(tmpp); }
void edit_cue(t_obj *cue_obj) /* The cue to edit */ { t_ctxt *ctxt; /* The context */ t_usr_ctxt *usr; ctxt = new_ctxt(0, sizeof(t_usr_ctxt), cue_obj); if(!ctxt) return; usr = ctxt->usr; usr->cue_obj = cue_obj; /* Store cue in local context*/ usr->cue = CUE(cue_obj); /* ... and structure itself */ init_window(ctxt); } /* edit_cue() */
void COE(int n, double **o, long *iseed) /* COE matrix from CUE matrix U as U^T U */ { int i,j,k; double **tmp; tmp=(double**)malloc(sizeof(double*)*n); for(i=0;i<n;i++) tmp[i]=(double*)malloc(sizeof(double)*2*n); /* get CUE */ CUE(n,tmp,iseed); /* U^T U */ for(i=0;i<n;i++) for(j=0;j<n;j++) { o[i][2*j]=o[i][2*j+1]=0; for(k=0;k<n;k++) { o[i][2*j]+=tmp[k][2*i]*tmp[k][2*j]-tmp[k][2*i+1]*tmp[k][2*j+1]; o[i][2*j+1]+=tmp[k][2*i]*tmp[k][2*j+1]+tmp[k][2*i+1]*tmp[k][2*j]; } } for(i=0;i<n;i++) free(tmp[i]); free(tmp); }
void run_cue( t_obj *cue_obj, /* Cue to run */ bool asynchronous) /* Out of sequence? */ /* * This routine receives a cue which must be executed * There are two modes, normal or asynchronous. Normally cues are * scheduled in order from the cue sheet. However, cues may also be * asynchronously scheduled via triggers and in this case some of the * functionality (ie chain mode) is not applicable. * * We arrange for every action to be invoked. * In addition, if the cue is in 'chain' follow-on mode then we alert * the controller of each action executed (if appropriate) so it knows * all of the actions it has to wait to finish. * This is communicated by sending a message to the qagent via message queue. * In addition we send a similar message before we do anything and a * negating message when we've * finished executing actions to effectively lock this whilst we're * initialising everything to prevent race conditions where an action * finishes before we've kicked off the next making the qagent * think that everything is complete. */ { t_obj *qsheet_obj; t_qsheet *qsheet; t_cue *cue; t_am_args *args; /* Message arguments */ t_qri *qri; /* Cue Run Instance */ cue = CUE(cue_obj); qsheet_obj = cue->qsheet; qsheet = QSHEET(qsheet_obj); /* * Run the current Cue. First add a new Q Run Instance node to the * cue trace being maintained by the agent for this cue sheet */ qri = add_q2trace(cue_obj); /* Add new QRI to trace */ if(!qri) /* Failed to create QRI? */ return; if(!asynchronous) /* Running in order? */ g_atomic_int_set(&qri->chains, 1); g_atomic_int_set(&qri->actions, 1); /* * Do we need to send the MIDI Show Control "GO" message? * Note that we never do this for out-of-sequence cues, * but this should probably be controlled by an option * * TODO: Add general show option to ignore out-of-sequence * cues from sending a MIDI GO command */ if(!asynchronous && cue->tx_go) /* Running in order? */ tx_midi_go(); /* * Start all actions */ for_each_obj(cue->alist, (t_for_obj)run_action, qri); args = am_pool_get(); args->cue.qri = qri; client2agent_tx(qsheet->client, am_cue_running, args); /* * If decrementing no of actions takes us to zero then the cue * is complete */ if(g_atomic_int_dec_and_test(&qri->actions)) { args = am_pool_get(); args->cue.qri = qri; client2agent_tx(qsheet->client, am_cue_complete, args); } if(!asynchronous) { /* * If decrementing no. of chain actions takes us to zero then * the chain is complete */ if(g_atomic_int_dec_and_test(&qri->chains)) { args = am_pool_get(); args->cue.qri = qri; client2agent_tx(qsheet->client, am_cue_chain_complete, args); } } } /* run_cue() */