Browse Source

Stop using alloca and allocate buffer on the heap for alsa_io.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4162 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.7
sletz 14 years ago
parent
commit
246b75a99b
3 changed files with 108 additions and 22 deletions
  1. +2
    -0
      ChangeLog
  2. +53
    -13
      example-clients/alsa_in.c
  3. +53
    -9
      example-clients/alsa_out.c

+ 2
- 0
ChangeLog View File

@@ -39,6 +39,8 @@ Valerio Pilo
* jack_client_has_session_callback implementation. * jack_client_has_session_callback implementation.
* Fix jdelay for new latency API. * Fix jdelay for new latency API.
* Check requested buffer size and limit to 1..8192 - avoids wierd behaviour caused by jack_bufsize foobar. * Check requested buffer size and limit to 1..8192 - avoids wierd behaviour caused by jack_bufsize foobar.
* jack_port_type_get_buffer_size implementation.
* Stop using alloca and allocate buffer on the heap for alsa_io.


2011-03-08 Stephane Letz <letz@grame.fr> 2011-03-08 Stephane Letz <letz@grame.fr>




+ 53
- 13
example-clients/alsa_in.c View File

@@ -11,12 +11,11 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>


#include <alloca.h>
#include <math.h> #include <math.h>


#include <jack/jack.h> #include <jack/jack.h>
#include <jack/jslist.h> #include <jack/jslist.h>
#include <memops.h>
#include <jack/memops.h>


#include "alsa/asoundlib.h" #include "alsa/asoundlib.h"


@@ -77,6 +76,12 @@ volatile float output_diff = 0.0;
snd_pcm_uframes_t real_buffer_size; snd_pcm_uframes_t real_buffer_size;
snd_pcm_uframes_t real_period_size; snd_pcm_uframes_t real_period_size;


// buffers

char *tmpbuf;
char *outbuf;
float *resampbuf;

// format selection, and corresponding functions from memops in a nice set of structs. // format selection, and corresponding functions from memops in a nice set of structs.


typedef struct alsa_format { typedef struct alsa_format {
@@ -307,8 +312,6 @@ double hann( double x )
*/ */
int process (jack_nframes_t nframes, void *arg) { int process (jack_nframes_t nframes, void *arg) {


char *outbuf;
float *resampbuf;
int rlen; int rlen;
int err; int err;
snd_pcm_sframes_t delay = target_delay; snd_pcm_sframes_t delay = target_delay;
@@ -322,10 +325,15 @@ int process (jack_nframes_t nframes, void *arg) {
// this is for compensating xruns etc... // this is for compensating xruns etc...


if( delay > (target_delay+max_diff) ) { if( delay > (target_delay+max_diff) ) {
char *tmp = alloca( (delay-target_delay) * formats[format].sample_size * num_channels );
snd_pcm_readi( alsa_handle, tmp, delay-target_delay );

output_new_delay = (int) delay; output_new_delay = (int) delay;


while ((delay-target_delay) > 0) {
snd_pcm_uframes_t to_read = ((delay-target_delay) > 512) ? 512 : (delay-target_delay);
snd_pcm_readi( alsa_handle, tmpbuf, to_read );
delay -= to_read;
}

delay = target_delay; delay = target_delay;


// Set the resample_rate... we need to adjust the offset integral, to do this. // Set the resample_rate... we need to adjust the offset integral, to do this.
@@ -399,13 +407,6 @@ int process (jack_nframes_t nframes, void *arg) {


// Calculate resample_mean so we can init ourselves to saner values. // Calculate resample_mean so we can init ourselves to saner values.
resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor;
/*
* now this should do it...
*/

outbuf = alloca( rlen * formats[format].sample_size * num_channels );

resampbuf = alloca( rlen * sizeof( float ) );


// get the data... // get the data...
again: again:
@@ -465,6 +466,32 @@ again:
return 0; return 0;
} }


/**
* the latency callback.
* sets up the latencies on the ports.
*/

void
latency_cb (jack_latency_callback_mode_t mode, void *arg)
{
jack_latency_range_t range;
JSList *node;

range.min = range.max = target_delay;

if (mode == JackCaptureLatency) {
for (node = capture_ports; node; node = jack_slist_next (node)) {
jack_port_t *port = node->data;
jack_port_set_latency_range (port, mode, &range);
}
} else {
for (node = playback_ports; node; node = jack_slist_next (node)) {
jack_port_t *port = node->data;
jack_port_set_latency_range (port, mode, &range);
}
}
}



/** /**
* Allocate the necessary jack ports... * Allocate the necessary jack ports...
@@ -661,6 +688,8 @@ int main (int argc, char *argv[]) {


jack_on_shutdown (client, jack_shutdown, 0); jack_on_shutdown (client, jack_shutdown, 0);


if (jack_set_latency_callback)
jack_set_latency_callback (client, latency_cb, 0);


// get jack sample_rate // get jack sample_rate
@@ -716,6 +745,17 @@ int main (int argc, char *argv[]) {
// alloc input ports, which are blasted out to alsa... // alloc input ports, which are blasted out to alsa...
alloc_ports( num_channels, 0 ); alloc_ports( num_channels, 0 );


outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels );
resampbuf = malloc( num_periods * period_size * sizeof( float ) );
tmpbuf = malloc( 512 * formats[format].sample_size * num_channels );

if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL))
{
fprintf( stderr, "no memory for buffers.\n" );
exit(20);
}

memset( tmpbuf, 0, 512 * formats[format].sample_size * num_channels);


/* tell the JACK server that we are ready to roll */ /* tell the JACK server that we are ready to roll */




+ 53
- 9
example-clients/alsa_out.c View File

@@ -11,12 +11,11 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>


#include <alloca.h>
#include <math.h> #include <math.h>


#include <jack/jack.h> #include <jack/jack.h>
#include <jack/jslist.h> #include <jack/jslist.h>
#include <memops.h>
#include <jack/memops.h>


#include "alsa/asoundlib.h" #include "alsa/asoundlib.h"


@@ -35,6 +34,7 @@ snd_pcm_t *alsa_handle;
int jack_sample_rate; int jack_sample_rate;
int jack_buffer_size; int jack_buffer_size;


int quit = 0;
double resample_mean = 1.0; double resample_mean = 1.0;
double static_resample_factor = 1.0; double static_resample_factor = 1.0;
double resample_lower_limit = 0.25; double resample_lower_limit = 0.25;
@@ -45,7 +45,6 @@ double *window_array;
int offset_differential_index = 0; int offset_differential_index = 0;


double offset_integral = 0; double offset_integral = 0;
int quit = 0;


// ------------------------------------------------------ commandline parameters // ------------------------------------------------------ commandline parameters


@@ -77,6 +76,12 @@ volatile float output_diff = 0.0;
snd_pcm_uframes_t real_buffer_size; snd_pcm_uframes_t real_buffer_size;
snd_pcm_uframes_t real_period_size; snd_pcm_uframes_t real_period_size;


// buffers

char *tmpbuf;
char *outbuf;
float *resampbuf;

// format selection, and corresponding functions from memops in a nice set of structs. // format selection, and corresponding functions from memops in a nice set of structs.


typedef struct alsa_format { typedef struct alsa_format {
@@ -90,6 +95,7 @@ typedef struct alsa_format {
alsa_format_t formats[] = { alsa_format_t formats[] = {
{ SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" },
{ SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" },
{ SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" },
{ SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" },
{ SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" }
}; };
@@ -311,8 +317,6 @@ double hann( double x )
*/ */
int process (jack_nframes_t nframes, void *arg) { int process (jack_nframes_t nframes, void *arg) {


char *outbuf;
float *resampbuf;
int rlen; int rlen;
int err; int err;
snd_pcm_sframes_t delay = target_delay; snd_pcm_sframes_t delay = target_delay;
@@ -321,7 +325,6 @@ int process (jack_nframes_t nframes, void *arg) {
delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ; delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ;


delay -= jack_frames_since_cycle_start( client ); delay -= jack_frames_since_cycle_start( client );
delay += jack_get_buffer_size( client ) / 2;
// Do it the hard way. // Do it the hard way.
// this is for compensating xruns etc... // this is for compensating xruns etc...


@@ -340,12 +343,15 @@ int process (jack_nframes_t nframes, void *arg) {
offset_array[i] = 0.0; offset_array[i] = 0.0;
} }
if( delay < (target_delay-max_diff) ) { if( delay < (target_delay-max_diff) ) {
char *tmp = alloca( (target_delay-delay) * formats[format].sample_size * num_channels );
memset( tmp, 0, formats[format].sample_size * num_channels * (target_delay-delay) );
snd_pcm_writei( alsa_handle, tmp, target_delay-delay );


output_new_delay = (int) delay; output_new_delay = (int) delay;


while ((target_delay-delay) > 0) {
snd_pcm_uframes_t to_write = ((target_delay-delay) > 512) ? 512 : (target_delay-delay);
snd_pcm_writei( alsa_handle, tmpbuf, to_write );
delay += to_write;
}

delay = target_delay; delay = target_delay;


// Set the resample_rate... we need to adjust the offset integral, to do this. // Set the resample_rate... we need to adjust the offset integral, to do this.
@@ -463,6 +469,32 @@ again:
return 0; return 0;
} }


/**
* the latency callback.
* sets up the latencies on the ports.
*/

void
latency_cb (jack_latency_callback_mode_t mode, void *arg)
{
jack_latency_range_t range;
JSList *node;

range.min = range.max = target_delay;

if (mode == JackCaptureLatency) {
for (node = capture_ports; node; node = jack_slist_next (node)) {
jack_port_t *port = node->data;
jack_port_set_latency_range (port, mode, &range);
}
} else {
for (node = playback_ports; node; node = jack_slist_next (node)) {
jack_port_t *port = node->data;
jack_port_set_latency_range (port, mode, &range);
}
}
}



/** /**
* Allocate the necessary jack ports... * Allocate the necessary jack ports...
@@ -659,6 +691,8 @@ int main (int argc, char *argv[]) {


jack_on_shutdown (client, jack_shutdown, 0); jack_on_shutdown (client, jack_shutdown, 0);


if (jack_set_latency_callback)
jack_set_latency_callback (client, latency_cb, 0);


// get jack sample_rate // get jack sample_rate
@@ -714,6 +748,16 @@ int main (int argc, char *argv[]) {
// alloc input ports, which are blasted out to alsa... // alloc input ports, which are blasted out to alsa...
alloc_ports( 0, num_channels ); alloc_ports( 0, num_channels );


outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels );
resampbuf = malloc( num_periods * period_size * sizeof( float ) );
tmpbuf = malloc( 512 * formats[format].sample_size * num_channels );

if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL))
{
fprintf( stderr, "no memory for buffers.\n" );
exit(20);
}



/* tell the JACK server that we are ready to roll */ /* tell the JACK server that we are ready to roll */




Loading…
Cancel
Save