Gambas-it

Gambas3 => Programmazione => Topic aperto da: vuott - 21 Febbraio 2014, 16:49:48

Titolo: Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 21 Febbraio 2014, 16:49:48
Come creare un semplicissimo Client del server audio Jack Audio Connection Kit:

https://www.gambas-it.org/wiki/index.php/Creare_un_Client_di_Jack_con_le_funzioni_esterne_del_API_di_libjack
Titolo: Re: Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 21 Febbraio 2014, 18:27:27
molto interessante vuott ....

da un po' di tempo cercavo uno spunto per iniziare un progetto basao su Jack .... appena andato in pensione ne riparliamo :D
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 24 Febbraio 2016, 23:41:00
ciao VUOTT, ben ritrovato :D

Allora ricapitolando, prendo un editor di testo e ci metto il codice del tuo esempio C ... chiamato come nel tuo esempio  jk.c

Ora ho strasformato il file jk.c in un file oggetto jk.o con:
gcc -fPIC -Wall -g -c jk.c

PS: prima ho installato le librerie di jack server 2 con:  sudo apt-get install libjack-jackd2-dev

A questo punto come proseguo? Da quello che leggo (http://www.gambas-it.org/wiki/index.php?title=Creare_una_Libreria_condivisa_(Shared_Library)_.so) dovrei usare un comando tipo:
gcc -g -shared -Wl,-soname,libprimo.so.0 -o libprimo.so.0.0 primo.o -lc

per generare la jk.so .... ma ... devo usare la libreria condivisa "vera" di jack? Ovvero la riga e' :
gcc -g -shared -Wl,-soname,libjack.so.0 -o jk.so.0.0 jk.o -lc

????


oppure (per avere come output un file .so) uso questo comando?:
gcc -g -shared -Wl,-soname,libjack.so.0 -o jk.so jk.o -lc

in C so veramente una mezza ..... :bad:
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 24 Febbraio 2016, 23:46:54
No, è molto più semplice la cosa: in un editor di testo incolli il codice C e salvi il testo ad esempio nella cartella /tmp con il nome jk.c .

In tal caso nel codice Gambas dovrai solo cambiare la riga:
 Shell "gcc -o  /tmp/libjk.so " & Application.Path &/ "jk.c -shared -fPIC -ljack"

con questa nuova:
Codice: [Seleziona]
Shell "gcc -o  /tmp/libjk.so /tmp/jk.c -shared -fPIC -ljack"

Sarà questa riga, appunto, a creare la libreria esterna dinamica condivisa .so ad hoc .

Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 25 Febbraio 2016, 00:13:34
Perfetto!

il fatto di usare gli spazi nella cartella del progetto gambas non aiutava ... :D
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 25 Febbraio 2016, 00:23:52
Mooooolto bene !!!    :D

Ho variato il codice facilitando la creazione del sorgente della libreria ad hoc direttamente da Gambas.
Provalo e fammi sapere se funziona ugualmente.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 25 Febbraio 2016, 11:19:29
Perfetto! Funziona benissimo :D

Pero' nel wiki la sezione relativa al codice C e' rimasta un po' confusa ..... magari sarebbe da fare riferimento al fatto che il codice c e' incluso nella procedura CreaLibjk dell'applicazione gambas.


Ho fatto qualche modifica "duplicando" le porte di in e out:
Codice: [Seleziona]
Private input_port_right As Pointer   'AGGIUNTA PER LO STEREO
Private output_port_right As Pointer  'AGGIUNTA PER LO STEREO
nelle dichiarazioni ...

e
Codice: [Seleziona]
input_port_right = jack_port_register(client, "input_2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)         'AGGIUNTA PER LO STEREO
output_port_right = jack_port_register(client, "output_2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)      'AGGIUNTA PER LO STEREO
If (input_port_right = 0) Or (output_port_right = 0) Then Print "Nessuna porta di Jack disponibile !"         'AGGIUNTA PER LO STEREO

ed effettivamente jack riconoscie le porte di in e out ....

Ma suppongo che dovro' lavorare su CreaLibjk per avere il feedback audio come succede sul canale left ......


Codice: [Seleziona]
  File.Save("/tmp/jk.c", "#include <string.h>\n" &
           "#include <jack/jack.h>" &
           "\n\n" &
           "jack_port_t *input_port_left;\n" &
           "jack_port_t *input_port_right;\n" &     'AGGIUNTA PER LO STEREO
           "jack_port_t  *output_port_left;\n" &
           "jack_port_t  *output_port_right;\n" &   'AGGIUNTA PER LO STEREO
           "jack_client_t *client;" &
           "\n\n" &
           "int process (jack_nframes_t, void *);" &
           "\n\n" &
         "void principale (jack_client_t *cl, jack_port_t *it, jack_port_t *ot) {\n" &
           "   client = cl;\n" &
           "   input_port_left = it;\n" &
           "   input_port_right = it;\n" &      'AGGIUNTA PER LO STEREO
           "   output_port_left = ot;\n" &
           "   output_port_right = ot;\n\n" &     'AGGIUNTA PER LO STEREO
           "   jack_set_process_callback (client, process, 0);\n}" &
           "\n\n" &
         "int process (jack_nframes_t nframes, void *arg) {\n"
           "   jack_default_audio_sample_t *in, *out;\n" &
           "   in = jack_port_get_buffer (input_port_left, nframes);\n" &
           "   out = jack_port_get_buffer (output_port_left, nframes);\n\n" &
           "   memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes);\n\n" &
           "   return 0;\n}\n")


manca qualcosa in in e out .....
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 25 Febbraio 2016, 14:20:58
se inputport  e outputport le trasformo in inputport_left e inputport_right e outputport_left e outputport_right .... Che definisco opportunamente, posso gestire un client stereo?

Quelle sono semplicemente delle variabili di tipo Puntatore.
Suppongo che l'effetto stereo sia legato solo ai dati trasmessi (ad esempio un file audio wav di due canali è sempre comunque un unico file).
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 25 Febbraio 2016, 14:35:51
penso che jack lavori sempre in mono ... stereo sono sue jack mono accoppiati ....
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 25 Febbraio 2016, 14:48:38
penso che jack lavori sempre in mono
Si, lavora in seriale


stereo sono sue jack mono accoppiati ....
Ah, ora ho compreso meglio ciò che intendevi dire.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 25 Febbraio 2016, 16:36:33
.... magari sarebbe da fare riferimento al fatto che il codice c e' incluso nella procedura CreaLibjk dell'applicazione gambas.
Grazie, ho apportato la precisazione.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 25 Febbraio 2016, 19:09:31
Scrivo dal cellulare quindi non ho a portata di mano il codice ...

Ma mi sembra di notare che l'ascolto di quello che dico al microfono (solo un canale), derivi dal fatto che faccio un memcopy da in su out.
Ma per aggiungere una seconda procedura di callback sul canale destro dove devo metterlo nel pezzo in c?
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 25 Febbraio 2016, 19:21:59
Ma per aggiungere una seconda procedura di callback sul canale destro dove devo metterlo nel pezzo in c?
Ritengo di sì, poiché la chiamata alla funzione di callback avviene nel codice C della libreria .so da noi appositamente creata.
Si pone, a mio avviso, anche il problema di "cosa" viene passato  da Gambas alla funzione chiamata "principale" della nostra libreria .so.

...sarebbe utile magari fare anche una ricerca su un eventuale esempio in C di gestione stereo. 
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 25 Febbraio 2016, 21:21:00
...ci sarebbe da raddoppiare alcune righe del codice Gambas, cambiando opportunamente i nomi delle porte e di alcune variabili... per esempio aggiungere le righe per input_2 e così via insomma.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 26 Febbraio 2016, 00:30:17
Domani dall'ufficio carico le mie modifiche ..  Artigianali .... E provo a googolare un po di esempi in C ...
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 26 Febbraio 2016, 15:18:08
Ciao,
credo di aver risolto.
Ti ho inviato l'intero codice come messaggio privato.

Verificalo e fammi sapere.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 12 Novembre 2016, 13:53:47
... con molta calma torno alla creazione del client jack con gambas :D

Come solito VUOTT e' stato risolutivo.

Ci sono delle imprecisioni nel wiki rispetto al codice definitivo scritto da VUOTT e (se posso) modifichero' il wiki lunedi'.

In allegato una piccola applicazione che rappresenta quel che VUOT ha messo in chiaro con grande perizia.

Ora l'idea dell'applicativo "orecchia" e' intercettare il volume del segnale in ingresso per capire se c'e' silenzio o meno.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 12 Novembre 2016, 14:57:00
Ho provato il tuo applicativo con un microfono, ma appena lo attivo, mi dà come un rumore di ritorno a ciclo continuo.    :-\ 
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 14 Novembre 2016, 12:09:07
potrebbe essere un larsen?
cioe' manda in out quel che entra e lo rimanda su se stesso?

per ora ho praticamente riciclato il tuo wiki nello scheletro di un programmino che "fara'" da "orecchio".

di suo (ora) il programma fa anche le connessioni di jack, dall'ingresso all'usicita, ma pensavo di eliminarle e demandare il compito all'utente in fase di setup delle connessioni su jack (si puo' richiamare un patch panel pre programmato).

Ora sto studiando il codice in allegato per vedere come estrarre da jack informazioni sull'energia del segnale audio:
Codice: [Seleziona]
/* Pick the jack process method */
if (meter_type == MET_VU) {
init_buffers_rms();
jack_set_process_callback(client, process_rms, 0);
} else if (meter_type == MET_JF || meter_type == MET_SCO) {
jack_set_process_callback(client, process_ring, 0);
} else {
jack_set_process_callback(client, process_peak, 0);
}
// This is used to maually save the session, but the auto stuff
// does a better job anyway. Just here for testing
//jack_set_store_callback(client, store, NULL);

if (jack_activate(client)) {
fprintf (stderr, "cannot activate client");
exit(1);
}


che dovrebbe fare riferimento a questo:
http://jackaudio.org/files/docs/html/group__ClientCallbacks.html#gafb5ec9fb4b736606d676c135fb97888b (http://jackaudio.org/files/docs/html/group__ClientCallbacks.html#gafb5ec9fb4b736606d676c135fb97888b)

suppongo che per esempio "process_rms" sai una costante, un puntatore che dice al call back di ritornare (con una funzione interna delle api di jack) il livello RMS del segnale audio ... ma in internet non sono riuscito a trovare alcun riferimento ....
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 14 Novembre 2016, 18:01:43
potrebbe essere un larsen?
cioe' manda in out quel che entra e lo rimanda su se stesso?
L'ho pensato anch'io, ma facendo delle verifiche non mi è parso tale.
...proverò di nuovo.



suppongo che per esempio "process_rms" sai una costante, un puntatore che dice al call back di ritornare (con una funzione interna delle api di jack) ...
Sì, deve essere così, e nel progetto Gambas andrà passato nel secondo argomento di tale funzione esterna una variabile di tipo ''Puntatore''.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 09 Gennaio 2017, 13:06:05
mi sono incastrato alla grande ....

Codice: [Seleziona]
/tmp/jk.c:30:48: error: unknown type name ‘JACK_METER_TYPE’
 }void Invoca_Callback_meter (jack_client_t *cl,JACK_METER_TYPE,0) {
                                                ^
/tmp/jk.c:30:64: error: expected declaration specifiers or ‘...’ before numeric constant
 }void Invoca_Callback_meter (jack_client_t *cl,JACK_METER_TYPE,0) {
                                                                ^

ma penso che questo mio codice C "in linea" sia zeppo di errori (partendo da quello funzionante di VUOTT) ...
Codice: [Seleziona]
File.Save("/tmp/jk.c", "#include <string.h>\n" &
           "#include <jack/jack.h>" &
           "\n\n" &
           "jack_port_t **input_port;\n" &
           "jack_port_t **output_port;\n" &
           "jack_client_t *client;" &
           "\n\n" &
           "int process (jack_nframes_t, void *);" &
           "\n\n" &
        "int process (jack_nframes_t nframes, void *arg) {\n"
           "   int i;\n" &
           "   jack_default_audio_sample_t *in, *out;\n" &
           "   for (i = 0; i < 2; i++) {\n" &
           "   in = jack_port_get_buffer (input_port[i], nframes);\n" &
           "   out = jack_port_get_buffer (output_port[i], nframes);\n\n" &
           "   memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes);\n}\n\n" &
           "   return 0;\n}\n" &
           "\n\n" &
        "void Invoca_Callback (jack_client_t *cl, jack_port_t **it, jack_port_t **ot) {\n" &
           "   client = cl;\n" &
           "   input_port = it;\n" &
           "   output_port = ot;\n\n" &
           "   jack_set_process_callback (client, process, 0);\n}" &
        "void Invoca_Callback_meter (jack_client_t *cl,JACK_METER_TYPE,0) {\n" &
          "   client = cl;\n" &
          "   valore = process_rms;\n\n" &
          "   jack_set_process_callback (client, process, 0);\n}")
 
  Shell "gcc -o  /tmp/libjk.so /tmp/jk.c -shared -fPIC -ljack" Wait
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 09 Gennaio 2017, 15:25:17
Codice: [Seleziona]
/tmp/jk.c:30:48: error: unknown type name ‘JACK_METER_TYPE’
 }void Invoca_Callback_meter (jack_client_t *cl,JACK_METER_TYPE,0) {
 
Te sta' a ddì: " Ma 'sto JACK_METER_TYPE che è ? Quanto vale ?"



/tmp/jk.c:30:64: error: expected declaration specifiers or ‘...’ before numeric constant
 }void Invoca_Callback_meter (jack_client_t *cl,JACK_METER_TYPE,0) {
                                                                ^[/code]
Qui invece scambi i parametri per argomenti: non stai inviando, qui stai ricevendo. 'Sto zero che è ? Essendo qui un parametro della funzione, devi dichiarare tipo e variabile.... anche se poi resta a zero.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 09 Gennaio 2017, 23:46:02
" Ma 'sto JACK_METER_TYPE che è ? Quanto vale ?"
........insomma, è come se in Gambas tu avessi una situazione del genere:

Codice: [Seleziona]
Public Sub Main()

  Dim i As Integer
 
  i = 10 + JACK_METER_TYPE
 
  Print i
 
End

Provalo.... e vedi pure Gambas che ti dice.   (http://forum.ubuntu-it.org/images/smilies/whistle.gif)
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 11 Gennaio 2017, 14:05:07
cioe' quelal e' una costante definita da qualche parte ... ma dove si deve definire in C?

ho una certa difficolta' col C dentro un IDE, immaginate dentro una singola riga in gambas :D
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 11 Gennaio 2017, 18:06:39
Puoi porre quella costante con la direttiva #define.

Esempio in C:
Codice: [Seleziona]
#include <stdio.h>


#define JACK_METER_TYPE 99   /* definiamo una costante avente valore di tipo intero = 99 */


int main() {

    printf("%d\n", JACK_METER_TYPE);

return (0);

}
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 12 Gennaio 2017, 17:33:47
nella main.c del sorgente che ho trovato che implementa il vumeter per jack, c'e' una linea di questo tipo:
Codice: [Seleziona]
/* Pick the jack process method */
if (meter_type == MET_VU) {
init_buffers_rms();
jack_set_process_callback(client, process_rms, 0);
} else if (meter_type == MET_JF || meter_type == MET_SCO) {
jack_set_process_callback(client, process_ring, 0);
} else {
jack_set_process_callback(client, process_peak, 0);
}

il problema e' che ci sono anche un po' di include in testa:
Codice: [Seleziona]
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_thread.h>
#include <jack/jack.h>
#include <getopt.h>

#include "config.h"
#include "main.h"
#include "envelopes.h"
#include "find_image.h"

#include "vu_meters.h"
#include "ppm_meters.h"
#include "dpm_meters.h"
#include "jf_meters.h"
#include "scope.h"

#define MET_VU  1 // The meter display type
#define MET_PPM 2
#define MET_DPM 3
#define MET_JF  4
#define MET_SCO 5

spulciarseli a mano per capire dove sta' la costante che definisce il tipo di vumeter e' tosta ...
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 12 Gennaio 2017, 17:38:45
in realta' e' un po' piu' complicato ....

process_rms, process_ring e process_peak penso siano le uscite di queste funzioni (che estraggono i dati dai buffer di jack):

Codice: [Seleziona]
#include <math.h>
#include <jack/jack.h>

#include "main.h"
#include "envelopes.h"

float rms_buffers[MAX_METERS][RMS_BUF_SIZE];
float rms_sums[MAX_METERS];
float ring_buf[MAX_METERS][RING_BUF_SIZE];
unsigned int rms_pos = 0;

float env_read(int port)
{
float tmp = env[port];
env[port] = 0.0f;

return tmp;
}

int process_peak(jack_nframes_t nframes, void *arg)
{
unsigned int i, port;

if (meter_freeze) {
return 0;
}

for (port = 0; port < num_meters; port++) {
jack_default_audio_sample_t *in, *out;

/* just incase the port isn't registered yet */
if (input_ports[port] == 0 || output_ports[port] == 0) {
break;
}

in = (jack_default_audio_sample_t *) jack_port_get_buffer(input_ports[port], nframes);
out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_ports[port], nframes);

for (i = 0; i < nframes; i++) {
const float s = fabs(in[i]);
out[i] = in[i];
if (s > env[port]) {
env[port] = s;
}
}
}

return 0;
}

void init_buffers_rms()
{
unsigned int i, j;

for (i=0; i < MAX_METERS; i++) {
rms_sums[i] = 0.0f;
for (j=0; j < RMS_BUF_SIZE; j++) {
rms_buffers[i][j] = 0.0f;
}
}
}

int process_rms(jack_nframes_t nframes, void *arg)
{
unsigned int i, port;

if (meter_freeze) {
return 0;
}

for (port = 0; port < num_meters; port++) {
jack_default_audio_sample_t *in, *out;

/* just incase the port isn't registered yet */
if (input_ports[port] == 0 || output_ports[port] == 0) {
break;
}

in = (jack_default_audio_sample_t *) jack_port_get_buffer(input_ports[port], nframes);
out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_ports[port], nframes);

/* Update running total of samples in RMS buffer */
for (i = 0; i < nframes; i++) {
const float s = in[i] * in[i];
out[i] = in[i];
rms_sums[port] -= rms_buffers[port][rms_pos];
rms_sums[port] += s;
rms_buffers[port][rms_pos] = s;
rms_pos = (rms_pos + 1) & (RMS_BUF_SIZE - 1);

} if (rms_sums[port] < 0.0f) {
/* This should never happnen, but can occasionally due
* the the difference between the rms history and the
* float sum. We clobber it just to make sure. */
rms_sums[port] = 0.0f;
        }
        env[port] = sqrtf(rms_sums[port] / (float)RMS_BUF_SIZE); }

return 0;
}

int process_ring(jack_nframes_t nframes, void *arg)
{
static unsigned int pos = 0;
unsigned int i, port;
jack_default_audio_sample_t *in, *out;

if (meter_freeze) {
return 0;
}

for (port = 0; port < num_meters; port++) {
/* just incase the port isn't registered yet */
if (input_ports[port] == 0 || output_ports[port] == 0) {
break;
}

in = (jack_default_audio_sample_t *) jack_port_get_buffer(input_ports[port], nframes);
out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_ports[port], nframes);
for (i=0; i<nframes; i++) {
out[i] = in[i];
ring_buf[port][(pos + i) & (RING_BUF_SIZE - 1)] = in[i];
}
}
pos = (pos + nframes) & (RING_BUF_SIZE - 1);

return 0;
}

che e' il codice di envelopers.c

............. la vedo dura ....
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 12 Gennaio 2017, 22:26:43
il problema e' che ci sono anche un po' di include in testa:
Codice: [Seleziona]
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_thread.h>
#include <jack/jack.h>
#include <getopt.h>

#include "config.h"
#include "main.h"
#include "envelopes.h"
#include "find_image.h"

#include "vu_meters.h"
#include "ppm_meters.h"
#include "dpm_meters.h"
#include "jf_meters.h"
#include "scope.h"

spulciarseli a mano per capire dove sta' la costante che definisce il tipo di vumeter e' tosta ...

Ho capito: tu supponi che quella Costante, che dà problemi, sia dichiarata in un file header dichiarato con la direttiva "#include". Pertanto, per sapere il valore della Costante bisognerebbe andare a vedere in quale file header è dichiarata.

Sicuramente non nei file header delle librerie standard di C.
Quindi è da ricercare in questi file:
#include <jack/jack.h>
#include "envelopes.h"
#include "find_image.h"
#include "vu_meters.h"
#include "ppm_meters.h"
#include "dpm_meters.h"
#include "jf_meters.h"
#include "scope.h"


Ovviamente, trovato il file header contenente quella Costante, puoi richiamare poi nella parte C del tuo programma direttamente quel file header.
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 16 Gennaio 2017, 18:09:24
si e' collegata a #include "envelopes.h"

e' proprio l'uscita di una funzione che e' implementata in envelopers.c

penso che per ora mettero' in pausa il progetto ....
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: vuott - 16 Gennaio 2017, 21:04:33
si e' collegata a #include "envelopes.h"
Siamo precisi: affermi che l'identificatore JACK_METER_TYPE è una Costante dichiarata nel file header "envelopes.h" ?
Titolo: Re:Creare un semplice Client di Jack Audio Connection Kit
Inserito da: allegfede - 19 Gennaio 2017, 13:54:31
jack_meter_type e' una variabile che ho creato io, in realta' nel programma C originale, nella sezione main.c e' definito cosi':
Codice: [Seleziona]
/* Pick the jack process method */
if (meter_type == MET_VU) {
init_buffers_rms();
jack_set_process_callback(client, process_rms, 0);
} else if (meter_type == MET_JF || meter_type == MET_SCO) {
jack_set_process_callback(client, process_ring, 0);
} else {
jack_set_process_callback(client, process_peak, 0);
}

quindi il valore che potrebbe prendere e':
MET_VU o MET_SCO o MET_JF

in base a quale tipo di meter si voglia fare accesso, il callback di jack ha come opzioni:
client (puntatore a quale client di jack fa' la richiesta?)
process_rms / process_ring / process_peak (puntatore alla funzione che fa il calcolo dei valori? valore di ritorno della funzione di calcolo opportuna?)
0 (che cosa rappresenta?)

Sicuramente in envelopers.c ci sono queste funzioni:
Codice: [Seleziona]
#include <math.h>
#include <jack/jack.h>

#include "main.h"
#include "envelopes.h"

float rms_buffers[MAX_METERS][RMS_BUF_SIZE];
float rms_sums[MAX_METERS];
float ring_buf[MAX_METERS][RING_BUF_SIZE];
unsigned int rms_pos = 0;

float env_read(int port)
{
float tmp = env[port];
env[port] = 0.0f;

return tmp;
}

int process_peak(jack_nframes_t nframes, void *arg)
{
unsigned int i, port;

if (meter_freeze) {
return 0;
}

for (port = 0; port < num_meters; port++) {
jack_default_audio_sample_t *in, *out;

/* just incase the port isn't registered yet */
if (input_ports[port] == 0 || output_ports[port] == 0) {
break;
}

in = (jack_default_audio_sample_t *) jack_port_get_buffer(input_ports[port], nframes);
out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_ports[port], nframes);

for (i = 0; i < nframes; i++) {
const float s = fabs(in[i]);
out[i] = in[i];
if (s > env[port]) {
env[port] = s;
}
}
}

return 0;
}

void init_buffers_rms()
{
unsigned int i, j;

for (i=0; i < MAX_METERS; i++) {
rms_sums[i] = 0.0f;
for (j=0; j < RMS_BUF_SIZE; j++) {
rms_buffers[i][j] = 0.0f;
}
}
}

int process_rms(jack_nframes_t nframes, void *arg)
{
unsigned int i, port;

if (meter_freeze) {
return 0;
}

for (port = 0; port < num_meters; port++) {
jack_default_audio_sample_t *in, *out;

/* just incase the port isn't registered yet */
if (input_ports[port] == 0 || output_ports[port] == 0) {
break;
}

in = (jack_default_audio_sample_t *) jack_port_get_buffer(input_ports[port], nframes);
out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_ports[port], nframes);

/* Update running total of samples in RMS buffer */
for (i = 0; i < nframes; i++) {
const float s = in[i] * in[i];
out[i] = in[i];
rms_sums[port] -= rms_buffers[port][rms_pos];
rms_sums[port] += s;
rms_buffers[port][rms_pos] = s;
rms_pos = (rms_pos + 1) & (RMS_BUF_SIZE - 1);

} if (rms_sums[port] < 0.0f) {
/* This should never happnen, but can occasionally due
* the the difference between the rms history and the
* float sum. We clobber it just to make sure. */
rms_sums[port] = 0.0f;
        }
        env[port] = sqrtf(rms_sums[port] / (float)RMS_BUF_SIZE); }

return 0;
}

int process_ring(jack_nframes_t nframes, void *arg)
{
static unsigned int pos = 0;
unsigned int i, port;
jack_default_audio_sample_t *in, *out;

if (meter_freeze) {
return 0;
}

for (port = 0; port < num_meters; port++) {
/* just incase the port isn't registered yet */
if (input_ports[port] == 0 || output_ports[port] == 0) {
break;
}

in = (jack_default_audio_sample_t *) jack_port_get_buffer(input_ports[port], nframes);
out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_ports[port], nframes);
for (i=0; i<nframes; i++) {
out[i] = in[i];
ring_buf[port][(pos + i) & (RING_BUF_SIZE - 1)] = in[i];
}
}
pos = (pos + nframes) & (RING_BUF_SIZE - 1);

return 0;
}

che a loro volta vogliono (giustamente) i dati dei buffer di jack ..... la vedo complicata.

Io speravo che fosse una "feature" interna di jack.