Discussion:
[jOrgan-user] first step in creating .sfz files
David Gritter
2017-06-28 13:58:58 UTC
Permalink
As a first step in creating .sfz files for organs, the java source
included below will create .sfz files for simple cases. It assumes that
the directory structures and .wav file names are as normally defined for
grand orgue dispositions. It will allow multiple attack samples,
separate release samples, or just a release decay as has been common to
this point in Jorgan dispositions. It will allow one sample per note
.sfz files, or regions in which one sample is spread over several notes.
for such regions a separate text file is used as input defining the
region boundaries and the root note pitch. feel free to copy and
improve on this tool, which includes limited documentation embedded in
the source file. Subsequent posts will illustrate generated .sfz file
examples.

Usage:

paste the source below into a text editor and save as
Sfzfilebuilder.java. On a computer with the java SE SDK installed,
execute the command:

javac Sfzfilebuilder.java.

this will create a file Sfzfilebuilder.class. Copy this to your
working directory where you want the .sfz files created. from a
terminal window in that directory execute the command

java Sfzfilebuilder

you will be asked a series of questions that will define your .sfz file,
and the resulting file will be created.

____________beginning of java file_______________

/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*package sfzfilebuilder;*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;

/**
*
* @author dave gritter
*/
public class Sfzfilebuilder {

/**
* @param args the command line arguments
* @throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
int fn[] = null; /* first note in region*/
int ln[] = null; /* last note in region */
int rn[] = null; /* root note for region */
int vel[] = null;
String notenames[];/* constant string of notenames in wav files*/
String Suffixes[] = null;
String test; /*string for re-use in dialog*/
String separator="";
String reldir="";
boolean writevel;/* write lovel and hivel into regions*/
boolean rel; /* write release regions*/
boolean rep; /* need to write the pitch_keycenter parameter
into regions*/
boolean prfx; /*wave file prefix is used ahead of note number*/
boolean notenm; /* wave file also contains note name*/
notenames = new String[]
{"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
Scanner conin=new Scanner(System.in);
System.out.println("Enter number of desired notes or keyboard
regions");
int notes=conin.nextInt();
System.out.println("enter starting midi note number for samples
(assume keyboard starts at 36");
int strtsmplnote=conin.nextInt(); /*for example some wav
samples start at note number 24*/
System.out.println("do we need to repitch samples within
regions? (Y/N)");
test=conin.next();
if((test.equals("Y"))||(test.equals("y"))){
rep=true;
/*For repitching we assume that we need separate lokey,
hikey and pitch_keycenter
parameters. We also assume that one sample may be spread
across multiple
notes. Therefor, to avoid repetitive entries we ask you to
create a text file
where each line contains the starting note, the ending
note, and the sample note numbers
for the note or region. If we continue to use one sample
per note we can set the starting
note and ending note equal to each other separate with spaces*/
System.out.println("enter full directory/filename info for
region file only filename if in current dir");
String regfile=conin.next();
fn=new int[notes];
ln=new int[notes];
rn=new int[notes];
FileReader regtxt;
regtxt=new FileReader(regfile);
Scanner regsc = new Scanner(new BufferedReader(regtxt));
for (int i=0;i<notes;i++){
fn[i]=regsc.nextInt();
ln[i]=regsc.nextInt();
rn[i]=regsc.nextInt();
}
}
else
rep=false;
/*without re-pitching we assume one sample per note per
Grand Orgue
conventions. Therefor regions only need a key= parameter */
System.out.println("enter number of attack samples 1-N");
int attsmpl=conin.nextInt();
if (attsmpl==1){
writevel=false;
}
else {
System.out.println("enter velocity breakpoint maximums for
each attack");
System.out.println("separate with spaces "+attsmpl+" values
needed");
vel=new int[attsmpl*2+1];
writevel=true;
vel[0]=1;
for (int i=0;i<attsmpl;i++) {
vel[i*2+1]=conin.nextInt();
vel[i*2+2]=vel[i*2+1]+1;
}
}
System.out.println("separate release samples Y/N");
test=conin.next();
if((test.equals("Y"))||(test.equals("y"))){
rel=true;
System.out.println("release directory name in sample
directory");
reldir=conin.next();
}
else {
rel=false;
}
System.out.println("wav file directory name?");
String dirname=conin.next();
System.out.println("wave file prefix, enter XX if none");
String prefix=conin.next();
if(prefix.equals("XX")) prfx=false; else prfx=true;
System.out.println("wave files contain note names Y/N");
test=conin.next();
if((test.equals("Y"))||(test.equals("y")))notenm=true; else
notenm=false;
if(notenm){
System.out.println("enter separator string, XX for none");
separator=conin.next();
if (separator.equals("XX")) separator ="";

}

if(writevel){/* get suffixes for different attack waveform names.*/
System.out.println("enter suffixes for different attack
regions ");
System.out.println(""+attsmpl+" entries needed XX for no
suffix");
Suffixes= new String[attsmpl];
for(int i=0;i<attsmpl;i++){
String suffix=conin.next();
if(suffix.equals("XX")) suffix="";
Suffixes[i]=suffix;
}
}
/* now write the SFZ file start with group to set up the
necessary sound system params*?

*/

/* open file for writing*/
System.out.println("enter output sfz filename without the .sfz
extension");
String filename=conin.next();
PrintStream sfz = new PrintStream(new
FileOutputStream(filename+".sfz"));
sfz.println("<group>");
sfz.println("amp_veltrack=0");/* prevent midi note on velocity
from effecting
amplitude of sound -- velocity is used to select attack sample
*/
sfz.println("ampeg_attack=0.005"); /*ATTACK time for both
attack andrelease waveforms */
if(rel) sfz.println("ampeg_release=0.005");else
sfz.println("ampeg_release=0.1");
/*if release samples are used the release time needs to be the
same as the release sample attack time */

/* iterate in nested loops for note number, attack samples*/
for( int i=0;i<notes;i++){
for(int j=0;j<attsmpl;j++) {
sfz.println();
sfz.println("<region>");
/*print fully qualified attack sample information
directory
prefix
notenumber
separator if notenames are used
notename if notenames are used
suffix, if multiple attacks*/
sfz.print("sample=");
sfz.print(dirname);
sfz.print("/");
if (prfx)sfz.print(prefix);
if(!rep) {
sfz.print(i+strtsmplnote);
}
else{
sfz.print(rn[i]);
}
if(notenm){
sfz.print(separator);
if(rep)
sfz.print(notenames[rn[i]%12]);
else
sfz.print(notenames[i%12]);
}
if(writevel) sfz.print(Suffixes[j]);
sfz.println(".wav");
/* print velocity range if needed*/
if(writevel){
sfz.println("lovel="+vel[j*2]);
sfz.println("hivel="+vel[j*2+1]);
}
if(rep){
sfz.println("lowkey="+(fn[i]));
sfz.println("hikey="+(ln[i]));
sfz.println("pitch_keycenter="+(rn[i]));
}
else {
sfz.println("key="+(i+36));/* region sounds only a
single note*/
}
sfz.println("loop_mode=loop_continuous");
/* now print release region if necessary*/
if(rel){
sfz.println("<region>");
/*print fully qualified attack sample information
directory
prefix
notenumber
separator if notenames are used
notename if notenames are used
suffix, if multiple attacks*/
sfz.print("sample=");
sfz.print(dirname);
sfz.print("/");
sfz.print(reldir);
sfz.print("/");
if (prfx)sfz.print(prefix);
if(!rep) {
sfz.print(i+strtsmplnote);
}
else{
sfz.print(rn[i]);
}
if(notenm){
sfz.print(separator);
if(rep)
sfz.print(notenames[rn[i]%12]);
else
sfz.print(notenames[i%12]);
}
if(writevel) sfz.print(Suffixes[j]);
sfz.println(".wav");
sfz.println("trigger=release");
sfz.println("loop_mode=no_loop");
/* print velocity range if needed*/
if(writevel){
sfz.println("lovel="+vel[j*2]);
sfz.println("hivel="+vel[j*2+1]);
}
if(rep){
sfz.println("lowkey="+(fn[i]));
sfz.println("hikey="+(ln[i])); /*region only sounds
a single note*/
sfz.println("pitch_keycenter="+(rn[i]));
}
else {
sfz.println("key="+(i+36));/* one note per sample*/
}
}
}
}
sfz.flush();
sfz.close();
}
}
Aaron Laws
2017-06-28 14:47:44 UTC
Permalink
Great work! Do you know how to use git? Would you be opposed to me posting
this in a public git repository?

Are you using real sample sets for this work, or just "dummy" sounds...or
no sounds at all?


In Christ,
Aaron Laws
Post by David Gritter
As a first step in creating .sfz files for organs, the java source
included below will create .sfz files for simple cases. It assumes that
the directory structures and .wav file names are as normally defined for
grand orgue dispositions. It will allow multiple attack samples, separate
release samples, or just a release decay as has been common to this point
in Jorgan dispositions. It will allow one sample per note .sfz files, or
regions in which one sample is spread over several notes. for such regions
a separate text file is used as input defining the region boundaries and
the root note pitch. feel free to copy and improve on this tool, which
includes limited documentation embedded in the source file. Subsequent
posts will illustrate generated .sfz file examples.
paste the source below into a text editor and save as
Sfzfilebuilder.java. On a computer with the java SE SDK installed, execute
javac Sfzfilebuilder.java.
this will create a file Sfzfilebuilder.class. Copy this to your working
directory where you want the .sfz files created. from a terminal window in
that directory execute the command
java Sfzfilebuilder
you will be asked a series of questions that will define your .sfz file,
and the resulting file will be created.
____________beginning of java file_______________
/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*package sfzfilebuilder;*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
/**
*
*/
public class Sfzfilebuilder {
/**
*/
public static void main(String[] args) throws FileNotFoundException {
int fn[] = null; /* first note in region*/
int ln[] = null; /* last note in region */
int rn[] = null; /* root note for region */
int vel[] = null;
String notenames[];/* constant string of notenames in wav files*/
String Suffixes[] = null;
String test; /*string for re-use in dialog*/
String separator="";
String reldir="";
boolean writevel;/* write lovel and hivel into regions*/
boolean rel; /* write release regions*/
boolean rep; /* need to write the pitch_keycenter parameter into
regions*/
boolean prfx; /*wave file prefix is used ahead of note number*/
boolean notenm; /* wave file also contains note name*/
notenames = new String[] {"C","C#","D","D#","E","F","F#
","G","G#","A","A#","B"};
Scanner conin=new Scanner(System.in);
System.out.println("Enter number of desired notes or keyboard
regions");
int notes=conin.nextInt();
System.out.println("enter starting midi note number for samples
(assume keyboard starts at 36");
int strtsmplnote=conin.nextInt(); /*for example some wav samples
start at note number 24*/
System.out.println("do we need to repitch samples within regions?
(Y/N)");
test=conin.next();
if((test.equals("Y"))||(test.equals("y"))){
rep=true;
/*For repitching we assume that we need separate lokey, hikey
and pitch_keycenter
parameters. We also assume that one sample may be spread
across multiple
notes. Therefor, to avoid repetitive entries we ask you to
create a text file
where each line contains the starting note, the ending note,
and the sample note numbers
for the note or region. If we continue to use one sample per
note we can set the starting
note and ending note equal to each other separate with spaces*/
System.out.println("enter full directory/filename info for
region file only filename if in current dir");
String regfile=conin.next();
fn=new int[notes];
ln=new int[notes];
rn=new int[notes];
FileReader regtxt;
regtxt=new FileReader(regfile);
Scanner regsc = new Scanner(new BufferedReader(regtxt));
for (int i=0;i<notes;i++){
fn[i]=regsc.nextInt();
ln[i]=regsc.nextInt();
rn[i]=regsc.nextInt();
}
}
else
rep=false;
/*without re-pitching we assume one sample per note per Grand
Orgue
conventions. Therefor regions only need a key= parameter */
System.out.println("enter number of attack samples 1-N");
int attsmpl=conin.nextInt();
if (attsmpl==1){
writevel=false;
}
else {
System.out.println("enter velocity breakpoint maximums for each
attack");
System.out.println("separate with spaces "+attsmpl+" values
needed");
vel=new int[attsmpl*2+1];
writevel=true;
vel[0]=1;
for (int i=0;i<attsmpl;i++) {
vel[i*2+1]=conin.nextInt();
vel[i*2+2]=vel[i*2+1]+1;
}
}
System.out.println("separate release samples Y/N");
test=conin.next();
if((test.equals("Y"))||(test.equals("y"))){
rel=true;
System.out.println("release directory name in sample
directory");
reldir=conin.next();
}
else {
rel=false;
}
System.out.println("wav file directory name?");
String dirname=conin.next();
System.out.println("wave file prefix, enter XX if none");
String prefix=conin.next();
if(prefix.equals("XX")) prfx=false; else prfx=true;
System.out.println("wave files contain note names Y/N");
test=conin.next();
if((test.equals("Y"))||(test.equals("y")))notenm=true; else
notenm=false;
if(notenm){
System.out.println("enter separator string, XX for none");
separator=conin.next();
if (separator.equals("XX")) separator ="";
}
if(writevel){/* get suffixes for different attack waveform names.*/
System.out.println("enter suffixes for different attack
regions ");
System.out.println(""+attsmpl+" entries needed XX for no
suffix");
Suffixes= new String[attsmpl];
for(int i=0;i<attsmpl;i++){
String suffix=conin.next();
if(suffix.equals("XX")) suffix="";
Suffixes[i]=suffix;
}
}
/* now write the SFZ file start with group to set up the
necessary sound system params*?
*/
/* open file for writing*/
System.out.println("enter output sfz filename without the .sfz
extension");
String filename=conin.next();
PrintStream sfz = new PrintStream(new
FileOutputStream(filename+".sfz"));
sfz.println("<group>");
sfz.println("amp_veltrack=0");/* prevent midi note on velocity
from effecting
amplitude of sound -- velocity is used to select attack sample
*/
sfz.println("ampeg_attack=0.005"); /*ATTACK time for both attack
andrelease waveforms */
if(rel) sfz.println("ampeg_release=0.005");else
sfz.println("ampeg_release=0.1");
/*if release samples are used the release time needs to be the
same as the release sample attack time */
/* iterate in nested loops for note number, attack samples*/
for( int i=0;i<notes;i++){
for(int j=0;j<attsmpl;j++) {
sfz.println();
sfz.println("<region>");
/*print fully qualified attack sample information
directory
prefix
notenumber
separator if notenames are used
notename if notenames are used
suffix, if multiple attacks*/
sfz.print("sample=");
sfz.print(dirname);
sfz.print("/");
if (prfx)sfz.print(prefix);
if(!rep) {
sfz.print(i+strtsmplnote);
}
else{
sfz.print(rn[i]);
}
if(notenm){
sfz.print(separator);
if(rep)
sfz.print(notenames[rn[i]%12]);
else
sfz.print(notenames[i%12]);
}
if(writevel) sfz.print(Suffixes[j]);
sfz.println(".wav");
/* print velocity range if needed*/
if(writevel){
sfz.println("lovel="+vel[j*2]);
sfz.println("hivel="+vel[j*2+1]);
}
if(rep){
sfz.println("lowkey="+(fn[i]));
sfz.println("hikey="+(ln[i]));
sfz.println("pitch_keycenter="+(rn[i]));
}
else {
sfz.println("key="+(i+36));/* region sounds only a
single note*/
}
sfz.println("loop_mode=loop_continuous");
/* now print release region if necessary*/
if(rel){
sfz.println("<region>");
/*print fully qualified attack sample information
directory
prefix
notenumber
separator if notenames are used
notename if notenames are used
suffix, if multiple attacks*/
sfz.print("sample=");
sfz.print(dirname);
sfz.print("/");
sfz.print(reldir);
sfz.print("/");
if (prfx)sfz.print(prefix);
if(!rep) {
sfz.print(i+strtsmplnote);
}
else{
sfz.print(rn[i]);
}
if(notenm){
sfz.print(separator);
if(rep)
sfz.print(notenames[rn[i]%12]);
else
sfz.print(notenames[i%12]);
}
if(writevel) sfz.print(Suffixes[j]);
sfz.println(".wav");
sfz.println("trigger=release");
sfz.println("loop_mode=no_loop");
/* print velocity range if needed*/
if(writevel){
sfz.println("lovel="+vel[j*2]);
sfz.println("hivel="+vel[j*2+1]);
}
if(rep){
sfz.println("lowkey="+(fn[i]));
sfz.println("hikey="+(ln[i])); /*region only sounds a
single note*/
sfz.println("pitch_keycenter="+(rn[i]));
}
else {
sfz.println("key="+(i+36));/* one note per sample*/
}
}
}
}
sfz.flush();
sfz.close();
}
}
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
jOrgan-user mailing list
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Thomas Beck
2017-06-28 22:19:21 UTC
Permalink
Hi David,

Thanks for this. I'm a little confused, though. I thought the sfz test case
was going to use the real-life example of the Burea choir organ. I don't
recognize the directory structure or wave file names from these examples.

Tom
Post by Aaron Laws
Great work! Do you know how to use git? Would you be opposed to me posting
this in a public git repository?
Are you using real sample sets for this work, or just "dummy" sounds...or
no sounds at all?
In Christ,
Aaron Laws
Post by David Gritter
As a first step in creating .sfz files for organs, the java source
included below will create .sfz files for simple cases. It assumes that
the directory structures and .wav file names are as normally defined for
grand orgue dispositions. It will allow multiple attack samples, separate
release samples, or just a release decay as has been common to this point
in Jorgan dispositions. It will allow one sample per note .sfz files, or
regions in which one sample is spread over several notes. for such regions
a separate text file is used as input defining the region boundaries and
the root note pitch. feel free to copy and improve on this tool, which
includes limited documentation embedded in the source file. Subsequent
posts will illustrate generated .sfz file examples.
paste the source below into a text editor and save as
Sfzfilebuilder.java. On a computer with the java SE SDK installed, execute
javac Sfzfilebuilder.java.
this will create a file Sfzfilebuilder.class. Copy this to your working
directory where you want the .sfz files created. from a terminal window in
that directory execute the command
java Sfzfilebuilder
you will be asked a series of questions that will define your .sfz file,
and the resulting file will be created.
____________beginning of java file_______________
/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*package sfzfilebuilder;*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
/**
*
*/
public class Sfzfilebuilder {
/**
*/
public static void main(String[] args) throws FileNotFoundException {
int fn[] = null; /* first note in region*/
int ln[] = null; /* last note in region */
int rn[] = null; /* root note for region */
int vel[] = null;
String notenames[];/* constant string of notenames in wav files*/
String Suffixes[] = null;
String test; /*string for re-use in dialog*/
String separator="";
String reldir="";
boolean writevel;/* write lovel and hivel into regions*/
boolean rel; /* write release regions*/
boolean rep; /* need to write the pitch_keycenter parameter into
regions*/
boolean prfx; /*wave file prefix is used ahead of note number*/
boolean notenm; /* wave file also contains note name*/
notenames = new String[] {"C","C#","D","D#","E","F","F#
","G","G#","A","A#","B"};
Scanner conin=new Scanner(System.in);
System.out.println("Enter number of desired notes or keyboard
regions");
int notes=conin.nextInt();
System.out.println("enter starting midi note number for samples
(assume keyboard starts at 36");
int strtsmplnote=conin.nextInt(); /*for example some wav samples
start at note number 24*/
System.out.println("do we need to repitch samples within regions?
(Y/N)");
test=conin.next();
if((test.equals("Y"))||(test.equals("y"))){
rep=true;
/*For repitching we assume that we need separate lokey, hikey
and pitch_keycenter
parameters. We also assume that one sample may be spread
across multiple
notes. Therefor, to avoid repetitive entries we ask you to
create a text file
where each line contains the starting note, the ending note,
and the sample note numbers
for the note or region. If we continue to use one sample per
note we can set the starting
note and ending note equal to each other separate with spaces*/
System.out.println("enter full directory/filename info for
region file only filename if in current dir");
String regfile=conin.next();
fn=new int[notes];
ln=new int[notes];
rn=new int[notes];
FileReader regtxt;
regtxt=new FileReader(regfile);
Scanner regsc = new Scanner(new BufferedReader(regtxt));
for (int i=0;i<notes;i++){
fn[i]=regsc.nextInt();
ln[i]=regsc.nextInt();
rn[i]=regsc.nextInt();
}
}
else
rep=false;
/*without re-pitching we assume one sample per note per Grand
Orgue
conventions. Therefor regions only need a key= parameter */
System.out.println("enter number of attack samples 1-N");
int attsmpl=conin.nextInt();
if (attsmpl==1){
writevel=false;
}
else {
System.out.println("enter velocity breakpoint maximums for
each attack");
System.out.println("separate with spaces "+attsmpl+" values
needed");
vel=new int[attsmpl*2+1];
writevel=true;
vel[0]=1;
for (int i=0;i<attsmpl;i++) {
vel[i*2+1]=conin.nextInt();
vel[i*2+2]=vel[i*2+1]+1;
}
}
System.out.println("separate release samples Y/N");
test=conin.next();
if((test.equals("Y"))||(test.equals("y"))){
rel=true;
System.out.println("release directory name in sample
directory");
reldir=conin.next();
}
else {
rel=false;
}
System.out.println("wav file directory name?");
String dirname=conin.next();
System.out.println("wave file prefix, enter XX if none");
String prefix=conin.next();
if(prefix.equals("XX")) prfx=false; else prfx=true;
System.out.println("wave files contain note names Y/N");
test=conin.next();
if((test.equals("Y"))||(test.equals("y")))notenm=true; else
notenm=false;
if(notenm){
System.out.println("enter separator string, XX for none");
separator=conin.next();
if (separator.equals("XX")) separator ="";
}
if(writevel){/* get suffixes for different attack waveform names.*/
System.out.println("enter suffixes for different attack
regions ");
System.out.println(""+attsmpl+" entries needed XX for no
suffix");
Suffixes= new String[attsmpl];
for(int i=0;i<attsmpl;i++){
String suffix=conin.next();
if(suffix.equals("XX")) suffix="";
Suffixes[i]=suffix;
}
}
/* now write the SFZ file start with group to set up the
necessary sound system params*?
*/
/* open file for writing*/
System.out.println("enter output sfz filename without the .sfz
extension");
String filename=conin.next();
PrintStream sfz = new PrintStream(new
FileOutputStream(filename+".sfz"));
sfz.println("<group>");
sfz.println("amp_veltrack=0");/* prevent midi note on velocity
from effecting
amplitude of sound -- velocity is used to select attack sample
*/
sfz.println("ampeg_attack=0.005"); /*ATTACK time for both attack
andrelease waveforms */
if(rel) sfz.println("ampeg_release=0.005");else
sfz.println("ampeg_release=0.1");
/*if release samples are used the release time needs to be the
same as the release sample attack time */
/* iterate in nested loops for note number, attack samples*/
for( int i=0;i<notes;i++){
for(int j=0;j<attsmpl;j++) {
sfz.println();
sfz.println("<region>");
/*print fully qualified attack sample information
directory
prefix
notenumber
separator if notenames are used
notename if notenames are used
suffix, if multiple attacks*/
sfz.print("sample=");
sfz.print(dirname);
sfz.print("/");
if (prfx)sfz.print(prefix);
if(!rep) {
sfz.print(i+strtsmplnote);
}
else{
sfz.print(rn[i]);
}
if(notenm){
sfz.print(separator);
if(rep)
sfz.print(notenames[rn[i]%12]);
else
sfz.print(notenames[i%12]);
}
if(writevel) sfz.print(Suffixes[j]);
sfz.println(".wav");
/* print velocity range if needed*/
if(writevel){
sfz.println("lovel="+vel[j*2]);
sfz.println("hivel="+vel[j*2+1]);
}
if(rep){
sfz.println("lowkey="+(fn[i]));
sfz.println("hikey="+(ln[i]));
sfz.println("pitch_keycenter="+(rn[i]));
}
else {
sfz.println("key="+(i+36));/* region sounds only a
single note*/
}
sfz.println("loop_mode=loop_continuous");
/* now print release region if necessary*/
if(rel){
sfz.println("<region>");
/*print fully qualified attack sample information
directory
prefix
notenumber
separator if notenames are used
notename if notenames are used
suffix, if multiple attacks*/
sfz.print("sample=");
sfz.print(dirname);
sfz.print("/");
sfz.print(reldir);
sfz.print("/");
if (prfx)sfz.print(prefix);
if(!rep) {
sfz.print(i+strtsmplnote);
}
else{
sfz.print(rn[i]);
}
if(notenm){
sfz.print(separator);
if(rep)
sfz.print(notenames[rn[i]%12]);
else
sfz.print(notenames[i%12]);
}
if(writevel) sfz.print(Suffixes[j]);
sfz.println(".wav");
sfz.println("trigger=release");
sfz.println("loop_mode=no_loop");
/* print velocity range if needed*/
if(writevel){
sfz.println("lovel="+vel[j*2]);
sfz.println("hivel="+vel[j*2+1]);
}
if(rep){
sfz.println("lowkey="+(fn[i]));
sfz.println("hikey="+(ln[i])); /*region only sounds a
single note*/
sfz.println("pitch_keycenter="+(rn[i]));
}
else {
sfz.println("key="+(i+36));/* one note per sample*/
}
}
}
}
sfz.flush();
sfz.close();
}
}
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
jOrgan-user mailing list
https://lists.sourceforge.net/lists/listinfo/jorgan-user
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
jOrgan-user mailing list
https://lists.sourceforge.net/lists/listinfo/jorgan-user
David Gritter
2017-06-28 23:34:11 UTC
Permalink
yes, I plan to use this tool to create .sfzs for the burea choir organ.
However the region structure for this organ is quite complicated and
unusual, so cut and paste methods didn't seem very efficient; hence the
java tool. the samples i sent are just test cases to show that the
program is working as intended and to allow people to provide feedback
on what might need to be different in the generated .sfz files.
Post by Thomas Beck
Hi David,
Thanks for this. I'm a little confused, though. I thought the sfz test
case was going to use the real-life example of the Burea choir organ.
I don't recognize the directory structure or wave file names from
these examples.
Tom
Great work! Do you know how to use git? Would you be opposed to me
posting this in a public git repository?
Are you using real sample sets for this work, or just "dummy"
sounds...or no sounds at all?
In Christ,
Aaron Laws
On Wed, Jun 28, 2017 at 9:58 AM, David Gritter
As a first step in creating .sfz files for organs, the java
source included below will create .sfz files for simple
cases. It assumes that the directory structures and .wav file
names are as normally defined for grand orgue dispositions.
It will allow multiple attack samples, separate release
samples, or just a release decay as has been common to this
point in Jorgan dispositions. It will allow one sample per
note .sfz files, or regions in which one sample is spread over
several notes. for such regions a separate text file is used
as input defining the region boundaries and the root note
pitch. feel free to copy and improve on this tool, which
includes limited documentation embedded in the source file.
Subsequent posts will illustrate generated .sfz file examples.
David Gritter
2017-06-28 23:28:04 UTC
Permalink
I don't have any problem with you posting this to a git repository. I
believe nebeans, which I use for java development has some form of git
support built in. Probably you want to substitute a gpl license header
for the license header in the file I copied into the original email

The java program itself has no interaction with real sample sets. Rather
you set up a directory structure of wav files manually, or start with
one created for hauptwerk/grandorgue and run the java program
repeatedly, once for each stop, and answer the coimmand line questions
to describe the wav directory structure so the .sfz files can be
created. subsequent loading of the sfz file into your chosen sampler
engine should then cause the sampler to interact properly with the .wav
files and directories
Post by Aaron Laws
Great work! Do you know how to use git? Would you be opposed to me
posting this in a public git repository?
Are you using real sample sets for this work, or just "dummy"
sounds...or no sounds at all?
In Christ,
Aaron Laws
On Wed, Jun 28, 2017 at 9:58 AM, David Gritter
As a first step in creating .sfz files for organs, the java source
included below will create .sfz files for simple cases. It
assumes that the directory structures and .wav file names are as
normally defined for grand orgue dispositions. It will allow
multiple attack samples, separate release samples, or just a
release decay as has been common to this point in Jorgan
dispositions. It will allow one sample per note .sfz files, or
regions in which one sample is spread over several notes. for such
regions a separate text file is used as input defining the region
boundaries and the root note pitch. feel free to copy and improve
on this tool, which includes limited documentation embedded in the
source file. Subsequent posts will illustrate generated .sfz file
examples.
Aaron Laws
2017-06-29 17:52:14 UTC
Permalink
Post by David Gritter
I don't have any problem with you posting this to a git repository. I
believe nebeans, which I use for java development has some form of git
support built in. Probably you want to substitute a gpl license header for
the license header in the file I copied into the original email
Here it is: https://sourceforge.net/p/sfztool/code/ci/master/tree/

I'll be happy to add you as a Developer to the project (then you can
commit, etc.), but I'll need your SourceForge username. I have a couple
changes I'd like to make in future commits. Of course, there is no need to
think of this as "the" home for this software: it's free software, so
anyone can feel free to fork and separately maintain, etc., etc.

Thanks for sharing!

In Christ,
Aaron Laws

Loading...