wmme limit host buffer size to 32k. try to make host buffer size a factor of over-limit user buffer size. closes #189
This commit is contained in:
parent
6aa858c0f7
commit
16f40db4c8
1 changed files with 92 additions and 37 deletions
|
|
@ -1368,6 +1368,48 @@ static unsigned long ComputeHostBufferCountForFixedBufferSizeFrames(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned long ComputeHostBufferSizeGivenHardUpperLimit(
|
||||||
|
unsigned long userFramesPerBuffer,
|
||||||
|
unsigned long absoluteMaximumBufferSizeFrames )
|
||||||
|
{
|
||||||
|
static unsigned long primes_[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23,
|
||||||
|
29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 0 }; /* zero terminated */
|
||||||
|
|
||||||
|
unsigned long result = userFramesPerBuffer;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
assert( absoluteMaximumBufferSizeFrames > 67 ); /* assume maximum is large and we're only factoring by small primes */
|
||||||
|
|
||||||
|
/* search for the largest integer factor of userFramesPerBuffer less
|
||||||
|
than or equal to absoluteMaximumBufferSizeFrames */
|
||||||
|
|
||||||
|
/* repeatedly divide by smallest prime factors until a buffer size
|
||||||
|
smaller than absoluteMaximumBufferSizeFrames is found */
|
||||||
|
while( result > absoluteMaximumBufferSizeFrames ){
|
||||||
|
|
||||||
|
/* search for the smallest prime factor of result */
|
||||||
|
for( i=0; primes_[i] != 0; ++i )
|
||||||
|
{
|
||||||
|
unsigned long p = primes_[i];
|
||||||
|
unsigned long divided = result / p;
|
||||||
|
if( divided*p == result )
|
||||||
|
{
|
||||||
|
result = divided;
|
||||||
|
break; /* continue with outer while loop */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( primes_[i] == 0 )
|
||||||
|
{ /* loop failed to find a prime factor, return an approximate result */
|
||||||
|
unsigned long d = (userFramesPerBuffer + (absoluteMaximumBufferSizeFrames-1))
|
||||||
|
/ absoluteMaximumBufferSizeFrames;
|
||||||
|
return userFramesPerBuffer / d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PaError SelectHostBufferSizeFramesAndHostBufferCount(
|
static PaError SelectHostBufferSizeFramesAndHostBufferCount(
|
||||||
unsigned long suggestedLatencyFrames,
|
unsigned long suggestedLatencyFrames,
|
||||||
unsigned long userFramesPerBuffer,
|
unsigned long userFramesPerBuffer,
|
||||||
|
|
@ -1387,16 +1429,26 @@ static PaError SelectHostBufferSizeFramesAndHostBufferCount(
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
effectiveUserFramesPerBuffer = userFramesPerBuffer;
|
if( userFramesPerBuffer > absoluteMaximumBufferSizeFrames ){
|
||||||
|
|
||||||
if( effectiveUserFramesPerBuffer > absoluteMaximumBufferSizeFrames ){
|
/* user has requested a user buffer that's larger than absoluteMaximumBufferSizeFrames.
|
||||||
/* user has requested a user buffer that's larger than absoluteMaximumBufferSizeFrames */
|
try to choose a buffer size that is equal or smaller than absoluteMaximumBufferSizeFrames
|
||||||
|
but is also an integer factor of userFramesPerBuffer, so as to distribute computation evenly.
|
||||||
/* @todo FIXME/REVIEW right now we allow the user to request an oversize host buffer,
|
the buffer processor will handle the block adaption between host and user buffer sizes.
|
||||||
even though elsewhere in the code there are suggestions that oversize buffers
|
see http://www.portaudio.com/trac/ticket/189 for discussion.
|
||||||
can cause crashes with some drivers. see http://www.portaudio.com/trac/ticket/189
|
*/
|
||||||
*/
|
|
||||||
/* return paBufferTooBig; */
|
effectiveUserFramesPerBuffer = ComputeHostBufferSizeGivenHardUpperLimit( userFramesPerBuffer, absoluteMaximumBufferSizeFrames );
|
||||||
|
assert( effectiveUserFramesPerBuffer <= absoluteMaximumBufferSizeFrames );
|
||||||
|
|
||||||
|
/* try to ensure that duration of host buffering is at least as
|
||||||
|
large as duration of user buffer. */
|
||||||
|
if( suggestedLatencyFrames < userFramesPerBuffer )
|
||||||
|
suggestedLatencyFrames = userFramesPerBuffer;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
effectiveUserFramesPerBuffer = userFramesPerBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1407,39 +1459,42 @@ static PaError SelectHostBufferSizeFramesAndHostBufferCount(
|
||||||
*hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames(
|
*hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames(
|
||||||
suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount );
|
suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount );
|
||||||
|
|
||||||
/*
|
if( *hostBufferSizeFrames >= userFramesPerBuffer )
|
||||||
If there are too many host buffers we would like to coalesce
|
|
||||||
them by packing an integer number of user buffers into each host buffer.
|
|
||||||
We try to coalesce such that hostBufferCount will lie between
|
|
||||||
PA_MME_TARGET_HOST_BUFFER_COUNT_ and (PA_MME_TARGET_HOST_BUFFER_COUNT_*2)-1.
|
|
||||||
We limit coalescing to avoid exceeding either absoluteMaximumBufferSizeFrames and
|
|
||||||
preferredMaximumBufferSizeFrames.
|
|
||||||
|
|
||||||
First, compute a coalescing factor: the number of user buffers per host buffer.
|
|
||||||
The goal is to achieve PA_MME_TARGET_HOST_BUFFER_COUNT_ total buffer count.
|
|
||||||
Since our latency is computed based on (*hostBufferCount - 1) we compute a
|
|
||||||
coalescing factor based on (*hostBufferCount - 1) and (PA_MME_TARGET_HOST_BUFFER_COUNT_-1).
|
|
||||||
|
|
||||||
The + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2) term below is intended to round up.
|
|
||||||
*/
|
|
||||||
numberOfUserBuffersPerHostBuffer = ((*hostBufferCount - 1) + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2)) / (PA_MME_TARGET_HOST_BUFFER_COUNT_ - 1);
|
|
||||||
|
|
||||||
if( numberOfUserBuffersPerHostBuffer > 1 )
|
|
||||||
{
|
{
|
||||||
unsigned long maxCoalescedBufferSizeFrames = (absoluteMaximumBufferSizeFrames < preferredMaximumBufferSizeFrames) /* minimum of our limits */
|
/*
|
||||||
? absoluteMaximumBufferSizeFrames
|
If there are too many host buffers we would like to coalesce
|
||||||
: preferredMaximumBufferSizeFrames;
|
them by packing an integer number of user buffers into each host buffer.
|
||||||
|
We try to coalesce such that hostBufferCount will lie between
|
||||||
|
PA_MME_TARGET_HOST_BUFFER_COUNT_ and (PA_MME_TARGET_HOST_BUFFER_COUNT_*2)-1.
|
||||||
|
We limit coalescing to avoid exceeding either absoluteMaximumBufferSizeFrames and
|
||||||
|
preferredMaximumBufferSizeFrames.
|
||||||
|
|
||||||
unsigned long maxUserBuffersPerHostBuffer = maxCoalescedBufferSizeFrames / effectiveUserFramesPerBuffer; /* don't coalesce more than this */
|
First, compute a coalescing factor: the number of user buffers per host buffer.
|
||||||
|
The goal is to achieve PA_MME_TARGET_HOST_BUFFER_COUNT_ total buffer count.
|
||||||
|
Since our latency is computed based on (*hostBufferCount - 1) we compute a
|
||||||
|
coalescing factor based on (*hostBufferCount - 1) and (PA_MME_TARGET_HOST_BUFFER_COUNT_-1).
|
||||||
|
|
||||||
if( numberOfUserBuffersPerHostBuffer > maxUserBuffersPerHostBuffer )
|
The + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2) term below is intended to round up.
|
||||||
numberOfUserBuffersPerHostBuffer = maxUserBuffersPerHostBuffer;
|
*/
|
||||||
|
numberOfUserBuffersPerHostBuffer = ((*hostBufferCount - 1) + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2)) / (PA_MME_TARGET_HOST_BUFFER_COUNT_ - 1);
|
||||||
|
|
||||||
|
if( numberOfUserBuffersPerHostBuffer > 1 )
|
||||||
|
{
|
||||||
|
unsigned long maxCoalescedBufferSizeFrames = (absoluteMaximumBufferSizeFrames < preferredMaximumBufferSizeFrames) /* minimum of our limits */
|
||||||
|
? absoluteMaximumBufferSizeFrames
|
||||||
|
: preferredMaximumBufferSizeFrames;
|
||||||
|
|
||||||
*hostBufferSizeFrames = effectiveUserFramesPerBuffer * numberOfUserBuffersPerHostBuffer;
|
unsigned long maxUserBuffersPerHostBuffer = maxCoalescedBufferSizeFrames / effectiveUserFramesPerBuffer; /* don't coalesce more than this */
|
||||||
|
|
||||||
/* recompute hostBufferCount to approximate suggestedLatencyFrames now that hostBufferSizeFrames is larger */
|
if( numberOfUserBuffersPerHostBuffer > maxUserBuffersPerHostBuffer )
|
||||||
*hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames(
|
numberOfUserBuffersPerHostBuffer = maxUserBuffersPerHostBuffer;
|
||||||
suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount );
|
|
||||||
|
*hostBufferSizeFrames = effectiveUserFramesPerBuffer * numberOfUserBuffersPerHostBuffer;
|
||||||
|
|
||||||
|
/* recompute hostBufferCount to approximate suggestedLatencyFrames now that hostBufferSizeFrames is larger */
|
||||||
|
*hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames(
|
||||||
|
suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return paNoError;
|
return paNoError;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue