<div dir="ltr">I had an interesting (but short) twitter discussion with Leonard Ritter (@paniq) about synchronizing 3D sources in OpenAL , and was wondering if folk on this thread had ideas / input.<div><br></div><div>In brief, the problem is that there is a need to synchronize the playback of one 3D positional source with another at a sample accurate (i.e. sub-buffer) level. I can see a number of ways of going about this without OpenAL alterations, but they're all fairly involved.</div>
<div><br></div><div>Due to pitch and Doppler variations I don't think it's possible to implement an API which guarantees continuous synchronized playback of multiple spatial sources, but timing the start of one with a sample position of another should be possible.</div>
<div><br></div><div>My proposal would be a trigger API. Triggers have an event sample position (likely best using <span style="color:rgb(0,0,0);white-space:pre-wrap">AL_SAMPLE_OFFSET_LATENCY_SOFT i64v 32.32 int.fract format), and a list of sources to play (played all at once when the trigger is hit).</span></div>
<div><span style="color:rgb(0,0,0);white-space:pre-wrap"><br></span></div><div><span style="color:rgb(0,0,0);white-space:pre-wrap">Sources are modified to add a list of triggers, which are ordered when added.</span></div>
<div><span style="color:rgb(0,0,0);white-space:pre-wrap"><br></span></div><div><font color="#000000"><span style="white-space:pre-wrap">Processing of the triggers would appear to be best done in mixer.c, at the end of MixSource, or in alu.c during aluMixData where the source processing takes place (which would potentially make it easier to add the sources. This would be low overhead, in the case of no triggers one conditional branch per source, and only one extra integer test per source with a trigger.</span></font></div>
<div><br></div><div><div><font face="courier new, monospace"> /* apply triggers, example for just b4 Update source info in mixer.c*/</font></div><div><font face="courier new, monospace"> while( Source->trigger )</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> ALuint timeToGo = Source->trigger->time - Source->position;</font></div><div><font face="courier new, monospace"> if( timeToGo < DataPosInt ) //using int pos as example</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> // fire off event</font></div><div><font face="courier new, monospace"> EnqueueSourceDelayed( Source->trigger->source, // src to play</font></div>
<div><font face="courier new, monospace"> Source, // src of event</font></div><div><font face="courier new, monospace"> timeToGo ); // delay</font></div>
<div><font face="courier new, monospace"> Source->trigger = Source->trigger->next;</font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><span style="white-space:pre"> </span>else</font></div>
<div><font face="courier new, monospace"><span style="white-space:pre"> </span>{</font></div><div><font face="courier new, monospace"><span style="white-space:pre"> </span>break;</font></div><div><font face="courier new, monospace"> }</font></div>
<div><font face="courier new, monospace"> }</font></div><div><br></div></div>The EnqueueSourceDelayed function would add the sources to the list of playing sources with a delay which would attempt to time the beginning of the source with the sample offset required.<br>
<br>I'd be interested to know if people think that this would be useful, or if there is already some functionality I've missed which could achieve a similar objective. I'd be happy to take a look at making these changes for contribution to OpenAL, first of all detailing the API in greater depth for feedback.<br>
<br>Thanks for reading!<div><br>twitter: @dougbinks</div><div>web: <a href="http://www.enkisoftware.com/about.html#doug">http://www.enkisoftware.com/about.html#doug</a></div></div>