Logo Search packages:      
Sourcecode: jmeters version File versions  Download package

jclient.cc

/*
    Copyright (C) 2008 Fons Adriaensen <fons@kokkinizita.net>
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#include <string.h>
#include <sndfile.h>
#include <math.h>
#include "jclient.h"
#include "meterwin.h"


//-------------------------------------------------------------------------------------------------------


Jclient::Jclient (const char *name, JMconf *config) :
    A_thread ("Jclient"),
    _jack_client (0),
    _jname (name),
    _fsamp (0),
    _fsize (0),
    _config (config),
    _type (0)
{
    init_jack ();   
    initialise ();
}


Jclient::~Jclient (void)
{
    if (_jack_client) close_jack ();
}


void Jclient::init_jack (void)
{
    int            i;
    char           t1 [16];
    char           t2 [64];
    jack_status_t  s;

    if ((_jack_client = jack_client_open (_jname, (jack_options_t) 0, &s)) == 0)
    {
        fprintf (stderr, "Can't connect to JACK.\n");
        exit (1);
    }

    jack_set_process_callback (_jack_client, jack_static_process, (void *) this);
    jack_on_shutdown (_jack_client, jack_static_shutdown, (void *) this);

    if (jack_activate (_jack_client))
    {
        fprintf(stderr, "Can't activate JACK.\n");
        exit (1);
    }

    _jname = jack_get_client_name (_jack_client);
    _fsamp = jack_get_sample_rate (_jack_client);
    _fsize = jack_get_buffer_size (_jack_client);

    for (i = 0; i < _config->_numb; i++)
    {
      sprintf (t1, "in-%d", i + 1);
      sprintf (t2, "%s:%s", _jname, t1);
        _jack_ipports [i] = jack_port_register (_jack_client, t1, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
      jack_connect (_jack_client, _config->_mdata [i]._port, t2);
    }
}


void Jclient::close_jack ()
{
    jack_deactivate (_jack_client);
    jack_client_close (_jack_client);
}


void Jclient::jack_static_shutdown (void *arg)
{
    return ((Jclient *) arg)->jack_shutdown ();
}


void Jclient::jack_shutdown (void)
{
    send_event (EV_EXIT, 1);
}


int Jclient::jack_static_process (jack_nframes_t nframes, void *arg)
{
    return ((Jclient *) arg)->jack_process (nframes);
}
 

int Jclient::jack_process (jack_nframes_t nframes)
{
    int             i;
    jack_nframes_t  n;
    float          *p,  t1, t2, m1, z1, z2;
    bool            f;
    Mdata          *M;

    f = (_config->_cnt1 != _config->_cnt2);
    M = _config->_mdata;

    switch (_type)
    {
    case VUM:
      for (i = 0; i < _config->_numb; i++, M++)
      {
          p = (float *) jack_port_get_buffer (_jack_ipports [i], nframes);
          m1 = f ? 0: M->_m1;
          z1 = M->_z1;
          z2 = M->_z2;
          n = nframes / 4;
          while (n--)
          {
            t2 = z2 / 2;
            t1 = fabsf (*p++) - t2;
            z1 += _wvum * (t1 - z1);
            t1 = fabsf (*p++) - t2;
            z1 += _wvum * (t1 - z1);
            t1 = fabsf (*p++) - t2;
            z1 += _wvum * (t1 - z1);
            t1 = fabsf (*p++) - t2;
            z1 += _wvum * (t1 - z1);
            z2 += 4 * _wvum * (z1 - z2);
            if (z2 > m1) m1 = z2;
          }
          M->_level = _gvum * m1;
          M->_m1 = m1;
          M->_z1 = z1;
          M->_z2 = z2 + 1e-10f;
      }
      break;

    case PPM:
      for (i = 0; i < _config->_numb; i++, M++)
      {
          p = (float *) jack_port_get_buffer (_jack_ipports [i], nframes);
          m1 = f ? 0: M->_m1;
          z1 = M->_z1;
          n = nframes / 4;
          while (n--)
          {
            t1 = fabsf (*p++);
            if (t1 > z1) z1 += _wppm1 * (t1 - z1);
            t1 = fabsf (*p++);
            if (t1 > z1) z1 += _wppm1 * (t1 - z1);
            t1 = fabsf (*p++);
            if (t1 > z1) z1 += _wppm1 * (t1 - z1);
            t1 = fabsf (*p++);
            if (t1 > z1) z1 += _wppm1 * (t1 - z1);
            if (z1 > m1) m1 = z1;
            z1 *= _wppm2;
          }
          M->_m1 = m1;
          M->_z1 = z1 + 1e-10f;
            M->_level = m1 * _gppm;
      }
      break;
    }

    _config->_cnt2 = _config->_cnt1;
    return 0;
}


void Jclient::initialise ()
{
    float g;

    g = powf (10.0f, 0.05f * _config->_gain);
    _gvum = g * 1.5f * 1.571f * 3.162f;
    _wvum = 11.1f / _fsamp; 
    _gppm = g * 1.028f;
    _wppm1 = 357.0f / _fsamp;
    _wppm2 = 1.0f - 4.0f / _fsamp;
    switch (_config->_type)
    {
    case Meterwin::MVUM:
    case Meterwin::SVUM:
      _type = VUM;
      break;
    case Meterwin::MPPM:
    case Meterwin::SPPM:
    case Meterwin::MPPM2:
    case Meterwin::SPPM2:
      _type = PPM;
      break;
    }
}


//-------------------------------------------------------------------------------------------------------

Generated by  Doxygen 1.6.0   Back to index