| 
					
				 | 
			
			
				@@ -37,6 +37,7 @@ laBaseNodeType LA_IDN_OUTPUT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laBaseNodeType LA_IDN_SCOPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laBaseNodeType LA_IDN_ENVELOPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laBaseNodeType LA_IDN_QUANTIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+laBaseNodeType LA_IDN_SYNTH_DRIVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laPropContainer* LA_PC_IDN_INPUT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laPropContainer* LA_PC_IDN_FM; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -46,6 +47,7 @@ laPropContainer* LA_PC_IDN_OUTPUT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laPropContainer* LA_PC_IDN_SCOPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laPropContainer* LA_PC_IDN_ENVELOPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laPropContainer* LA_PC_IDN_QUANTIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+laPropContainer* LA_PC_IDN_DRIVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define _2PI 6.283185307 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -546,6 +548,72 @@ void laui_QuantizeNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laCol 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laEndRow(uil,b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void IDN_SynthDriverInit(laSynthNodeDriver* n, int NoCreate){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(NoCreate){ return; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    n->Prev=laCreateInSocket("PREV",0); n->Next=laCreateOutSocket(n,"NEXT",0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    n->InTransport=laCreateInSocket("TRANSPORT",LA_PROP_FLOAT|LA_PROP_ARRAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    n->InReset=laCreateInSocket("RESET",LA_PROP_FLOAT|LA_PROP_ARRAY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strSafeSet(&n->Base.Name,"Sound Player"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void IDN_SynthDriverDestroy(laSynthNodeDriver* n){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laDestroyInSocket(n->InTransport); laDestroyInSocket(n->InReset); strSafeDestroy(&n->Base.Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laDestroyInSocket(n->Prev); laDestroyOutSocket(n->Next); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int IDN_SynthDriverVisit(laSynthNodeDriver* n, laNodeVisitInfo* vi){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_GUARD_THIS_NODE(n,vi); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(LA_SRC_AND_PARENT(n->Prev)){ laBaseNode*bn=n->Prev->Source->Parent; LA_VISIT_NODE(bn,vi); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(LA_SRC_AND_PARENT(n->InTransport)){ laBaseNode*bn=n->InTransport->Source->Parent; LA_VISIT_NODE(bn,vi); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(LA_SRC_AND_PARENT(n->InReset)){ laBaseNode*bn=n->InReset->Source->Parent; LA_VISIT_NODE(bn,vi); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_ADD_THIS_NODE(n,vi); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return LA_DAG_FLAG_PERM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int IDN_SynthDriverEval(laSynthNodeDriver* n){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSynth*ss=n->Target; if(!ss){ return 0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int trans=n->iTransport; LA_GET_SRC_AS_VALUE(trans,n->InTransport); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int res=n->iReset; LA_GET_SRC_AS_VALUE(res,n->InReset); int dif=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(n->AlreadyReset && res==0){ n->AlreadyReset=0; res=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elif(!n->AlreadyReset && res!=0){ n->AlreadyReset=1; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else{ res=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinLock(&ss->Lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(ss->Playing!=trans){ dif=1; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ss->Playing = trans; if(res){ ss->EvalSamples=0; ss->EvalTime=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinUnlock(&ss->Lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(dif){ laNotifyInstanceUsers(ss); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void IDN_SynthDriverCopy(laSynthNodeDriver* new, laSynthNodeDriver* old, int DoRematch){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(DoRematch){ LA_IDN_NEW_LINK(InTransport); LA_IDN_NEW_LINK(InReset); return; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    new->iTransport = old->iTransport; new->iReset = old->iReset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memAssignRef(new,&new->Target,old->Target); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laui_SynthDriverNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laColumn* c=laFirstColumn(uil),*cl,*cr,*cll,*clr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_BASE_NODE_HEADER(uil,c,This); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSplitColumn(uil,c,0.6); cl=laLeftColumn(c,0); cr=laRightColumn(c,3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //laSplitColumn(uil,cl,0.4); cll=laLeftColumn(cl,3); clr=laRightColumn(cl,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laUiItem* b2, *rui; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laShowNodeSocket(uil,cr,This,"prev",0)->Flags|=LA_UI_SOCKET_LABEL_W; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laShowNodeSocket(uil,cr,This,"next",0)->Flags|=LA_UI_SOCKET_LABEL_W; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laUiItem* b=laBeginRow(uil,cl,0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laShowNodeSocket(uil,cl,This,"in_transport",0); b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_transport.source")));{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laShowItemFull(uil,cl,This,"transport",0,"text=Transport",0,0)->Expand=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }laElse(uil,b2);{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laShowLabel(uil,cl,"Transport",0,0)->Expand=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }laEndCondition(uil,b2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laShowNodeSocket(uil,cl,This,"in_reset",0); b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_reset.source")));{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laUiItem* u=laShowItemFull(uil,cl,This,"reset",0,"text=Reset",0,0);u->Expand=1;u->Flags|=LA_UI_FLAGS_MOMENTARY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }laElse(uil,b2);{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laShowLabel(uil,cl,"Reset",0,0)->Expand=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }laEndCondition(uil,b2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laEndRow(uil,b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laShowItemFull(uil,cl,This,"target",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void laRebuildSynthGraphs(int current_only){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(MAIN.Audio->CurrentSynth && current_only){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -586,7 +654,13 @@ int laEvalSynthGraphs(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void laaudio_DataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    float* out=pOutput; int any=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    float* out=pOutput; int any=1; int Paused; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinLock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Paused = MAIN.Audio->Paused; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinUnlock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(Paused){ memset(out,0,sizeof(float)*LA_SYNTH_PLEN); return; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for(int i=0;i<frameCount;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(MAIN.Audio->NextAudioSample>=LA_SYNTH_PLEN){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             MAIN.Audio->NextAudioSample=0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -653,11 +727,11 @@ void laInitMiniAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laRefreshAudioDevices(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    la_SelectAudioDevice(MAIN.Audio->AudioDevices.pFirst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    INITPACKET(MAIN.Audio->AudioSamples); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laSpinInit(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    INITPACKET(MAIN.Audio->AudioSamples); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    la_SelectAudioDevice(MAIN.Audio->AudioDevices.pFirst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void laDeinitAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laSpinDestroy(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -666,6 +740,28 @@ void laDeinitAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ma_context_uninit(&MAIN.Audio->MiniAudioContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laStartAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinLock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MAIN.Audio->Paused = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinUnlock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ma_device_start(&MAIN.Audio->AudioDevice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laStopAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ma_device_start(&MAIN.Audio->AudioDevice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laPauseAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinLock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MAIN.Audio->Paused = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSpinUnlock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laResetAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(laSynth* s=MAIN.Audio->Synths.pFirst;s;s=s->Item.pNext){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laSpinLock(&s->Lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        s->EvalTime = 0; s->EvalSamples = 0; s->Playing = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laSpinUnlock(&s->Lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // Operations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int OPINV_laRefreshAudioDevices(laOperator* a, laEvent* e){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -731,7 +827,7 @@ int OPINV_laSynthPlay(laOperator* a, laEvent* e){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ss->Playing=play; if(!play){ ss->EvalSamples=0; ss->EvalTime=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laSpinUnlock(&ss->Lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ma_device_start(&MAIN.Audio->AudioDevice); laNotifyInstanceUsers(ss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(play){ laStartAudio(); } laNotifyInstanceUsers(ss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return LA_FINISHED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -898,7 +994,8 @@ void la_AudioPreFrame(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laSpinLock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     anyaudio=MAIN.Audio->AudioAny; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laSpinUnlock(&MAIN.Audio->AudioStatusLock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(!anyaudio){ ma_device_stop(&MAIN.Audio->AudioDevice); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //if(anyaudio){ ma_device_start(&MAIN.Audio->AudioDevice); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //else{ ma_device_stop(&MAIN.Audio->AudioDevice); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void laInitAudio(){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1030,6 +1127,22 @@ void laInitAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laAddEnumItemAs(p,"IDLE","Idle","Trigger idle",0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laAddEnumItemAs(p,"TRIG","Trigger","Trigger active",1,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pc=laAddPropertyContainer("la_node_synth_driver", "Synth Driver Node", "Control playing status of the synth",0,laui_SynthDriverNode,sizeof(laSynthNodeDriver),lapost_Node,0,1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_PC_IDN_DRIVER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddSubGroup(pc,"prev", "Previous","Previous node","la_in_socket",0,0,0,offsetof(laSynthNodeDriver,Prev),0,0,0,0,0,0,0,LA_UDF_SINGLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddSubGroup(pc,"next", "Next","Next node","la_out_socket",0,0,0,offsetof(laSynthNodeDriver,Next),0,0,0,0,0,0,0,LA_UDF_SINGLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddSubGroup(pc,"in_transport", "In Transport","Transport input","la_in_socket",0,0,0,offsetof(laSynthNodeDriver,InTransport),0,0,0,0,0,0,0,LA_UDF_SINGLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddSubGroup(pc,"in_reset", "In Reset","Reset input (trigger on rising edge)","la_in_socket",0,0,0,offsetof(laSynthNodeDriver,InReset),0,0,0,0,0,0,0,LA_UDF_SINGLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    p=laAddEnumProperty(pc,"transport","Transport","Play or stop the synth playing",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laSynthNodeDriver,iTransport),0,0,0,0,0,0,0,0,0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddEnumItemAs(p,"STOPPED","Stopped","Synth is stopped",0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddEnumItemAs(p,"PLAYING","Playing","Synth is playing",1,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    p=laAddEnumProperty(pc,"reset","Reset","Reset Synth",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laSynthNodeDriver,iReset),0,0,0,0,0,0,0,0,0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddEnumItemAs(p,"IDLE","Idle","Trigger idle",0,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddEnumItemAs(p,"TRIG","Trigger","Trigger active",1,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laAddSubGroup(pc,"target","Target","Target synth to control","la_synth",0,0,0,offsetof(laSynthNodeDriver,Target),laget_FirstSynth,0,laget_ListNext,0,0,0,0,LA_UDF_REFER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pc=laAddPropertyContainer("la_node_synth_quantize", "Quantize Node", "Quantize control voltages",0,laui_QuantizeNode,sizeof(laSynthNodeQuantize),lapost_Node,0,1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     LA_PC_IDN_QUANTIZE=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1048,12 +1161,16 @@ void laInitAudio(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     LA_IDN_REGISTER("Sound Output",U'🕪',LA_IDN_OUTPUT, LA_PC_IDN_OUTPUT, IDN_Output, laSynthNodeOutput); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     LA_IDN_REGISTER("Envelope",U'^',LA_IDN_ENVELOPE, LA_PC_IDN_ENVELOPE, IDN_Envelope, laSynthNodeEnvelope); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     LA_IDN_REGISTER("Quantize",U'#',LA_IDN_QUANTIZE, LA_PC_IDN_QUANTIZE, IDN_Quantize, laSynthNodeQuantize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    LA_NODE_CATEGORY_SYNTHESIZER=laAddNodeCategory("OSC",0,LA_RACK_TYPE_AUDIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    LA_NODE_CATEGORY_SYSTEM_SOUND=laAddNodeCategory("System",0,LA_RACK_TYPE_AUDIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_IDN_REGISTER("Sound Player",U'⏯',LA_IDN_SYNTH_DRIVER, LA_PC_IDN_DRIVER, IDN_SynthDriver, laSynthNodeDriver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_NODE_CATEGORY_SYNTHESIZER=laEnsureNodeCategory("OSC",0,LA_RACK_TYPE_AUDIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_NODE_CATEGORY_SYSTEM_SOUND=laEnsureNodeCategory("System",0,LA_RACK_TYPE_AUDIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_SYNTHESIZER, &LA_IDN_INPUT,&LA_IDN_FM,&LA_IDN_NOISE,&LA_IDN_VCA,&LA_IDN_ENVELOPE,&LA_IDN_QUANTIZE,&LA_IDN_SCOPE,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_SYSTEM_SOUND, &LA_IDN_OUTPUT,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_NODE_CATEGORY_DRIVER=laEnsureNodeCategory("Driver",0,LA_RACK_TYPE_DRIVER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_DRIVER, &LA_IDN_SYNTH_DRIVER,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void laAudioDummy(){ 
			 |