Closed munshkr closed 9 years ago
Hmm, I just came across a sample that causes Dirt to segfault, so let me check and test a bit more, just in case.
OK, there was a small bug, I think it's fixed :)
Thanks for this I merged it but I don't like the behaviour as it stands.
E.g. if I run this:
d1 $ sound "bd sn:2*2"
then this:
d1 $ sound "bd:2 sn:2*2"
the first time round the bass drum isn't played. It'd be much better if it was late by a few samples in that case.
I guess part of the problem is when it starts loading the sample. It should do that as soon as the OSC message comes in.. I'll have a look into it.
Sorry I reverted it again, this change of behaviour won't work out in many situations.
I'm surprised this doesn't work out better, there's 0.04 seconds of latency in which dirt can load its samples, and as far as I can tell dirt is using it.
I think what we need though is a way that sample triggers are still queued even if samples aren't loaded yet, and only get dequeued when they are. This could be a runtime option - whether to drop late triggers or not.
I see what you mean... For small samples, it should take little time and could play them as soon as it's loaded. Do you think preloading as soon as Dirt receives the OSC message would solve this problem in most cases?
I think what we need though is a way that sample triggers are still queued even if samples aren't loaded yet, and only get dequeued when they are. This could be a runtime option - whether to drop late triggers or not.
If I understood correctly, you're saying that when file_get
fails to get a cached sample and needs to read from disk, it should queue that audio_play
call, and when sample is finally loaded, dequeue and retrigger it?
Do you think preloading as soon as Dirt receives the OSC message would solve this problem in most cases? Yes although from my brief look, it seems to be doing that already. I could be wrong!
If I understood correctly, you're saying that when file_get fails to get a cached sample and needs to read from disk, it should queue that audio_play call, and when sample is finally loaded, dequeue and retrigger it?
Yes, not sure whether it needs a special queue for this, I guess that would be the ideal situation..
:+1: I'll try to solve this and let you know. Thanks!
@yaxu OK, I've been working on this and I think I managed to solve the issue you mentioned...
Basically Dirt now calls audio_play
again, with the same arguments, as soon as the sample is loaded. There was no need for a queue because a thread only handles one sample so I just needed to pass a copy of the arguments to the thread start routine as a callback function.
I also added a command-line option to enable or disable late triggering, just in case someone doesn't want late triggers. I left it enabled as default so it behaves as always. Because, actually, most of the time Dirt plays samples really fast :) Especially if you keep them normalized to skip samplerate conversion, for instance.
I'll keep testing it a bit more before submitting a new PR, but you can have a look here if you want.
Whenever Dirt needs to load up a new sample from disk, it now creates a thread for reading and loading sound data into cache. Meanwhile the main thread continues playing, solving the problem with large sample files blocking the main execution thread.
To keep it simple, I made it so that there can only be one thread for file reading (that is, there are no queues), and to enforce that, there is a boolean variable (and its corresponding mutex) that determines if there is actually one running. If there is, skip file loading.
This changeset has a (nice) side effect that makes Dirt play a sample at a specific time only if it's already loaded in the samples cache, meaning that the first time you try to play an unloaded sample, it will not actually play until the next "tick" after it's been loaded in the cache. I think this is actually better than the old behavior, because now it will always play a sample in the right moment, even if it's delayed a bit more than before (because it used to play just after loading it).