). Would it be possible to
include the source code below as an example?
* There's already a midi controlled synth application in that repo
(midisine.c). But I feel the example demonstrates in a clearer way
how to send audio to the sound card's stereo output, because it just
uses audio data, not audio data plus midi handling.
* There's also the simple client example (simple_client.c), but that
one (effectively) handles bi-directional audio data streaming. This
client just sends audio data which makes it clearer how to use data
output (and, by implication, data input).
Long story in short - this example is clearer to n00bs (like me).
Thank you for your consideration!
|/** @file simple_client.c * * @brief This simple
client demonstrates
the basic features of JACK * as they would be used by many
applications.
*/#include<stdio.h>#include<errno.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<signal.h>#ifndefWIN32
#include<unistd.h>#endif#include<jack/jack.h>jack_port_t*output_port1,*output_port2;jack_client_t*client;#ifndefM_PI
#defineM_PI (3.14159265)#endif#defineTABLE_SIZE
(200)typedefstruct{floatsine[TABLE_SIZE];intleft_phase;intright_phase;}paTestData;staticvoidsignal_handler(intsig){jack_client_close(client);fprintf(stderr,"signal
received, exiting ...\n");exit(0);}/** * The process callback for this
JACK application is called in a * special realtime thread once for
each audio cycle. * * This client follows a simple rule: when the JACK
transport is * running, copy the input port to the output. When it
stops, exit.
*/intprocess(jack_nframes_tnframes,void*arg){jack_default_audio_sample_t*out1,*out2;paTestData
*data =(paTestData*)arg;inti;out1
=(jack_default_audio_sample_t*)jack_port_get_buffer(output_port1,nframes);out2
=(jack_default_audio_sample_t*)jack_port_get_buffer(output_port2,nframes);for(i
=0;i<nframes;i++){out1[i]=data->sine[data->left_phase];// left
out2[i]=data->sine[data->right_phase];// right data->left_phase
+=1;if(data->left_phase >=TABLE_SIZE)data->left_phase
-=TABLE_SIZE;data->right_phase +=10;// higher pitch so we can
distinguish left and right. if(data->right_phase
=TABLE_SIZE)data->right_phase
-=TABLE_SIZE;}return0;}/** * JACK calls
this shutdown_callback if the server ever
shuts down or * decides to
disconnect the client.
*/voidjack_shutdown(void*arg){exit(1);}intmain(intargc,char*argv[]){constchar**ports;constchar*client_name;constchar*server_name
=NULL;jack_options_toptions
=JackNullOption;jack_status_tstatus;paTestData data;inti;/*if (argc >=
2) { // client name specified? client_name = argv[1]; if (argc >= 3) {
// server name specified? server_name = argv[2]; int my_option =
JackNullOption | JackServerName; options = (jack_options_t)my_option;
} } else { // use basename of argv[0] client_name = strrchr(argv[0],
'/'); if (client_name == 0) { client_name = argv[0]; } else {
client_name++; } }*/client_name ="mytest";for(i
=0;i<TABLE_SIZE;i++){data.sine[i]=0.2*(float)sin(((double)i
/(double)TABLE_SIZE)*M_PI *2.);}data.left_phase =data.right_phase
=0;// open a client connection to the JACK server client
=jack_client_open(client_name,options,&status,server_name);if(client
==NULL){fprintf(stderr,"jack_client_open() failed, ""status =
0x%2.0x\n",status);if(status &JackServerFailed){fprintf(stderr,"Unable
to connect to JACK server\n");}exit(1);}if(status
&JackServerStarted){fprintf(stderr,"JACK server started\n");}if(status
&JackNameNotUnique){client_name
=jack_get_client_name(client);fprintf(stderr,"unique name `%s'
assigned\n",client_name);}// tell the JACK server to call `process()'
whenever//there is work to be
done.jack_set_process_callback(client,process,&data);// tell the JACK
server to call `jack_shutdown()' if//it ever shuts down, either
entirely, or if it//just decides to stop calling
us.jack_on_shutdown(client,jack_shutdown,0);// create two ports
output_port1
=jack_port_register(client,"output1",JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0);output_port2
=jack_port_register(client,"output2",JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0);if((output_port1
==NULL)||(output_port2 ==NULL)){fprintf(stderr,"no more JACK ports
available\n");exit(1);}//Tell the JACK server that we are ready to
roll. Our// process() callback will start running now.
if(jack_activate(client)){fprintf(stderr,"cannot activate
client");exit(1);}// Connect the ports. You can't do this before the
client is// activated, because we can't make connections to clients//
that aren't running. Note the confusing (but necessary)// orientation
of the driver backend ports: playback ports are// "input" to the
backend, and capture ports are "output" from// it.ports
=jack_get_ports(client,NULL,NULL,JackPortIsPhysical|JackPortIsInput);if(ports
==NULL){fprintf(stderr,"no physical playback
ports\n");exit(1);}if(jack_connect(client,jack_port_name(output_port1),ports[0])){fprintf(stderr,"cannot
connect output
ports\n");}if(jack_connect(client,jack_port_name(output_port2),ports[1])){fprintf(stderr,"cannot
connect output ports\n");}jack_free(ports);// install a signal handler
to properly quits jack client #ifdefWIN32
signal(SIGINT,signal_handler);signal(SIGABRT,signal_handler);signal(SIGTERM,signal_handler);#elsesignal(SIGQUIT,signal_handler);signal(SIGTERM,signal_handler);signal(SIGHUP,signal_handler);signal(SIGINT,signal_handler);#endif//
keep running until the Ctrl+C while(1){#ifdefWIN32
Sleep(1000);#elsesleep(1);#endif}jack_client_close(client);exit(0);}|