Menu

#2 corrupted reading after some time

open
nobody
None
5
2012-09-14
2007-12-25
Anonymous
No
Hi !

It seems bio2jack's input support tends to produce garbage after some time.

I've experencied it many times, when reading from an input, after periods from 1 hour to few minutes.

The attached test example was tested with jack's dummy driver, connected to another output, and failed after few minutes.

No such corruption seems to happen when using output.

Discussion

  • Nobody/Anonymous

    Test program

     
  • Nobody/Anonymous

    Logged In: NO

    Sorry, I wanted to add a bla.wav file with only wav header, but wasn't logged in when I sumbited..

    You can use the test program that way:
    touch /tmp/bla.wav
    ./test

    On another console:
    aplay -t wav -r 48000 -c 2 -f S16_LE /tmp/bla.wav

    After some time, the output is corrupted.

     
  • Toots

    Toots - 2007-12-26

    Logged In: YES
    user_id=1049569
    Originator: NO

    After moving a ERR message, the corruption seems to occur after a buffer overrun, I always have this kind of logs before:

    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 7993 bytes
    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 8192 bytes
    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 8192 bytes
    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 8192 bytes
    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 8192 bytes
    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 8192 bytes
    ERR: bio2jack.c::JACK_callback(793) buffer overrun of 8192 bytes

    I've written a quick and dirty work around I'll let you know if this works better..

     
  • Toots

    Toots - 2007-12-26

    Logged In: YES
    user_id=1049569
    Originator: NO

    I can confirm the bug, and propose a work around.

    It simply returns 0 when the buffer is full. That is exactly the same os keeping previous data until it has been read. Seems to me the good way to operate, since the other way is very delicate for thread safety (even actual code does nothing when tryGetDriver failed...).

    Here's a workaround that works here:
    --- bio2jack/bio2jack.c 2006-06-17 18:20:09.000000000 +0100
    +++ bio2jack.wo/bio2jack.c 2007-12-26 18:09:27.000000000 +0100
    @@ -789,22 +789,24 @@
    it seems like it's better to throw away old data than new /
    if(write_space < jack_bytes)
    {
    - /
    the ringbuffer is designed such that only one thread should ever access each pointer.
    - since calling read_advance here will be touching the read pointer which is also accessed
    - by JACK_Read, we need to lock the mutex first for safety /
    - jack_driver_t
    d = tryGetDriver(drv->deviceID);
    - if( d )
    - {
    - / double check the write space after we've gained the lock, just
    - in case JACK_Read was being called before we gained it
    /
    - write_space = jack_ringbuffer_write_space(drv->pRecPtr);
    - if(write_space < jack_bytes)
    - {
    - ERR("buffer overrun of %ld bytes\n", jack_bytes - write_space);
    - jack_ringbuffer_read_advance(drv->pRecPtr, jack_bytes - write_space);
    - }
    - releaseDriver(drv);
    - }
    + ERR("buffer overrun of %ld bytes\n", jack_bytes - write_space);
    +
    +// / the ringbuffer is designed such that only one thread should ever access each pointer.
    +// since calling read_advance here will be touching the read pointer which is also accessed
    +// by JACK_Read, we need to lock the mutex first for safety
    /
    +// jack_driver_t d = tryGetDriver(drv->deviceID);
    +// if( d )
    +// {
    +// /
    double check the write space after we've gained the lock, just
    +// in case JACK_Read was being called before we gained it */
    +// write_space = jack_ringbuffer_write_space(drv->pRecPtr);
    +// if(write_space < jack_bytes)
    +// {
    +// jack_ringbuffer_read_advance(drv->pRecPtr, jack_bytes - write_space);
    +// }
    +// releaseDriver(drv);
    +// }
    + return 0;
    }

         jack_ringbuffer_write(drv->pRecPtr, drv->callback_buffer1,
    

    There is the same code in the resampling section.

    Romain

     
  • Toots

    Toots - 2007-12-26

    Logged In: YES
    user_id=1049569
    Originator: NO

    Hi again !

    I've been testing various fix, like writting only write_space bytes, or not doing anything when the lock cannot be taken, but the corruption always occured...

    On the other hand, just doing nothing when there is not enough space seems to work very kindly, and I cannot hear anything. I also noticed it's how ices-kh does in this case.

    You can find a complete patch that also removes the no more needed function tryGetDriver there:
    http://www.rastageeks.org/~toots/bio2jack/

     

Anonymous
Anonymous

Add attachments
Cancel