corrupted reading after some time
Brought to you by:
chrismorgan
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.
Anonymous
Test program
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.
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..
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;
}
There is the same code in the resampling section.
Romain
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/