[LAD] jack app help

Stefanos K gnittor at freemail.gr
Sun Dec 16 01:39:59 UTC 2007


hello,

I am trying to develop an app using jack. My first goal is to play a 
stereo wav.
I've used clockloop http://plugin.org.uk/clockloop by Steve Harris as a 
starting point. It uses libsndfile to open a mono wav.

I've reached a point where 2 outputs are created and connected to the 
first two outputs of the sound card.
I managed to send a mono file to both outs. I've opened a stereo file, 
but I'm having trouble outputting it correctly.

I am a bit confused on how to continue.
If someone could give me some pointers would be much appreciated.



thanks in advance
stefanos




This is what I have so far:


//================ audio.c ===============
/*
 *  Copyright (C) 2003 Steve Harris
 *
 *  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.
 */

#include <stdlib.h>
#include <jack/jack.h>

#include "audio.h"
#include <stdio.h>

buffer_t *buffers = NULL;
unsigned int buffer_size = 0;
unsigned int num_buffers = 0;
unsigned int play_pos = 0;

float gain_inc = 0.01f;
float c_gain = 0.1f;

jack_client_t *client;
jack_port_t *output_port_ML;
jack_port_t *output_port_MR;

int process(jack_nframes_t nframes, void *arg)
{
    unsigned int i,j;
    sample_t *outML = (sample_t *)jack_port_get_buffer(output_port_ML, 
nframes);
    sample_t *outMR = (sample_t *)jack_port_get_buffer(output_port_MR, 
nframes);

    for (j=0; j<nframes; j++) {
        outML[j] = 0.0f;
        outMR[j] = 0.0f;
    }
    for (i=0; i<num_buffers; i=i++) {
        if (buffers[i].state == on) {
            for (j=0; j<nframes; j++) {
                outML[j] += (buffers[i].data[(play_pos + j) % 
buffer_size]) * c_gain;
                outMR[j] += (buffers[i].data[(play_pos + j) % 
buffer_size]) * c_gain;
            }
        }

    }
    play_pos = (play_pos + nframes) % buffer_size;

    return 0;
}





//====================== audio.h ======================
#ifndef AUDIO_H
#define AUDIO_H

#include <jack/jack.h>

typedef jack_default_audio_sample_t sample_t;

typedef enum {
    off,
    on,
    ramp_down,
    ramp_up,
} b_state;

typedef struct {
    float *data;
    float gain;
    b_state state;
} buffer_t;

extern buffer_t *buffers;
extern unsigned int buffer_size;
extern unsigned int num_buffers;

extern jack_client_t *client;
extern jack_port_t *output_port_ML;
extern jack_port_t *output_port_MR;

extern float gain_inc;

int process(jack_nframes_t nframes, void *arg);

#endif





//=================== clockloop.c =======================
/*
 *  Copyright (C) 2003 Steve Harris
 *
 *  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.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
#include <sndfile.h>

#include "audio.h"


void midi_action(snd_seq_t * seq_handle);

jack_client_t *client;
jack_port_t *output_port_ML;
jack_port_t *output_port_MR;

int main(int argc, char **argv)
{

    unsigned int i;
    int count;
    const char **ports;


    if (argc < 2) {
        fprintf(stderr, "Usage: %s <audio-file> ...\n", argv[0]);
        return 1;
    }

    /* JACK stuff */

    if ((client = jack_client_new("clock-loop")) == 0) {
    fprintf (stderr, "jack server not running?\n");
    return 1;
    }
    jack_set_process_callback (client, process, 0);
    output_port_ML = jack_port_register (client, "out_Master_Left", 
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    output_port_MR = jack_port_register (client, "out_Master_Right", 
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
   

    num_buffers = argc - 1;
    buffers = malloc(sizeof(buffer_t) * num_buffers * 
2);                  // *2 for stereo
    buffer_size = 0;
    for (i = 0; i<num_buffers; i++) {
        SNDFILE *sf;
        SF_INFO sfi;

        sfi.format = 0;
        sf = sf_open(argv[i + 1], SFM_READ, &sfi);
        /*if (sfi.channels != 1) {
            fprintf(stderr, "%s: only works with mono files\n", argv[0]);
            return 1;
        }*/
        if (!buffer_size) {
            buffer_size = sfi.frames;
            gain_inc = (float)jack_get_buffer_size(client) / 
(buffer_size * 8.0f);
            buffers[i].state = on;
            buffers[i].gain = 1.0f;
        } else {
            buffers[i].state = off;
            buffers[i].gain = 0.0f;
        }
        if (sfi.frames > buffer_size) {
            fprintf(stderr, "%s warning: '%s' is %d frames longer than 
reference file, truncating\n", argv[0], argv[i+1], (int)(sfi.frames - 
buffer_size));
        }
        buffers[i].data = malloc(buffer_size * sizeof(float));
        count = sf_read_float(sf, buffers[i].data, buffer_size);
        if (count < buffer_size) {
            fprintf(stderr, "%s warning: only read %d/%d frames from 
file '%s', zero padding\n", argv[0], count, buffer_size, argv[i+1]);
            memset(buffers[i].data + count, 0, buffer_size - count);
        }
        sf_close(sf);
    }
       
    if (jack_activate(client)) {
        fprintf (stderr, "cannot activate client");
        exit(1);
    }

    /* connect the ports*/
    if ((ports = jack_get_ports (client, NULL, NULL, 
JackPortIsPhysical|JackPortIsInput)) == NULL) {
      fprintf(stderr, "Cannot find any physical playback ports\n");
      exit(1);
    }

      if (jack_connect (client, jack_port_name (output_port_ML), 
ports[0])) {
        fprintf (stderr, "cannot connect output ports\n");
      }
      if (jack_connect (client, jack_port_name (output_port_MR), 
ports[1])) {
        fprintf (stderr, "cannot connect output ports\n");
      }

    for(;;)
      sleep (1);
}





More information about the Linux-audio-dev mailing list