Autore Topic: Creare un semplice Client di Jack Audio Connection Kit  (Letto 1618 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #15 il: 26 Febbraio 2016, 15:18:08 »
Ciao,
credo di aver risolto.
Ti ho inviato l'intero codice come messaggio privato.

Verificalo e fammi sapere.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #16 il: 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.
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #17 il: 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.    :-\ 
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #18 il: 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

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 ....
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #19 il: 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''.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #20 il: 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
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #21 il: 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.
« Ultima modifica: 09 Gennaio 2017, 15:26:07 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #22 il: 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.   
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #23 il: 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
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #24 il: 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);

}
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #25 il: 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 ...
se corri, morirai stanco (motto degli sniper)

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #26 il: 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 ....
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #27 il: 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.
« Ultima modifica: 13 Gennaio 2017, 08:59:36 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #28 il: 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 ....
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Creare un semplice Client di Jack Audio Connection Kit
« Risposta #29 il: 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" ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »