[LAD] [Faudiostream-devel] Prototyping algorithms and ideas

Yann Orlarey orlarey at free.fr
Thu Jan 31 17:29:58 UTC 2008


Hi Fons,

Thanks for your useful and constructive comments. I have updated the 
jack-gtk.cpp architecture file with your suggested main. It provides a 
flexible solution that should make both the auto-connection and 
manual-connection people happy ;-) Moreover it solves the unique name 
problem.

Fons Adriaensen a écrit :
> Hi Yann,
>
>   
>> Here is a quick solution using Faust :
>>
>> ...
>> A fully functional jack application can be easily generated using the
>> faust2jack command or by pasting the above code in the online faust
>> compiler (http://faust.grame.fr). The performances on my Vaio laptop  
>> (Intel
>> Core 2 CPU  T7400  @ 2.16GHz) is approximately of 2%.
>>     
>
> Many thanks for this. I'm very happy you point me back
> to Faust, as despite the comments below I am really
> impressed by what it achieves. Enough to organise a
> demo yesterday afternoon for two of the researchers
> I work with. They are not programmers, but both will
> start learning to use Faust.
>   
Great ! Benvenuti ! If they have programming questions (I am sure pretty 
they will have some at the beginning ;-)) they are welcome, as well as 
suggestions and contributions.
> Here are my comments, some of them posted before.
>
> 1. The auto-connection issue. If I would install (or
> some day, update) Faust at home or at my normal working
> place, build the examples to test the installation, and
> run 'osc', this would send a continuous, maximum level,
> 1kHz signal to a power amp feeding an HF speaker that
> doesn't much like signals of this frequency, and even
> less at a power level at least 20 dB above its maximum
> continuous rating. It would be destroyed instantly, and
> I would be happy to escape without permanent hearing
> damage. Please don't assume you can safely connect to
> the first N physical ports. At least make it an option,
> and one that needs explicit user action to be enabled.
> The code attached below solves this.
>
> 2. It's not possible to run a more than one instance
> of a JACK client since all instances have the same
> name, there is no -name option, and they don't use
> the API that automatically generates unique names.
> This also is solved by the code attached below.
>   
As I said above I have update the CVS with the revised jack-gtk.cpp 
architecture file. The faust server is not updated yet, but it will be 
soon...
> 3. All the recursive filters I tested will generate
> denormals if the input is stopped or disconnected.
> On Intel systems this can easily push the CPU load
> up to crash levels. Solving this requires changes
> to all the Faust sources defining these filters.
> BTW, some other systems, e.g. SC3, have the same
> problem.
>   
This is a real problem but it should be solved on modern intel cpu by 
enabling the FTZ mode.
> 4. The fdelay() functions are not usable for the
> application I posted. All of them have significant
> HF loss if the delay is not integer, and as a result,
> will generate amplitude and maybe also phase modulation
> if the delay value is not static. Strangely, fdelay4()
> is not any better than fdelay2(), and fdelay3() is even
> worse.
>   
Is fdelay *that* bad or do you have a very demanding application ? For the worst cases (x.5 delays) the amplitude response for fdelay4 is down about 2 dB at 15 kHz and 7 dB at 20 kHz (for a 44.1 kHz sampling rate). 
 
This is consistent with your observed 6 dB drop at 20 kHz for a 48 kHz sampling rate. But please note that all the gain drop is concentrated at very high frequencies.  Moreover, with a sampling rate of 96 kHz instead of 48 KHz, the gain falls to only -1/4 dB at 20 KHz.

BTW, Julius has updated 'filter.lib' to correct one of the coefficients of fdelay2 and added Thiran allpass interpolators (http://ccrma.stanford.edu/~jos/pasp/Thiran_Allpass_Interpolators.html) with very flat frequency response.


> 5. There may be quality issues with some of the libs.
> The 'bandfilter' for example behaves very strangely.
>   
That's right, we should revise it. I must confess that until recently 
most of our development efforts have been put on the compiler and quite 
few on the libraries. But with a growing community things are changing...
>
> Alternative main() for jack-gtk.
>
> The code below solves two problems.
>
> 1. Auto-connection of ports requires a one-time user
> action. Ports will be connected only if the environment
> variables FAUST2JACK_INPUTS and FAUST2JACK_OUTPUTS are
> defined, e.g. in ~/.bash_profile. They should be defined
> as e.g.
>
> export FAUST2JACK_INPUTS=system:capture_%d
> export FAUST2JACK_OUTPUTS=system:playback_%d
>
> Both are used as format strings in snprintf().
>
> 2. Use jack_client_open() instead of jack_client_new().
> This will automatically generate a unique client name
> in case there is a conflict. Creation of the UI is
> delayed until the JACK connection is established, so
> the correct name will also be shown in the window title.
>
>
> Ciao,
>
>
> --------------------------------------------------------------
>
> int main(int argc, char *argv[] )
> {
> 	//gtk_init (&argc, &argv);
> 	
> 	UI* 				interface;
> 	jack_client_t*			client;	
> 	char                            buf [256];
> 	char				rcfilename[256];
>         jack_status_t                   jackstat;
> 	char                            *home;
> 	char                            *pname;
> 	char                            *jname;
>
> 	jname = basename (argv [0]);
>         client = jack_client_open (jname, (jack_options_t) 0,  
> &jackstat);
>         if (client == 0) {
>             fprintf (stderr, "Can't connect to JACK, is the server  
> running ?\n");
>             exit (1);
>         }
>         if (jackstat & JackNameNotUnique) {
> 	    jname = jack_get_client_name (client);
>         }
>
>         jack_set_process_callback(client, process, 0);
> 	jack_set_sample_rate_callback(client, srate, 0);
> 	jack_on_shutdown(client, jack_shutdown, 0);
> 	
> 	gNumInChans = DSP.getNumInputs();
> 	gNumOutChans = DSP.getNumOutputs();
> 	
> 	for (int i = 0; i < gNumInChans; i++) {
> 	    snprintf(buf, 256, "in_%d", i);
> 	    input_ports[i] = jack_port_register(client, buf,  
> JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
> 	}
> 	for (int i = 0; i < gNumOutChans; i++) {
> 	    snprintf(buf, 256, "out_%d", i);
> 	    output_ports[i] = jack_port_register(client, buf,  
> JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
> 	}
> 	
>         interface = new GTKUI (jname, &argc, &argv);
> 	DSP.init(jack_get_sample_rate(client));
> 	DSP.buildUserInterface(interface);
>
> 	home = getenv ("HOME");
> 	if (home == 0) home = ".";
>         snprintf(rcfilename, 256, "%s/.%src", home, jname);
> 	interface->recallState(rcfilename);
>
> 	if (jack_activate(client)) {
> 	    fprintf(stderr, "Can't activate JACK client\n");
> 	    return 1;
> 	}
> 	
> 	pname = getenv("FAUST2JACK_INPUTS");
>         if (pname && *pname) {
>             for (int i = 0; i < gNumInChans; i++) {
> 	        snprintf(buf, 256, pname, i + 1);
>                 jack_connect(client, buf,  
> jack_port_name(input_ports[i]));
>             }
>         }
>
> 	pname = getenv("FAUST2JACK_OUTPUTS");
>         if (pname && *pname) {
>             for (int i = 0; i < gNumOutChans; i++) {
> 	        snprintf(buf, 256, pname, i + 1);
>                 jack_connect(client, jack_port_name(output_ports[i]),  
> buf);
>             } 		
>         }
> 	
> 	interface->run();
> 	jack_deactivate(client);
> 	
> 	for (int i = 0; i < gNumInChans; i++) {
> 	    jack_port_unregister(client, input_ports[i]);
> 	}
> 	for (int i = 0; i < gNumOutChans; i++) {
> 	    jack_port_unregister(client, output_ports[i]);
> 	}
> 	
> 	jack_client_close(client);
> 	interface->saveState(rcfilename);
> 		
>   	return 0;
> }
>
>
> --------------------------------------------------------------
>
>
>   
Thanks again !

Cheers

Yann



More information about the Linux-audio-dev mailing list