Help with SFZ groups please..

Link to good samples/soundfonts at http://wiki.linuxaudio.org/wiki/free_audio_data

Moderators: MattKingUSA, khz

Post Reply
User avatar
GMaq
Established Member
Posts: 2774
Joined: Fri Sep 25, 2009 1:42 pm
Has thanked: 520 times
Been thanked: 555 times

Help with SFZ groups please..

Post by GMaq »

Hi,

I'm working on a new AVL Drumkit and just arriving at the point where I've created an initial rough-in SFZ file.. I have some files for reference that @j_e_f_f_g helped me with many years ago but I need to expand on this a bit and I'd rather learn for myself how to employ groups properly so I understand it for future projects..

Before you direct me to the relevant SFZ format pages I've been there and their cryptic 3 word descriptions are virtually meaningless to me. I understand that I want a group to do things like make the open hihat sample stop playing when the closed hihat sample is played and make the crash cymbal choke sample terminate the crash cymbal sample etc..

I also understand the basic syntax 'group=1' and so on.. What I am unclear on is how to decide when things belong to the same group number and when things are to be assigned different group numbers.. Please speak calmly and slowly as if explaining to a simple child... :? :wink:

*EDIT... It's starting to sink in... groups should be specific to their kit pieces..? ie all hihat samples should be within the same group..? Crash 1/Crash1 Choke should be it's own group and so on..?

User avatar
Michael Willis
Established Member
Posts: 1451
Joined: Mon Oct 03, 2016 3:27 pm
Location: Rocky Mountains, North America
Has thanked: 69 times
Been thanked: 164 times
Contact:

Re: Help with SFZ groups please..

Post by Michael Willis »

This might be a signal to "abandon hope all ye who enter here," but you can take a look at how I did this in a drum kit I put together from the Tchackpoum samples:

https://github.com/michaelwillis/tchack ... s.sfz#L153

I adapted this from the SFZ files in Sam Gossner's Virtuosity Drums

User avatar
GMaq
Established Member
Posts: 2774
Joined: Fri Sep 25, 2009 1:42 pm
Has thanked: 520 times
Been thanked: 555 times

Re: Help with SFZ groups please..

Post by GMaq »

Thanks @Michael Willis for the reply..

Your kit handling of hihats is vastly more complicated than mine so I'm a little confused. Here is a snippet of my SFZ file pertaining to hihats and with groups set like this auditioning it in SFizz the group assignments don't seem to be doing anything, each of the 4 hihats samples just plays away without being controlled when a different hihat sample is played.

Any suggestions?

Code: Select all

// 42-Zildjian-13-HatClosed-HR-
<group> group=1 key=42 pan=36 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=42-Zildjian-13-HatClosed-HR-1.wav
<region> lovel=27 hivel=52 sample=42-Zildjian-13-HatClosed-HR-2.wav
<region> lovel=53 hivel=77 sample=42-Zildjian-13-HatClosed-HR-3.wav
<region> lovel=78 hivel=102 sample=42-Zildjian-13-HatClosed-HR-4.wav
<region> lovel=103 hivel=127 sample=42-Zildjian-13-HatClosed-HR-5.wav

// 43-TAMA-14-FloorTomEdge-HR-
<group> key=43 pan=-40 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=43-TAMA-14-FloorTomEdge-HR-1.wav
<region> lovel=27 hivel=52 sample=43-TAMA-14-FloorTomEdge-HR-2.wav
<region> lovel=53 hivel=77 sample=43-TAMA-14-FloorTomEdge-HR-3.wav
<region> lovel=78 hivel=102 sample=43-TAMA-14-FloorTomEdge-HR-4.wav
<region> lovel=103 hivel=127 sample=43-TAMA-14-FloorTomEdge-HR-5.wav

// 44-Zildjian-13-HatPedal-HR-
<group> group=1 key=44 pan=36 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=44-Zildjian-13-HatPedal-HR-1.wav
<region> lovel=27 hivel=52 sample=44-Zildjian-13-HatPedal-HR-2.wav
<region> lovel=53 hivel=77 sample=44-Zildjian-13-HatPedal-HR-3.wav
<region> lovel=78 hivel=102 sample=44-Zildjian-13-HatPedal-HR-4.wav
<region> lovel=103 hivel=127 sample=44-Zildjian-13-HatPedal-HR-5.wav

// 45-TAMA-10-TomCenter-HR-
<group> key=45 pan=10 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=45-TAMA-10-TomCenter-HR-1.wav
<region> lovel=27 hivel=52 sample=45-TAMA-10-TomCenter-HR-2.wav
<region> lovel=53 hivel=77 sample=45-TAMA-10-TomCenter-HR-3.wav
<region> lovel=78 hivel=102 sample=45-TAMA-10-TomCenter-HR-4.wav
<region> lovel=103 hivel=127 sample=45-TAMA-10-TomCenter-HR-5.wav

// 46-Zildjian-12-HatSemi-HR-
<group> group=1 key=46 pan=36 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=46-Zildjian-12-HatSemi-HR-1.wav
<region> lovel=27 hivel=52 sample=46-Zildjian-12-HatSemi-HR-2.wav
<region> lovel=53 hivel=77 sample=46-Zildjian-12-HatSemi-HR-3.wav
<region> lovel=78 hivel=102 sample=46-Zildjian-12-HatSemi-HR-4.wav
<region> lovel=103 hivel=127 sample=46-Zildjian-12-HatSemi-HR-5.wav

// 47-TAMA-10-TomEdge-HR-
<group> key=47 pan=10 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=47-TAMA-10-TomEdge-HR-1.wav
<region> lovel=27 hivel=52 sample=47-TAMA-10-TomEdge-HR-2.wav
<region> lovel=53 hivel=77 sample=47-TAMA-10-TomEdge-HR-3.wav
<region> lovel=78 hivel=102 sample=47-TAMA-10-TomEdge-HR-4.wav
<region> lovel=103 hivel=127 sample=47-TAMA-10-TomEdge-HR-5.wav

// 48-Zildjian-13-HatSwish-HR-
<group> group=1 key=48 pan=36 loop_mode=one_shot lochan=1 hichan=16
<region> lovel=1 hivel=26 sample=48-Zildjian-13-HatSwish-HR-1.wav
<region> lovel=27 hivel=52 sample=48-Zildjian-13-HatSwish-HR-2.wav
<region> lovel=53 hivel=77 sample=48-Zildjian-13-HatSwish-HR-3.wav
<region> lovel=78 hivel=102 sample=48-Zildjian-13-HatSwish-HR-4.wav
<region> lovel=103 hivel=127 sample=48-Zildjian-13-HatSwish-HR-5.wav


Aha! More info here: https://sfzformat.com/tutorials/cymbal_muting

User avatar
Michael Willis
Established Member
Posts: 1451
Joined: Mon Oct 03, 2016 3:27 pm
Location: Rocky Mountains, North America
Has thanked: 69 times
Been thanked: 164 times
Contact:

Re: Help with SFZ groups please..

Post by Michael Willis »

@GMaq I only vaguely understand the SFZ format, and mostly resort to imitating stuff I find, like Harry Potter reading annotations from the half blood prince. However, adding a "polyphony=1" directive to each of your hihat groups might do what you want.

User avatar
GMaq
Established Member
Posts: 2774
Joined: Fri Sep 25, 2009 1:42 pm
Has thanked: 520 times
Been thanked: 555 times

Re: Help with SFZ groups please..

Post by GMaq »

Michael Willis wrote: Tue Feb 07, 2023 10:51 pm

@GMaq I only vaguely understand the SFZ format, and mostly resort to imitating stuff I find, like Harry Potter reading annotations from the half blood prince. However, adding a "polyphony=1" directive to each of your hihat groups might do what you want.

Actually I was missing an off_by companion to the group looking closer at my JeffG notes, it works now with this:

Code: Select all

<group> group=1 key=44 pan=-36 loop_mode=one_shot off_mode=fast off_by=1 offby=1
User avatar
Michael Willis
Established Member
Posts: 1451
Joined: Mon Oct 03, 2016 3:27 pm
Location: Rocky Mountains, North America
Has thanked: 69 times
Been thanked: 164 times
Contact:

Re: Help with SFZ groups please..

Post by Michael Willis »

GMaq wrote: Tue Feb 07, 2023 11:06 pm
Michael Willis wrote: Tue Feb 07, 2023 10:51 pm

@GMaq I only vaguely understand the SFZ format, and mostly resort to imitating stuff I find, like Harry Potter reading annotations from the half blood prince. However, adding a "polyphony=1" directive to each of your hihat groups might do what you want.

Actually I was missing an off_by companion to the group looking closer at my JeffG notes, it works now with this:

Code: Select all

<group> group=1 key=44 pan=-36 loop_mode=one_shot off_mode=fast off_by=1 offby=1

Oh right! That just means that any time a sample in group 1 plays, it silences any sample that was already playing in group 1.

j_e_f_f_g
Established Member
Posts: 2032
Joined: Fri Aug 10, 2012 10:48 pm
Been thanked: 357 times

Re: Help with SFZ groups please..

Post by j_e_f_f_g »

In a nutshell, if you want the playback of a set of waves to cutoff another set of waves, you put all the first set waves into one group and give them a group number (with the group opcode), then use the off_by opcode with the second set.

For example, a closed hihat hit, as well as a pedal close, cut off any open hihat (whether half open, or fully open) sound.

Therefore, your closed hihat waves, and any closed pedal waves must have a group number. Your open hihat waves must have an off_by with that group number.

Code: Select all

<region> sample=Closed_Hihat.wav group=1
<region> sample=Closed_Pedal.wav group=1
<region> sample=Full_Open_Hihat.wav off_by=1
<region> sample=Half_Open_Hihat.wav off_by=1

If you want the sound to be slowly cutoff (versus immediately cutoff) also use off_mode=normal. Otherwise, the sound will be cutoff immediately (which is what you want for cutting off open hihat).

Code: Select all

<region> sample=Closed_Hihat.wav group=1
<region> sample=Closed_Pedal.wav group=1
<region> sample=Full_Open_Hihat.wav off_by=1 off_mode=normal
<region> sample=Half_Open_Hihat.wav off_by=1 off_mode=normal

Just for clarification, let's review some of the ways that you can "qualify" (ie, apply certain rules during playback to) the triggering of a wave.

If you want the waves to play only for a specific range of notes (numbers), use the lokey and hikey opcodes.

Code: Select all

<region> sample=w1.wav lokey=60 hikey=60 /* Play only for note 60 */
<region> sample=w2.wav lokey=30 hikey=31 /* Play only for notes 30 and 31 */

If you want the waves to play only for notes on a specific midi channel, but not other midi channels, use the lochan and hichan opcodes.

Code: Select all

<region> sample=w1.wav lochan=1 hichan=4 /* Play only for notes on chan 1 to 4 */
<region> sample=w2.wav lochan=10 hichan=10 /* Play only on chan 10 (General MIDI drum chan) */

If you want the waves to play only when a note is within a specific volume range, use the lovel and hivel opcodes.

Code: Select all

<region> sample=w1.wav lovel=1 hivel=30 /* Play only notes at a volume 1 to 30 */
<region> sample=w1.wav lovel=31 hivel=127 /* Play only notes at a volume greater than 30 */

If you want the waves to play only when a specific midi controller is a certain value, use the locc and hicc opcodes. Follow the cc with the controller number you desire. For example, if you want mod wheel, follow cc with 1. If you want sustain pedal, follow cc with 64. Etc.

Code: Select all

<region> sample=w1.wav locc1=100 hicc1=127 /* Play only when mod wheel is between 100 to 127 */
<region> sample=w1.wav locc64=1 hicc64=127 /* Play only when the sustain pedal is on */

If you want the waves to play only when another specific midi note is or was held down (ie, commonly referred to as "key switching"). Use the sw_lokey and sw_hikey opcodes, along with either the sw_last, sw_down, or sw_up opcode.

For example, assume you have 3 sets of waves, for 3 different kits. You have a snare sound for kit 1 (Kit1_Snare.wav), a different snare sound for kit 2 (Kit2_Snare.wav), and another snare sound for kit 3 (Kit3_Snare.wav). You're going to assign all 3 snare waves to note 38.

You decide to use midi notes 24, 25, and 26 to switch between the kits. After you press note 24, all subsequent notes will play kit 1's snare. After you press note 25, all subsequent note will play kit 2's snare. After 26, it's kit 3.

First you need to specify that notes 24 to 26 are being used to switch sounds. You do that with the sw_lokey and sw_hikey opcodes. Here you use sw_lokey=24 and sw_hikey=26. These 2 opcodes need to be added to all regions. Then you can add either a sw_last, sw_down, or sw_up opcode to each region. For example, sw_last means "in the range sw_lokey to sw_hikey, which note in that range was last played".

Here we use sw_last to implement our snare switch.

Code: Select all

/* Play Kit1_Snare if key 24 (out of 24, 25, and 26) was last played */
<region> sample=Kit1_Snare.wav lokey=38 hikey=38 sw_last=24 sw_lokey=24 sw_hikey=26
/* Play Kit2_Snare if key 25 (out of 24, 25, and 26) was last played */
<region> sample=Kit2_Snare.wav lokey=38 hikey=38 sw_last=25 sw_lokey=24 sw_hikey=26
/* Play Kit3_Snare if key 26 (out of 24, 25, and 26) was last played */
<region> sample=Kit3_Snare.wav lokey=38 hikey=38 sw_last=26 sw_lokey=24 sw_hikey=26

And of course, you can combine any or all of the above ways (opcodes) to determine when a region gets triggered (played):

Code: Select all

/* Play only when note 60 plays, and the mod wheel is set between 100 and 127 */
<region> sample=w1.wav locc1=100 hicc1=127 lokey=60 hikey=60

If you have dozens and dozens of waves, you can save yourself a lot of typing by putting waves with the same opcode values under their own <group> header (not to be confused with the aforementioned group opcode. These two things are for different purposes. They just unfortunately are named similarly).

For example, assume you have lot of regions with the opcode values lovel=1 and hivel=30. And you have lots of other regions with lovel=31 and hivel=127. You could add those opcodes to each region like so:

Code: Select all

<region> sample=SnareVel1.wav lokey=38 hikey=38 lovel=1 hivel=30
<region> sample=SnareVel2.wav lokey=38 hikey=38 lovel=31 hivel=127
<region> sample=KickVel1.wav lokey=36 hikey=36 lovel=1 hivel=30
<region> sample=KickVel2.wav lokey=36 hikey=36 lovel=31 hivel=127
<region> sample=CrashVel1.wav lokey=57 hikey=57 lovel=1 hivel=30
<region> sample=CrashVel2.wav lokey=57 hikey=57 lovel=31 hivel=127

But you save some typing by separating all the lovel=1 hivel=30 regions into their own <group> section, and then specify the lovel=1 hivel=30 opcodes on the group itself. When you do this, those group opcodes get automatically applied to all the regions under it. You can do likewise with the lovel=31 hivel=127 regions, like so:

Code: Select all

<group> lovel=1 hivel=30 
/* All regions below play only for notes with a vol between 1 and 30 */
<region> sample=SnareVel1.wav lokey=38 hikey=38
<region> sample=KickVel1.wav lokey=36 hikey=36
<region> sample=CrashVel1.wav lokey=57 hikey=57

<group> lovel=31 hivel=127 
/* All regions below play only for notes with a vol between 31 and 127 */
<region> sample=SnareVel2.wav lokey=38 hikey=38
<region> sample=KickVel2.wav lokey=36 hikey=36
<region> sample=CrashVel2.wav lokey=57 hikey=57

There are so many more opcodes you can add to <region> (and <group>) to affect the playback of waves that it would probably be easier to know what specific behavior you're trying to model, so that I can direct you to the specific opcodes to use for that purpose.

Author of BackupBand at https://sourceforge.net/projects/backupband/files/
My fans show their support by mentioning my name in their signature.

Post Reply