[LAD] jack ringbuffer question

lieven moors lievenmoors at gmail.com
Wed Dec 2 02:22:57 UTC 2009


Hi everyone,

I just started writing my first c++ program, and I'm kind of stuck with
something I cannot understand. After a few days of trying to figure this
out, I decided to ask for more professional help. I'm working on a kind 
of arpeggiator for linux (which I intend to release under GPL).
The program uses a text file, in which the user can specify a number of
arpeggios. Each arpeggio is loaded into an object called 'Arp',
and for every Arp I make a jack port, and a ringbuffer.
(the port and ringbuffer are stored in an object called Arp_jack)
A seperate thread, watches the text file for modifications (using 
inotify), and every time the file is changed, the file is loaded afresh, 
and the new Arps are put in the respective ringbuffers. The ringbuffers 
have a size of two Arps, and the idea is that when a new Arp arrives, 
the old one is discarded. If there is only one Arp in the buffer, the 
program keeps on reading the same one.

This code is part of the inotify thread:

while (i < len)
{
  struct inotify_event *event;
  event = (struct inotify_event *) &buf[i];

  if ( event->wd == wd )
  {
    vector<Arp>* arps = new vector<Arp> ;
    read_load_file( arps ) ;

    for( uint x = 0; x < arps->size(); x++ )
    {
     const char* arp_char = reinterpret_cast<const char*>(&(*arps)[x]);
     jack_ringbuffer_write( (*ARPS_JACK)[x].rb, arp_char, sizeof( Arp ));
    }
    //delete arps ;
  }

The next code fragment comes from the process callback. As you can see,
I'm using jack_ringbuffer_get_read_vector to read the raw data, and I 
advance the the read pointer when a new arp is available:


if( (jack_ringbuffer_read_space( (*arps_jack)[i].rb ) ) ==
	(sizeof( Arp ) * 2) )
{
   jack_ringbuffer_read_advance( (*arps_jack)[i].rb, sizeof(Arp) ) ;
}

if( (jack_ringbuffer_read_space( (*arps_jack)[i].rb ) ) ==
	sizeof( Arp ) )
{
   jack_ringbuffer_data_t data[2] ;
   jack_ringbuffer_get_read_vector( (*arps_jack)[i].rb, data ) ;

   if ( data[0].len > 0 )
   {
    arp = reinterpret_cast<Arp*>( data[0].buf ) ;
    steps = &arp->steps ;
    scale = &arp->scale ;
   }
   else if( data[1].len > 0)
   {
    cout << "data in second part of ringbuffer, this should not
	happen!" <<  endl ;
   }

....

Now to the question. The code works as I expect, as long as I don't
delete the vector of arps in the inotify thread (see the commented 
line). When I do delete the vector, the program segfaults.
(and also when I allocate the vector on the stack, and it gets cleaned
up automatically)
I thought that writing to the ringbuffer with jack_ringbuffer_write
copies the data to the ringbuffer, so I don't understand why this should 
have an influence.  Is it a problem that I put the ringbuffer in
an object which is accessed by two different threads without using a
mutex? I've tried using a mutex,but I still had the segmentation fault. 
Any help with this would be really appreciated.

Thanks for your help,

Lieven





More information about the Linux-audio-dev mailing list