sfztools/sfizz

overriding default_path for each sfz mapping

Opened this issue · 2 comments

Discussed in #1231

Originally posted by michael02022 January 19, 2024
Hi, I was testing a concept I had, which is very simple:

rhodes_map.sfz

<group>
<region> sample=rhodes_36.wav key=36
<region> sample=rhodes_37.wav key=37
<region> sample=rhodes_38.wav key=38
<region> sample=rhodes_39.wav key=39
<region> sample=rhodes_40.wav key=40
...

piano_map.sfz

<group>
<region> sample=piano_36.wav key=36
<region> sample=piano_37.wav key=37
<region> sample=piano_38.wav key=38
<region> sample=piano_39.wav key=39
<region> sample=piano_40.wav key=40
...

We have these sfz mappings, only contains <group> and <region> headers. As you can see, no path is given for these samples.

Now, with #include we can call these mappings with the correct path using the <control> header to each them, and under that header, there is a default_path opcode that goes under the called mapping. Each mapping has different default_path value. And it will work correctly in this way using absolute paths. (not tested with relative paths yet)

<control>
#define $USERPATH F:/My SFZs

<master>
ampeg_release=1

<control>
default_path=$USERPATH/Rhodes/Samples/
#include "$USERPATH/Rhodes/rhodes_map.sfz"

<master>
ampeg_release=3

<control>
default_path=$USERPATH/Grand/Samples/
#include "$USERPATH/Grand/piano_map.sfz"

Sforzando loads the samples without problem with this, but in Sfizz doesn't work.

sfizz has some default_path test files already, but does not have one that uses includes and defines:
https://github.com/sfztools/sfizz/blob/develop/tests/TestFiles/default_path.sfz

I performed a quick test with this file:

<control>
#define $USERPATH ../../test/syntax/

<master>
ampeg_release=1

<control>
default_path=$USERPATH/path-a
#include "$USERPATH/basic.sfz"

<master>
ampeg_release=3

<control>
default_path=$USERPATH/path-b
#include "$USERPATH/basic.sfz"

When I run this file through sfizz_preprocessor I get

<?xml version="1.0"?>
<control />
<master>
	<opcode name="ampeg_release" value="1" />
</master>
<control>
	<opcode name="default_path" value="../../test/syntax//path-a" />
</control>
<region>
	<opcode name="sample" value="piano.wav" />
	<opcode name="pitch_keycenter" value="60" />
	<opcode name="lokey" value="58" />
	<opcode name="hikey" value="62" />
	<opcode name="lovel" value="1" />
	<opcode name="hivel" value="20" />
	<opcode name="locc64" value="64" />
	<opcode name="hicc64" value="127" />
</region>
<master>
	<opcode name="ampeg_release" value="3" />
</master>
<control>
	<opcode name="default_path" value="../../test/syntax//path-b" />
</control>
<region>
	<opcode name="sample" value="piano.wav" />
	<opcode name="pitch_keycenter" value="60" />
	<opcode name="lokey" value="58" />
	<opcode name="hikey" value="62" />
	<opcode name="lovel" value="1" />
	<opcode name="hivel" value="20" />
	<opcode name="locc64" value="64" />
	<opcode name="hicc64" value="127" />
</region>

Looks correct no? apart from the double slashes?

I added tests to my JavaScript parser in sfz-tools-core and it outputs the same result as sfizz:
sfzlab/sfz-tools-core@21e71a7

I'm not able to replicate the bug

Note here, this trick won't work if you use absolute paths, if you use relative paths it works in sfizz.

Example: $USERPATH ../..