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 _______________________________________________ Linux-audio-dev mailing list [email protected] http://lists.linuxaudio.org/mailman/listinfo/linux-audio-dev
