DiracProcess refuses to continue once it returns zero

Discussion about the DSP Dimension's articles, tutorials and code.

Moderator: neuronaut

DiracProcess refuses to continue once it returns zero

Postby zmotula » 11.11.2010 12:11

Hello! I have the following code:

Code: Select all
long framesProcessed = DiracProcess(&buffer, kBufferFrameSize, dirac);


I am processing an audio stream, which means that framesProcessed can drop to zero in the middle of the stream (no more audio data for now) and I want to continue later when I have another batch of data ready. The problem is that Dirac seems to remember that it already processed all available data and does not call the data reading callback anymore. What am I doing wrong?

(I was able to get around the issue by not processing the data until I can be sure that Dirac won’t consume all the available data, but that feels like a hack.)
zmotula
 
Posts: 3
Joined: 25.10.2010 13:31

Re: DiracProcess refuses to continue once it returns zero

Postby neuronaut » 11.11.2010 14:34

In this case you will either have to supply zero data (sample frames) in your callback when there is no data to process (this will cause silence to be processed, which may or may not be what you want), or simply stop calling DiracProcess() until enough new data is available. Dirac depends on its callback being able to deliver the requested amount of sample frames. You need to make sure that you buffer enough data ahead of time so that this condition is met at all times, otherwise you will get drop-outs in your data.

HTH,
Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany

Re: DiracProcess refuses to continue once it returns zero

Postby zmotula » 15.11.2010 16:49

Thanks for the quick response. I’m not sure if I was clear enough, I’ll better show you my main processing loop:

Code: Select all
for (;;) {
    if (![soundSource hasFrames:kBufferFrameSize] && !finish)
        break;
    long framesProcessed = DiracProcess(&buffer, kBufferFrameSize, dirac);
     if (framesProcessed <= 0)
        break;
    [soundSink storeFrames:framesProcessed from:buffer];
}


In other words I make sure that the source buffer has at least kBufferFrameSize frames before calling DiracProcess. But for certain sizes of the source buffer the DiracProcess seems to request more than kBufferFrameSize frames from the source buffer. See this log trace for kBufferFrameSize = 8192:

Code: Select all
Requested frames: 6144, have 8192 in the source buffer.
Requested frames: 4423, have 2048 in the source buffer.
Requested frames: 4147, have 0 in the source buffer.


This is all during single call to DiracProcess. After source buffer returns zero, Dirac returns zero framesProcessed and the loop ends. When I have more data in the source buffer, I enter the loop again, but now DiracProcess does not even call the data callback and immediately returns zero. Am I being dumb somewhere?
zmotula
 
Posts: 3
Joined: 25.10.2010 13:31

Re: DiracProcess refuses to continue once it returns zero

Postby neuronaut » 15.11.2010 17:54

I think your use of kBufferFrameSize is what is confusing you. You are requesting kBufferFrameSize to be delivered to you by DiracProcess, which is your buffer size at the output side of your signal chain.

However, Dirac reads its input data via its callback and the number of frames that it requests might be more or less than your kBufferFrameSize, there is no way to tell (that number might change with parameter settings, lambda, quality and the sonic properties of the input signal). Really the only thing that you know for sure is that the input frames it requests are consecutive, and not random access.

The big chunk that is requested at the beginning of processing is due to Dirac's internal cache mechanism, which gets filled on the first request. You can set the internal cache to a smaller size by using the CacheGranularity property with DiracSetProperty(), but that might affect performance.

Time stretching is a non-linear process in that there is no 1:1 correspondence between input and output buffers. For instance, if you're time stretching a sound, Dirac will request less input frames than it produces output frames (or the same amount but less frequently), and vice-versa. Time stretching is inherently a process that changes the length of the signal, hence you can't simply use the output side for comparison at the input side.

So, a temporary solution (until we have a call that returns the number of frames Dirac is going to request at some future point) could work like this: instead of using kBufferFrameSize you should store the maximum number of frames that Dirac has requested via its callback, and use that number for comparison in -hasFrames (better yet, double that number to be on the safe side). Also, kBufferFrameSize should be as small as you can make it without slowing down performance, to ensure that DiracProcess() doesn't have a chance to request multiple buffers in one pass.

HTH
Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany

Re: DiracProcess refuses to continue once it returns zero

Postby zmotula » 15.11.2010 18:40

Ah! Thank you, you’re right. Perfect support, I appreciate this very much.
zmotula
 
Posts: 3
Joined: 25.10.2010 13:31


Return to The DSP Dimension

Who is online

Users browsing this forum: No registered users and 0 guests

cron