Factory soundfonts library

Hi @hannesmenzel,

I think it would be worth defining how we want to handle SFZ font variants depending on the type of MIDI controller.

I know most people here are keyboard players, and most SFZ instruments are naturally designed for keyboards (with velocity as the main expression parameter). My long-term goal, however, is to use Zynthian as a “sound synth” for EWI / wind MIDI instruments. That’s why I really appreciated that @jofemodo added the option to use .yml mapping (e.g. responding to CC2 / breath, and potentially other CCs as well). But that’s only one part — the other part is that the SFZ files themselves often need adjustments to feel natural on EWI (e.g. little or no dependence on velocity, expression driven by CC2/CC11, different dynamic layers, attack/release settings, etc.).

So it would be great to assume that alongside “_kb” versions there can also be other variants, for example:

  • *_kb.sfz (keyboard)
  • *_ewi.sfz (breath / CC2 friendly)
  • optionally even *_gi.sfz (guitar MIDI / other specific controllers — yes, I’m pushing it a bit :slightly_smiling_face:)

Question: How do we want to organize this in the library / folder structure so it stays clear and maintainable?
My suggestion: keep a single base sample set, and provide different SFZ mappings, with clear suffixes (_kb/_ewi/...) or separate subfolders like kb/ and ewi/.

I’d be happy to prepare the first EWI variant for specific fonts (for example VSCO Trumpet, which you mentioned as an example — those are also clearly in a keyboard-oriented version, as I’ve tested), but I’d like to align on a “convention” first so it fits both the community and the Zynthian workflow.

1 Like

This is a really good suggestion!

It might be obvious that I personally tend to prefer reducing the number of versions per sound to get a really tidy patch list. For example in the current stock library I find the “ethnic” list very pleasing visually (although I would omit it for other reasons), but the “strings” list not so much for that reason.

The question may be if a user using any kind of breath controller would like to have an extra category or subfolder for breath controller enabled patches instead of scrolling through the library in search of these kind of patches (much like Surge has patch categories for pads, leads, keys, … , and “MPE”). So it might be a) another patch repository a user can download or b) just an additional sub folder to have all these files in one place?

About editing: I think you have already experience in doing that. I have no clue how breath controllers work, mainly how they trigger the note-on message. But I think binding cc2 to certain parameters was possible before the *.yml implementation. What would be another option is duplicating the regions within one script and ad a keyswitch option between keyboard and breath input, but the issue above would still apply.

What do you think?

Here would be another proposal, I did quite some changes and fixes:

Salamander Drumkit.zip (6.1 KB)

This has no license file but readme states:

Licence: CC-by-sa

http://creativecommons.org/licenses/by-sa/3.0/

Author: Alexander Holm

Feel free to mail me with any questions, if you're lucky, I might just answer them ;)

axeldenstore (at) gmail (dot) com

samples are in the factory library or can be downloaded.

Hi, thanks for the reply — and I agree that reducing the number of versions per sound is a very good point. From a Zynthian UI perspective it makes perfect sense: a clean and tidy patch list is a huge advantage. On the SFZ side it may mean a “bigger” file (more regions / layers), but that still feels like an acceptable trade-off for clarity and simplicity for the user.

I also lean towards the idea that solving this with extra repositories / subfolders / additional categories is not ideal. In the long run it would become a complicated structure that nobody can navigate, and maintenance would quickly turn into a nightmare.

Based on your feedback I’ve been thinking more about the fact that the real issue isn’t just “EWI vs keyboard”, but rather groups of MIDI controllers — i.e. what they typically send to the synthesizer and what kind of behavior the user expects. Roughly, I end up with:

  • Keyboards – typically polyphonic, primary expression via velocity / volume
  • EWI / wind controllers – typically monophonic, primary expression via expression (CC2/CC11)
  • Breath controller + keyboard, MIDI guitar – polyphonic, but expression via expression plus pitch bend
  • MPE controllers (of any kind) – polyphonic + per-note expression (expression + additional dimensions)

A quick note on Zynthian: historically (and to some extent still) the situation has been that CC messages were often intercepted for UI control, and not all of them were automatically passed through to the engine. That’s why we have “MIDI learn”, where users map CCs to menu items. And for some engines (e.g. sfizz) there has been gradual work on which CCs should pass directly to the engine — and during development this apparently evolved into a configuration mechanism, which is what we now use via .yml. I’m not claiming I understand all details — the exact background would best be confirmed by @jofemodo .

And now the key point: your idea of a single SFZ file containing multiple “modes” (keyboard / breath / …) is exactly what I think we need. One patch in the list, but internally defined sections/regions for different controller types.

The only place where I’d slightly push back is the switching mechanism:
Keyswitch is great for keyboard players (and it’s a well-established pattern), but personally I prefer switching via CC — it’s “without extra notes” and it can be standardized (e.g. a fixed CC used as “Mode Select”). A keyswitch inevitably consumes one or two notes in the range, which can be awkward on EWI. On the other hand, I understand that keyswitch is the most natural option for many users, and they could even map a CC to it via MIDI learn if needed — so my argument isn’t bulletproof here :slight_smile:

So my current preference would be:

  • 1 patch = 1 SFZ, with multiple modes inside (keyboard / breath / …)
  • switching ideally via CC, optionally also via keyswitch in parallel when it makes sense. On this point I’m happy to go with what works best for the keyboard majority.

How do you see it now? Would it make sense to agree on some kind of “standard” for mode switching (e.g. a specific CC, or a defined keyswitch note range), so it stays consistent across patches?

Also, it occurs to me that each SFZ should have a short help/notes section — nothing huge, just a quick description of what the user can expect from that particular instrument. And then a clear table showing which controllers a given SFZ supports.

I have done some more investigation and it seems that the main advantage to sforzando is its support of the ARIA specific opcodes, i.e. those that are not part of the official SFZ specification. So most libraries that comply with SFZ v1 or v2 should mostly work in sfizz but those that extend features using the ARIA specific opcodes may have some functionality limited or missing. It does not look like sforznado is likely to create a LV2 version or full API and headless version of its standalone product and it is closed source so we can’t help them with that. This leads me to recommend focusing on sfizz enahancements. We should make sfizz our default sfz player. Maybe we should disable by default linuxsampler but leave it available for users to re-enable if they need it (particularly for gig support). Any libraries that a user finds is not sufficiently supported can be highlighted so that we are aware of its limitations and can lobby for support of the required headers, opcodes, etc. (Lobbying may include providing software patches / pull requests, etc.)

Sfizz supports all SFZ v1 opcodes except for:

  • hichan (by design)
  • lowchan (by design)
  • sync beats
  • sync offset
  • hibpm (wip)
  • lobpm (wip)

Sfizz supports about 50% of SFZ v2 opcodes and abot 50% of ARIA opcodes.

Whatever structure we have for the libraries, we may benefit from some metadata around support. It should be possible to script this so that a library can be scanned for headers and opcodes and compared with a list of supported headers and opcodes so that limitations are automatically reported. (It feels odd that this isn’t already done!)

4 Likes

Hi, thanks for the update and for the changes / fixes.

I’m not sure if you’ve seen this, but while preparing I wanted to review what exactly was changed in the SFZ. I found a GitHub repository for Salamander Drumkit that seems to be maintained with a lot of care — it includes full change history and also a complete license context (author + CC BY-SA 3.0), which makes it a really good reference point.

It might make sense to treat this repo as the “canonical” source and either contribute patches there (or at least link to it), so it’s always clear where a given version comes from and what changes it contains.

Repo:

Just to confirm: are your edits based on this repository, or is it an independent fork/patch?

1 Like

There is a sfz checker: GitHub - sfztools/sfz-opcode-checker: Checks opcodes availability in sfzformat.github.io database from SFZ files definitions. This currently has a bug that it downloads the syntax.yml from the wrong url and fails. I have manually downloaded the correct file and scanned a couple of sfz files and is shows full compatibility for those. We could use this to provide a report for each installed sfz so that users can see the level of compatibility with sfizz. This could be a webconf feature that shows a RAG status of each library with a link to show the full report. It could be run when a sfz is installed using webconf and updated when a zynthian update detects a change of the validation (syntax.yml) file upstream.

4 Likes

It’s based on the patch in the current zynthian-data. But it seems to not differ from the repository here. About the repository above:

  • It does not include the samples either. It just names the download sources.
  • So we might include the readme file from the repository. But I actually don’t see the real difference between the license informations, and I also do not think this is the repository of the author, but rather state that the included readme in zynthian-data is in fact the readme of the author itself?
  • I wrote most of the changes into the script itself for now. It’s a work in progress thing. The issue is: there are some changes that fix things, and then there are some changes that change the behaviour.
  • It definitely has the same script with the same issues:

Just to name one (upper velocity level without lower velovity level).

(P.S.: This is probably not a valid substitute for a license file)

P.P.S.: You’re right that the kinwie-edited scripts address some of the issues already. What I personally do not like is to use the <global> opcode multiple times for another level of complexity.

How exactly would you switch with cc, and which one? Would you use the 127 ticks of the control or would you distribute it across the cc range with hiccN and loccN? How should Zynthian represent the articulations, snapshots or variants on the UI?

When using a (common) CC for articulation changing, the *.yml file would need to represent this like the current keyswitch behaviour. So if you are after the range of CC values strategy, Zynthian UI must be feeded with these ranges.

I think it’s worth thinking about it, but on the other hand midi controller mechanisms towards program changes are so different. I think my arturia uses CC107 and CC109 for bank and preset changes, but it sends the value 65 and 63 to increment and decrement the patch lists in Analog Lab…

I think keyswitches are common practice switching articulations or snapshots of an instrument.

Mechanism is split between the YAML and the SFZ file and works as follows:

  Bass Drum 1:
    Bass Drum volume:
      midi_cc: 16
      value: 127
    Bass Drum pan:
      midi_cc: 17
      value: 64
  
  Bass Drum 2:
    Bass Drum type:
      midi_cc: 18
      value: 0
      graph_path: 'note_on'
      labels: ['Clean', 'Color 01', 'Color 02', 'Color 03', 'Color 04', 'Color 05', 'Tape', 'Tube']
      ticks: [0, 16, 32, 48, 64, 80, 96, 112]
    Bass Drum decay:
      midi_cc: 19
      value: 0
      graph_path: 'note_on'
      labels: ['Decay Short', 'Decay Medium', 'Decay Long']
      ticks: [0, 43, 86]
    Bass Drum tone:
      midi_cc: 20
      value: 0
      graph_path: 'note_on'
      labels: ['Tone A', 'Tone B', 'Tone C', 'Tone D', 'Tone E', 'Tone F']
      ticks: [0, 22, 44, 65, 86, 107]
    Bass Drum tune:
      midi_cc: 21
      value: 64

…and then the corresponding part in the SFZ:

	
  #define $BASS_DRUM_NOTE 36
 
  set_cc16=127  // Bass Drum Volume
  set_cc17=64   // Bass Drum Pan
  set_cc18=0    // Bass Drum Type
  set_cc19=0    // Bass Drum Decay
  set_cc20=0    // Bass Drum Tone
  set_cc21=64   // Bass Drum Tune
  
  
  <master>
  key=$BASS_DRUM_NOTE
  amp_veltrack=100
  pitch_keycenter=$BASS_DRUM_NOTE
  volume=-30
  volume_cc16=36
  volume_curvecc16=20
  pan=-100
  pan_oncc17=200

<group> // Bass Drum - Clean (Type mode)
  locc18=0
  hicc18=15
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_A_01.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_A_06.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=107 hicc21=127
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_B_06.wav locc19=0 hicc19=42 locc20=22 hicc20=43 locc21=107 hicc21=127
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_C_06.wav locc19=0 hicc19=42 locc20=44 hicc20=64 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_D_01.wav locc19=0 hicc19=42 locc20=65 hicc20=85 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_D_06.wav locc19=0 hicc19=42 locc20=65 hicc20=85 locc21=107 hicc21=127
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_E_06.wav locc19=0 hicc19=42 locc20=86 hicc20=106 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_F_01.wav locc19=0 hicc19=42 locc20=107 hicc20=127 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/01._Short/BD_909_Clean_Short_F_06.wav locc19=0 hicc19=42 locc20=107 hicc20=127 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_A_01.wav locc19=43 hicc19=85 locc20=0 hicc20=21 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_A_06.wav locc19=43 hicc19=85 locc20=0 hicc20=21 locc21=107 hicc21=127
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_B_06.wav locc19=43 hicc19=85 locc20=22 hicc20=43 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_C_01.wav locc19=43 hicc19=85 locc20=44 hicc20=64 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_C_06.wav locc19=43 hicc19=85 locc20=44 hicc20=64 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_D_01.wav locc19=43 hicc19=85 locc20=65 hicc20=85 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_D_06.wav locc19=43 hicc19=85 locc20=65 hicc20=85 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_E_01.wav locc19=43 hicc19=85 locc20=86 hicc20=106 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_E_06.wav locc19=43 hicc19=85 locc20=86 hicc20=106 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_F_01.wav locc19=43 hicc19=85 locc20=107 hicc20=127 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/02._Medium/BD_909_Clean_Medium_F_06.wav locc19=43 hicc19=85 locc20=107 hicc20=127 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_A_01.wav locc19=86 hicc19=127 locc20=0 hicc20=21 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_A_06.wav locc19=86 hicc19=127 locc20=0 hicc20=21 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_B_01.wav locc19=86 hicc19=127 locc20=22 hicc20=43 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_B_06.wav locc19=86 hicc19=127 locc20=22 hicc20=43 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_C_01.wav locc19=86 hicc19=127 locc20=44 hicc20=64 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_C_06.wav locc19=86 hicc19=127 locc20=44 hicc20=64 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_D_01.wav locc19=86 hicc19=127 locc20=65 hicc20=85 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_D_06.wav locc19=86 hicc19=127 locc20=65 hicc20=85 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_E_01.wav locc19=86 hicc19=127 locc20=86 hicc20=106 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_E_06.wav locc19=86 hicc19=127 locc20=86 hicc20=106 locc21=107 hicc21=127
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_F_01.wav locc19=86 hicc19=127 locc20=107 hicc20=127 locc21=0 hicc21=21
..
  <region> sample=TR-909/01._Bass_Drum/01._Clean/03._Long/BD_909_Clean_Long_F_06.wav locc19=86 hicc19=127 locc20=107 hicc20=127 locc21=107 hicc21=127
  
<group> // Bass Drum - Color 01 (Type mode)
  locc18=16
  hicc18=31
  <region> sample=TR-909/01._Bass_Drum/04._Color/Color_01/01._Short/BD_909_Color_01_Short_A_01.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=0 hicc21=21
  <region> sample=TR-909/01._Bass_Drum/04._Color/Color_01/01._Short/BD_909_Color_01_Short_A_02.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=22 hicc21=43
  <region> sample=TR-909/01._Bass_Drum/04._Color/Color_01/01._Short/BD_909_Color_01_Short_A_03.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=44 hicc21=64
  <region> sample=TR-909/01._Bass_Drum/04._Color/Color_01/01._Short/BD_909_Color_01_Short_A_04.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=65 hicc21=85
  <region> sample=TR-909/01._Bass_Drum/04._Color/Color_01/01._Short/BD_909_Color_01_Short_A_05.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=86 hicc21=106
  <region> sample=TR-909/01._Bass_Drum/04._Color/Color_01/01._Short/BD_909_Color_01_Short_A_06.wav locc19=0 hicc19=42 locc20=0 hicc20=21 locc21=107 hicc21=127
  .....

Here it is in a “single bass drum” form: using CCs I can control volume, pan, color, decay, tone type, and tuning of the drum.

Great this works. Didn’t know the (“ticked”) labeled controls work that way. It’s definitely an option.

try my quick changes to support EWI.
Trumpet_EWI.zip (3.2 KB)

I have added some functions to the sfizz engine to validate supported opcodes. These are not yet used but could be added to webconf to display indication of sfz that are not fully supported and offer a report of what problems there are.

I have manually run these on the standard install zynthian-data and found:

  • There are 758 sfz files.
  • There are 5 unsupported opcodes within these 758 sfz files: ‘lochan’, ‘hichan’, ‘ampeg_dynamic’, ‘cutoff_smoothccN’, ‘group_label’.
  • ‘lochan’ & ‘hichan’ are unsupported by design, i.e. sfizz purposefully ignores these.
  • ‘ampeg_dynamic’ & ‘group_label’ are ARIA engine specific codes, i.e. not part of the official SFZ spec.
  • ‘group_label’ is only used for display.
  • There are 63 sfz in zynthian-data that use one or more of these unsupported opcodes.
  • 25 only use ‘group_label’ leaving 38 that may have some impact.

So the problems with sfizz appear quite limited. Here is the list of affected sfx:

/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SEC-PERF-KS-C3.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SOLO-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SOLO-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SOLO-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SEC-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SEC-PERF-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SEC-PERF-KS-C2.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SOLO-PERF-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SOLO-PERF-staccato-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SEC-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SOLO-PERF-KS-C2.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SEC-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SEC-PERF-staccato-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SOLO-PERF-KS-C3.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/flute-SOLO-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Woodwinds/all-woodwinds-SEC-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/viola-SEC-PERF.sfz: [''ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/all-strings-SOLO-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/all-strings-SOLO-PERF-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/bass-SOLO-PERF-KS-C5.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/bass-SOLO-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/viola-SEC-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/viola-SEC-PERF-KS-C2.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/cello-SEC-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/all-strings-SEC-PERF-staccato-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/harp-KS-C0.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/harp-dampened.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/cello-SEC-PERF-KS-C6.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/all-strings-SEC-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/cello-SEC-PERF-staccato.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/all-strings-SEC-PERF-panned.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/harp-KS-B7.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/all-strings-SEC-PERF.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/bass-SOLO-PERF-KS-C6.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/VPO3-perf/Strings/harp-sustain.sfz: ['ampeg_dynamic']
/zynthian/zynthian-data/soundfonts/sfz/Strings/SCC Expressive Strings/SCC Expressive Strings-Key Switch-CC11.sfz: ['cutoff_smoothcc11']
/zynthian/zynthian-data/soundfonts/sfz/Strings/SCC Expressive Strings/SCC Expressive Strings-Key Switch-CC1.sfz: ['cutoff_smoothcc1']
/zynthian/zynthian-data/soundfonts/sfz/Percussion/AVL_Drumkits_Percussion-1.0/AVL_Drumkits_Percussion-1.0.sfz: ['lochan', 'hichan']
3 Likes

The linux version of Sforzando is preliminary and has issues. On Windows, it’s my sample player of choice. One I bumped into is that it doesn’t handle loops in FLAC files correctly.

We might want to pull it into Zynthian – I suspect that if we did, it might help Plogue by finding issues. But I have no idea how committed to Linux they are at Plogue, especially for a free product that generates very little revenue these days. (I’m guessing that they originally got revenue thanks to Garritan using Plogue Aria/Sforzando, but I have heard that they try not to put too much manpower on it these days.)

It’s definitely proprietary. It’s free, but I believe the license doesn’t allow redistribution, so the best we could offer is a script to download and install it from the Plogue site.

MANY sfz instruments are just that, but SFZ supports very complex features. See https://sfzformat.com

@riban lochan and hichan can be ignored. They’re MIDI channel filtering, which is done a different way on Zynth.

ampeg_dynamic causes the envelope to be recalculated after CC changes, so these affect the sound – but possibly, not in ways that are crucial. It’s also possible that sfizz does this by default.

Keyswitches are also not ideal for pianos. I don’t miss a few keys at the top of an 88-key piano, but (a) many players use shorter keyboards, and (b) other players actually use those notes.

But I also have issues with using CC# for mode switching. On a lot of MIDI keyboards, we have limited options. For example, many of us use a digital piano with few knobs available, and the ones we have, we already use for something.

Frankly, I like the preset page for selecting things like this.

My jRhodes3d sampleset has three presets: the original stereo, mono, and stereo vibrato, and each of these is available with or without velocity crossfade. To me, it makes sense to select these as presets, and the current convention that each .sfz file is a preset is really ideal.

Keyswitch and CC control is necessary for things you need to control during a performance, like selecting articulations.

IMHO, it’s best to stick with this convention, using presets to select the instrument and keyswitch or CC to control during performance. (I admit I don’t follow it rigidly myself. For example, on my stereo version, you can use the mod wheel to control the stereo width, including down to zero to get mono. So, it’s best as a guideline and not a law.)

Minimizing the number of .sfz files just doesn’t make sense to me. Eliminating ones that don’t make sense for Zynth, or to reduce size, is another matter entirely, and absolutely appropriate.

1 Like

Hi @jlearman,

I get your point. My first proposal basically accepted the approach you describe: use presets (separate .sfz files) to select instrument variants, and use keyswitches/CC for things you actually need to control during performance.

Right after that I also suggested an alternative: a single .sfz file, where the user would choose in the Zynthian UI which controller type they use. But when I tried yesterday to quickly adapt the VCO Trumpet, I have to admit it’s quite a pain to keep multiple controller mappings working reliably together — and I suspect my quick-and-dirty edited file still has issues in that area.

So at the moment I also lean towards having separate .sfz files per controller type (e.g. *_kb.sfz, *_ewi.sfz, *_bc.sfz). Also because I definitely don’t plan to start modifying the existing *_kb.sfz files.

1 Like

For each sampleset we select, we need to categorize it as built-in or user-installable. User-installable should be easily added via webconf and bash commands. That is, each should have a script to install it.

The decision whether to host (in Zynth repos) a sampleset and whether it should be pre-loaded are independent.

Of course, we’ll have multiple levels of “hosting.” In some cases, none at all – it’s usable without modification. In other cases, full hosting is needed as there’s no good source for the audio files. In probably most cases, we’ll only host Zynth-specific aspects (as we currently do for most samplesets.) Above, I’m mostly talking about full hosting, where there isn’t a suitable public host.

Samplesets that we host should all follow a set of conventions so that a single simple script can be used to install them (whether that be during the build process or by the user.) The wiki should have a section for this, and we should probably have another discourse thread to discuss. If nobody else does, I’ll probably start one in a few days. (The standards will differ somewhat for partially- and fully-hosted samplesets. They should be compatible, where differences address what’s missing or not.)

The wiki is a great start! However, for the table at the end, I don’t like one line per item. We’ll want a number of grand pianos (possibly with different editors), IMHO at least two built-in and a few more user-installable.

I got the impression someone wants to get rid of categories, and I think that’s a big mistake. One long alpha-sorted list is not nearly as good as the categories like we already have. Hopefully I just misread/misremembered.

I don’t want to see _kb suffix on every sampleset intended for keyboards. I have no problem with suffixes for alternatives. One reason is to avoid changes between Zynth sfz files and original sources, when no changes are necessary.

What I would like for that purpose is a set of checkboxes above the categories, where we could pick what we want included, allowing us to select any number of checkboxes. I like the initial suggestion for “controller types”, and we should have an “other” type for oddballs. If enough of any particular type of oddball appears, we can promote it to a type. That’s to make it easy to add a sampleset for a type of controller we hadn’t thought of, without having to fiddle with the UI.

Can someone please add me as a wiki editor? Or, which discourse category should I post a request on?

Write a private message to @jofemodo

1 Like