[LAD] jack ringbuffer question

From: lieven moors <lievenmoors@email-addr-hidden>
Date: Wed Dec 02 2009 - 04:22:57 EET

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

_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/mailman/listinfo/linux-audio-dev
Received on Wed Dec 2 08:15:01 2009

This archive was generated by hypermail 2.1.8 : Wed Dec 02 2009 - 08:15:01 EET