Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

JackClient.cpp

Go to the documentation of this file.
00001 //
00002 // File: JackClient.h
00003 // Created by: cc <cc@sony.stanford.edu>
00004 // Created on: Sat Jul 26 13:08:21 2003
00005 //
00006 
00007 #include "JackClient.h"
00008 #include "math.h"
00009 #include "string.h"
00010 #include "Snd.h"
00011 jack_port_t **input_port;
00012 jack_port_t **output_port;
00013 jack_default_audio_sample_t **inBufPtr;
00014 jack_default_audio_sample_t **outBufPtr;
00015 double *inFrame;
00016 double *outFrame;
00017 double *iPhase;
00018 
00019 int xx_nChans_xx;
00020 unsigned int xx_nFrames_xx;
00021 extern Snd *theSnd;
00022 int
00023 xx_global_process_xx (unsigned int nframes, void *argc)
00024 {
00025 if (nframes!=xx_nFrames_xx)
00026 printf("xx_global_process_xx [%d nframes]\n", nframes);
00027 /* "in" is in from jack, "out" is out to jack */
00028         for (int i = 0; i < xx_nChans_xx; i++)
00029         {
00030                 inBufPtr[i] = (jack_default_audio_sample_t *)
00031                         jack_port_get_buffer (input_port[i], nframes);
00032                 outBufPtr[i] = (jack_default_audio_sample_t *)
00033                         jack_port_get_buffer (output_port[i], nframes);
00034         }
00035 //      memcpy (outBufPtr[0], inBufPtr[0], sizeof (jack_default_audio_sample_t) * nframes);
00036 //      memcpy (outBufPtr[1], inBufPtr[1], sizeof (jack_default_audio_sample_t) * nframes);
00037 
00038         for (int j = 0; j < (int)nframes; j++)
00039         {
00040                 jack_default_audio_sample_t *inBuf;
00041                 jack_default_audio_sample_t *outBuf;
00042                 for (int i = 0; i < xx_nChans_xx; i++)
00043                 {
00044                         inBuf = inBufPtr[i];
00045                         inFrame[i] = inBuf[j];
00046                 }
00047 
00048 //              for (int i = 0; i < xx_nChans_xx; i++)
00049 //                     outFrame[i] = inFrame[i];
00050 /*              
00051                   for (int i = 0; i < xx_nChans_xx; i++)
00052                   {
00053                   outFrame[i] = sin (iPhase[i]);
00054                   iPhase[i] += 0.01;
00055                   }
00056 */               
00057       outFrame = theSnd->tickFrame(inFrame);
00058 
00059                 for (int i = 0; i < xx_nChans_xx; i++)
00060                 {
00061                         outBuf = outBufPtr[i];
00062                         outBuf[j] = outFrame[i];
00063                 }
00064 // printf("xx_global_process_xx [frame %d]\n", j);
00065         }
00066 
00067         return 0;
00068 }
00069 
00070 JackClient::JackClient (QString name, int nChans, int nFrames):Stk ()
00071 {
00072         xx_nChans_xx = this->nChans = nChans;
00073         xx_nFrames_xx = nFrames;
00074         inFrame = new double[nChans];
00075         outFrame = new double[nChans];
00076         input_port = new jack_port_t *[nChans];
00077         output_port = new jack_port_t *[nChans];
00078         inBufPtr = new jack_default_audio_sample_t *[nChans];
00079         outBufPtr = new jack_default_audio_sample_t *[nChans];
00080 
00081         iPhase = new double[nChans];    // sample frame of output channels
00082         for (int i = 0; i < nChans; i++)
00083                 iPhase[i] = 0.0;
00084 
00085         /* tell the JACK server to call error() whenever it
00086          * experiences an error.  Notice that this callback is
00087          * global to this process, not specific to each client.
00088          * 
00089          * This is set here so that it can catch errors in the
00090          * connection process
00091          */
00092         jack_set_error_function (error);
00093 
00094         /* try to become a client of the JACK server */
00095 
00096         if ((client = jack_client_new (name)) == 0)
00097         {
00098                 printf ("jack server not running?\n");
00099 //              return 1;
00100         }
00101 
00102         /* tell the JACK server to call `process()' whenever
00103          * there is work to be done.
00104          */
00105 
00106         jack_set_process_callback (client, xx_global_process_xx, 0);
00107 
00108         /* tell the JACK server to call `srate()' whenever
00109          * the sample rate of the system changes.
00110          */
00111 
00112 
00113         jack_set_sample_rate_callback (client, srate_callback, 0);
00114 
00115         /* tell the JACK server to call `jack_shutdown()' if
00116          * it ever shuts down, either entirely, or if it
00117          * just decides to stop calling us.
00118          */
00119 
00120         jack_on_shutdown (client, jack_shutdown, 0);
00121 
00122         /* display the current sample rate. once the client is activated 
00123          * (see below), you should rely on your own sample rate
00124          * callback (see above) for this value.
00125          */
00126 
00127         printf ("engine sample rate: %u\n", jack_get_sample_rate (client));
00128 
00129         /* create two ports */
00130         for (int i = 0; i < nChans; i++)
00131         {
00132                 QString iName, oName;
00133                 QTextOStream (&iName) << "input" << i;
00134                 QTextOStream (&oName) << "output" << i;
00135 
00136                 input_port[i] =
00137                         jack_port_register (client, iName,
00138                                             JACK_DEFAULT_AUDIO_TYPE,
00139                                             JackPortIsInput, 0);
00140                 output_port[i] =
00141                         jack_port_register (client, oName,
00142                                             JACK_DEFAULT_AUDIO_TYPE,
00143                                             JackPortIsOutput, 0);
00144         }
00145 }
00146 
00147 
00148 void
00149 JackClient::stop ()
00150 {
00151 jack_client_close (client);
00152         }
00153         
00154 void
00155 JackClient::start ()
00156 {       /* tell the JACK server that we are ready to roll */
00157 
00158         if (jack_activate (client))
00159         {
00160                 printf ("cannot activate client");
00161 //              return 1;
00162         }
00163         go();
00164 }
00165 void
00166 JackClient::go ()
00167 {       /* tell the JACK server that we are ready to roll */
00168 
00169 //      if (jack_activate (client))
00170 //      {
00171 //              printf ("cannot activate client");
00172 //              return 1;
00173 //      }
00174 
00175         /* connect the ports. Note: you can't do this before
00176          * the client is activated, because we can't allow
00177          * connections to be made to clients that aren't
00178          * running.
00179          */
00180 
00181 
00182         if ((ports =
00183              jack_get_ports (client, NULL, NULL,
00184                              JackPortIsPhysical | JackPortIsOutput)) == NULL)
00185         {
00186                 fprintf (stderr, "Cannot find any physical capture ports\n");
00187                 exit (1);
00188         }
00189         for (int i = 0; i < nChans; i++)
00190         {
00191 
00192                 if (jack_connect
00193                     (client, ports[i], jack_port_name (input_port[i])))
00194                 {
00195                         fprintf (stderr, "cannot connect input ports\n");
00196                 }
00197         }
00198 
00199         free (ports);
00200 
00201         if ((ports =
00202              jack_get_ports (client, NULL, NULL,
00203                              JackPortIsPhysical | JackPortIsInput)) == NULL)
00204         {
00205                 fprintf (stderr, "Cannot find any physical playback ports\n");
00206                 exit (1);
00207         }
00208 
00209         for (int i = 0; i < nChans; i++)
00210         {
00211                 if (jack_connect
00212                     (client, jack_port_name (output_port[i]), ports[i]))
00213                 {
00214                         fprintf (stderr, "cannot connect output ports\n");
00215                 }
00216 
00217         }
00218 //      printf ("about to sleep\n");
00219         free (ports);
00220 
00221         /* Since this is just a toy, run for a few seconds, then finish */
00222 
00223 //      sleep (10);
00224 //      printf ("...awake\n");
00225 //      jack_client_close (client);
00226 //      exit (0);
00227 }
00228 
00229 JackClient::~JackClient ()
00230 {
00231         // TODO: put destructor code here
00232 }

Generated on Thu Aug 3 16:14:47 2006 by  doxygen 1.4.4