I am posting this here for suggestions. As I said I’m not familiar with audio programming, but am willing to help (and learn when pointed in the right direction).
Funny thing is it only happens when exporting, I have no problems when running ‘normally’, not even when I record the output of the master bus, with Jamin inserted, into a new track in the same session.
With my fix, Jamin eventually succeeds in writing all of the bytes, and I cannot hear anything funny in the exported file.
While it’s great that you have such enthusiasm for fixing this issue - my concern came mainly from the comments such as
“I’m really puzzled as to why it works now.”
"Do any of you have any idea why this works ? Is this the right thing to do ? "
I think it may be better to study the code properly and understand the exact nature of the problem you are trying to solve before jumping straight in with the debug tools and applying patches if you are not really sure why they work.
Ok, in general I would agree, but I was hoping for some comments on whether a retry of jack_ringbuffer_write when the return value is less than the number passed is something that would be allowed in freewheeling mode (as the api states that the return value will be between 0 and cnt, what do we do when this is less than cnt?). I guess this is not the right forum to be asking such questions.
I have high regard for both Ardour and Jamin developers, so the original code will not have been written for nothing (although one could argue about the abort() without shutting down properly). But then again, would Jamin development have forseen it would be run in freewheeling mode ?
My enthusiasm comes mainly from various post I’ve seen around the issue, my annoyance with the problem, and the fact that everywhere Ardour+Jamin seems to be advised as the combination for mastering on Linux. It would be nice if that also ran ok on Ubuntu (as it seems only on Ubuntu problems with export+Jamin arise).
@kees: My comments weren’t really intended to be too negative - as I said, its great that you have the enthsiasm for fixing the problem, I just think this stuff can be more complex than it first appears and it is really necessary to get an overview of the entire system and how the problems you are seeing fit with that before changing one specific part - so as to avoid unwanted side-effects.
I have to confess I don’t really use JAMIN that much - although those that do speak highly of it (I have written my own set of JACK client audio processors which I prefer)
Last time I tried JAMIN I found it to be a little out-dated and it didn’t seem to be being developed much, IIRC it uses some LADSPA plugins to do the processing and I found some of them weren’t completely reliable.
@linuxdsp: No offense taken,
not anymore, I must confess: made me feel like a junior programmer who thought he had found something, but didn’t follow the proper procedure, it’s been many years since I felt like that, but well … keeps me humble; makes you think twice next time before you post something, or maybe not share anything at all
but you could have commented on the content rather than on the way of working. The topic of this issue still is Ardour & Jamin export, whether or not you use Jamin. And the problem had been around for quite some time and keeps getting stirred up. I tried to debug the issue and find Jamin goes into panic mode by a plain abort(), what can you do ?
I’ll tell you why I was puzzled: if a retry of the short writes works (or seems to), why didn’t the Jamin developers do that, it can’t be that easy, can it? Furthermore, it seems like a timing issue, because with a short sleep it seems to work eventually without errors reported, or maybe I was just lucky several times, and I know from experience that with timing issues you can be lucky for a long time.
Well, too much said anyway, I’ll leave it here.
I’ll have a look at your plugins.
@kees: From a brief look at the section of code you posted (I’m afraid I don’t really have time to get into the inner workings of the Jamin code - and the Jamin devs are almost certainly better placed to answer this…) then it would appear that your problem is caused because (as the comment in the code says) “The DSP thread is not keeping up - we have input audio with no where to go” so the buffer is overflowing. In other words the JACK audio callback is providing chunks of audio faster than the DSP thread can process them. Your fix would appear to be related to putting a sleep (in the jack audio processing callback?) which allows the DSP thread to catch up. You may get away with this in freewheel mode - but it is really not recommended for normal use. So it would be nicer if a fix could be found that didn’t require it at all.
My guess would be that it is actually the - necessary - decoupling between the two threads provided by the ring buffer that causes the problem in freewheel mode, since in this mode JACK will just free-run as fast as it can. Since the only limit for jacks processing speed is then the time taken to fill the ring buffer - not necessarily the time taken to process the audio there is a good chance it will overun. In a more simplistic architecture where the audio can be processed directly in the jack audio callback (without a ring buffer), jack would be inherently limited by the time taken to process a buffer of audio samples when running in freewheel mode. So your fix may achieve the ‘right’ result by slowing jack down - but by (in my opinion) the wrong means. I hope I have interpreted all this correctly - as I said - this is only based on the code snippet posted - please correct me if I’m wrong. (Although this forum is probably not the best place for a detailed discussion about how the code works)
@linuxdsp: now that’s a helpful comment (finally ), thanks !
I know too little about Jack et al. to judge whether you are right, but it makes sense. In the diff I’ve uploaded I made my fix dependent on Jack running in freewheeling mode, so normal operation still would have the strict condition.
My own Jamin problems only had to do with export, never had crashes in ‘normal’ mode (as far as I remember), so I may indeed get away with this ‘fix’. Still no real explanation why that mostly happens at the end (Ardour busy writing, Jamin keeping up with the graphics, ???).
Looking around in Jamin development, I get the feeling we’re ‘beating on a dead horse’, correct me if I’m wrong. Not sure if it’s worth the while to find the ‘real’ cause, also because many advise to use Ardour plugins instead of Jamin. It’s just that Jamin is really handy for quick improvement, clicking on all three ‘auto make’ buttons.
Thanks for your comment.
Jamin is absolutely still useful and worthwhile in my opinion.
It isn’t just the fact it uses the plugins, but also provides an interface suitable for the fine grained control you will need in mastering.
I’ve started a new topic on the jamin devel mailing list on the issue.
I saw, but am not really the best person to answer. Give them a few days though as it can take a bit for them to answer sometimes.
Kees, if possible could you put up a 64 bit deb of your fix? Thanks!
EDIT: I also use ardour with jamin as an insert and in the past export used to freeze after creating the file successfully as described in this thread. However recently in karmic, ardour had issues where it would frequently disconnect from jack. Then i found out a repo for jack2 (ppa:frasten) and then on using that everything ran really well and was incredibly stable. Except for jamin crashing on export.
I am currently getting around the problem by connecting the master outs to a stereo track in ardour and recording it and then exporting the bounced track only.One advantage i see is that before export, i can immediately check in ardour if the track has any clipping…if so then it can be normalised directly.
However the wierd thing is irrespective of whether i deactivate the insert on the master track or even if i disable the master track itself, jamin will crash even if i export only the selective track. So i usually need to close jamin before i do this.
A quick update from the comments I got from Jamin developers and some tests I’ve done: it seems that the main cause of the problem was my Jack setting having less than 256 frames/period.
“The natural FFT window size for the signal processing component of jamin is 256 frames. If JACK is running with a smaller window size, then jamin needs to queue the processing to a lower-priority real-time thread so it has enough time to perform the FFT (which is computationally expensive) while still meeting the JACK audio processing deadlines.” according to Jamin developer Jack O’Quin.
So I’ve tried several tests with 256 frames/period and I did not have the problem. Also, exporting with Jamin started with the -t flag seemed to solve the problem. A quick patch from Jack O’Quin running as if started with the -t flag in export (Jack freewheeling) mode and without otherwise, did not yet succeed, but that seems to be the direction of the definitive patch.
So, my problem seems to disappear when running with larger frames/period.
@mendred: could you try that too ? I have no 64bit machine to compile on, and would not advise to use my patch anyway, unless you have no other option. Compiling Jamin and installing yourself is really easy on Ubuntu. Besides that, what you describe, is exactly what I experience.
To quote Jamin developer Jan Depner: "There seems to be a lot of misunderstanding about when you need low latency. If you’re not running live or trying to record new tracks while using software monitoring you don’t really need low latency. JAMin wasn’t designed for live work and it wasn’t designed to be a plugin for a single track. It was designed for stereo audio mastering. The amount of processing involved is significant so it probably won’t be able to keep up with small period sizes. Just kick it up to 2048 and
@kees, starting jamin with as “jamin -t” works brilliantly :). Thanks…I am trying to setup jack when my machine starts, so really don’t want to keep switching frames (currently using 64). to movw from low to high…I tried the -t both in regular mode (when i am playing ardour tracks…) and during export…and so far no issues…so will continue to use this…
As for Jan’s comment…well i guess sometimes. we find new uses for things which they may not have been designed for…but nevertheless work very well…it seemed very logical to me use jamin as an insert on master…but I guess it all depends on your point of view.
Anyway this definitely works…so thanks again!
EDIT: Ah i see the downside to -t in realtime…a much larger no. of xruns…especially when u have a large no. of tracks…i guess then as u mention either use -t for export only purposes or use 256 frames…