# Is there a way to play a zone by its ID or get zone velocity range?



## olmerk (Apr 24, 2016)

So the question is in the title. I'll clarify a bit:
1) Suppose I have a zone ID, is there a way to trigger the particular sample belonging to this zone? 
2) Is it possible to get velocity range of a certain zone by its ID? 

Something says me both answers are no, but anyway)))


----------



## EvilDragon (Apr 24, 2016)

No to both. Well, arguably you could kludge up something to solve 2), but you would need to fire 127 notes FOR EACH KEY, to test the zone IDs - if a zone ID changes, you can deduce the velocity range from that.


----------



## olmerk (Apr 26, 2016)

Thank Evil Dragon!

One little question concerning using the following piece of code:


```
on note
  wait(1)
  $zones_id := get_event_par($EVEN_ID,$EVENT_PAR_ZONE_ID)
end on
```

The variable $zones_id perfectly gets the zone id.

But without a line: ignore_event($EVENT_ID) - on note callback triggers all the groups. So I put it there like this:


```
on note
ignore_event($EVENT_ID)
  wait(1)
  $zones_id := get_event_par($EVEN_ID,$EVENT_PAR_ZONE_ID)
end on
```

And in this case the script can't get zone id and variable $zones_id equals -1 all the time.

How can I solve the problem - getting zone id without firing up all the groups?

Thank you!


----------



## d.healey (Apr 26, 2016)

Disallow group


----------



## olmerk (Apr 26, 2016)

Actually below in this code I did put

disallow_group(-1)
allow_group(0)

and it doesn't help


----------



## EvilDragon (Apr 27, 2016)

You need to use play_note() if you ignore_event(). Then use set_event_par_arr() along with $EVENT_PAR_ALLOW_GROUP to disallow/allow groups on event basis.


----------



## olmerk (Apr 27, 2016)

Nope, still not working...

That's my basic script (I have 3 groups in the patch). The version below triggers all three groups.


```
on note

wait(1)
  $zones_id := get_event_par($EVENT_ID,$EVENT_PAR_ZONE_ID)

ignore_event($EVENT_ID)

fade_out($active_id,100,1)
$active_id := play_note($EVENT_NOTE,$EVENT_VELOCITY,0,-1)

$counter_disallow := 0
while ($counter_disallow < $NUM_GROUPS)
     set_event_par_arr($active_id,$EVENT_PAR_ALLOW_GROUP,0,$counter_disallow)
  inc($counter_disallow)
end while

set_event_par_arr($active_id, $EVENT_PAR_ALLOW_GROUP,1,0)

end on
```


This version triggers group 0, but returns $zones_id equal to -1


```
on note

ignore_event($EVENT_ID)

wait(1)
  $zones_id := get_event_par($EVENT_ID,$EVENT_PAR_ZONE_ID)

fade_out($active_id,100,1)
$active_id := play_note($EVENT_NOTE,$EVENT_VELOCITY,0,-1)

$counter_disallow := 0
while ($counter_disallow < $NUM_GROUPS)
     set_event_par_arr($active_id,$EVENT_PAR_ALLOW_GROUP,0,$counter_disallow)
  inc($counter_disallow)
end while

set_event_par_arr($active_id, $EVENT_PAR_ALLOW_GROUP,1,0)

end on
```


----------



## EvilDragon (Apr 27, 2016)

You need to wait(1) and get event ID *AFTER *play_note - and you need to get_event_par from $active_id, not $EVENT_ID, of course, since the goal here is not to retrieve the zone ID of the original event ($EVENT_ID), but the zone ID of the play_note event.


You also don't need to use a loop to disallow groups for the play_note event - you can simply use $ALL_GROUPS constant instead.


----------



## olmerk (Apr 27, 2016)

Thanks EvilDragon! Your correction will definitely work, but my goal is next.

I want to get zone id of the original event (note) using get_event_par(), then check if the same zone has been used by the previous note (comparing zone IDs). If it has, then the script must change the play_note() velocity accordingly (it's another piece of code) to hit a different zone.

Do you think it's workable?


----------



## EvilDragon (Apr 27, 2016)

I think you're overcomplicating it. First of all, you don't need to do this in the note callback. You can have a button that does the scanning, then loops through all velocities and all keys.


----------



## olmerk (Apr 27, 2016)

Explain me please the trick with the button.)

Also in my case some adjacent notes share the same zone, that's why I want to run the zone id comparison mentioned above.


----------



## EvilDragon (Apr 27, 2016)

You can do it all with a while loop in an UI callback of a button. No trick there... Since you only need to find zone IDs once, it makes no sense to have it done in note callback, which then forces searching for zone IDs on every played note (and this takes time, so you don't want to do this on every note, really).

So it's better to declare a 128*128 array with all default values of -1 (declare %zoneIDs[16384] := (-1)) that will have zone IDs written into it for each velocity and each key, then you can simply read the zone ID from that array, like this:

$ID := %zoneIDs[($EVENT_NOTE * 128) + $EVENT_VELOCITY]

Of course you would need to query if the value is -1 - you don't want to use that value as a zone ID, nothing would happen.


Problem is that this would only work for one group... So you'd need to have a 128*128 array for each and every group in your instrument, at which point this might not be as good of a solution either... Unless you don't have a lot of groups (which you don't, you have 3).


----------



## olmerk (Apr 27, 2016)

Thank EvilDragon! Seems I got the point. The only thing that is still unclear for me. How %zoneIDs[] will be filled with exact zone ids? Using get_event_par() on ui callback, which will "loop-scan" and return a zone id for each note at each velocity?


----------



## EvilDragon (Apr 27, 2016)

Yep! So you'll need to do that once to go through all the zones. Of course, you should make the %zoneIDs array persistent, so that zone info sticks when you save the instrument. And of course, if there are any mapping changes, you'll need to rescan all zones again.


----------



## olmerk (Apr 27, 2016)

Thanks a lot! I'll try to code it.


----------



## olmerk (Apr 27, 2016)

Ok, I'm stuck a bit)) 
Do I need to trigger 128*128 "dummy" play_note()s inside ui callback to retrieve zone ids using get_event_par()


----------



## EvilDragon (Apr 27, 2016)

Yes, of course. You will need a while loop within a while loop.


Oh it would also be a good idea to use change_vol() set to -200000 to silence those play_notes completely.


----------

