first step in creating .sfz files

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

first step in creating .sfz files

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.

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();
             }
     }









------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: first step in creating .sfz files

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 <[hidden email]> wrote:
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();
            }
    }









------------------------------------------------------------------------------
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
[hidden email]
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: first step in creating .sfz files

tbeck
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

On Wed, Jun 28, 2017 at 10:47 AM, Aaron Laws <[hidden email]> wrote:
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 <[hidden email]> wrote:
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();
            }
    }









------------------------------------------------------------------------------
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
[hidden email]
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
[hidden email]
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: first step in creating .sfz files

David Gritter
In reply to this post by Aaron Laws
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



On 06/28/2017 10:47 AM, Aaron Laws wrote:
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 <[hidden email]> wrote:
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.


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: first step in creating .sfz files

David Gritter
In reply to this post by tbeck
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.


On 06/28/2017 06:19 PM, Thomas Beck wrote:
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

On Wed, Jun 28, 2017 at 10:47 AM, Aaron Laws <[hidden email]> wrote:
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 <[hidden email]> wrote:
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.


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: first step in creating .sfz files

Aaron Laws
In reply to this post by David Gritter
On Wed, Jun 28, 2017 at 7:28 PM, David Gritter <[hidden email]> wrote:
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


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

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/jorgan-user
Loading...