<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[A5] Playing Samples on the Fly?</title>
		<link>http://www.allegro.cc/forums/view/614729</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 28 Oct 2014 17:15:39 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In my game, I have lots of short sounds that will be event triggered. However, I don&#39;t want to load them all into memory, instead, I just want to load, play, and destroy them after they are done playing.</p><p>Is there a way to do this? Mainly, is there an event I can receive when a sample has finished playing?</p><p>I can do it via polling but that feels like a big hack.</p><p>Thanks
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jmasterx)</author>
		<pubDate>Sat, 18 Oct 2014 20:08:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Not currently, no. </p><p>Which part of Allegro would fire off the audio events? The mixer, or the voice? I suppose it would have to be the mixer. It should have a list of SAMPLE_IDS that it is playing, and it should be able to detect when that sample is done playing. But when is the event fired? During the buffer update? That could lead to destroying a sample before it is finished mixing. Remember the sample that quit and post it to a queue of events to fire off before the next mixer update?</p><p>I&#39;m sure allegro could be hacked to do this, but I haven&#39;t looked at the actual code. There&#39;s probably a mixer callback controlled by a timer in a separate thread.</p><p>I personally would like to see this happen too. No promises, but I&#39;ll try to take a look at the code to at least see how feasible this is, and what would need to be done.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Sun, 19 Oct 2014 01:38:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yeah, I guess it&#39;s a bit trickier the way Allegro is designed. When I coded on ios a few months ago, every AVAudioPlayer object can attach a listener (AVAudioDelegate) and you get a callback when the player finishes playing.</p><p>But that doesn&#39;t involve a mixer and causes things like global gain to be trickier to implement.</p><p>it would be nice to have something like:
</p><div class="source-code snippet"><div class="inner"><pre>al_register_sample_instance_callback<span class="k2">(</span><span class="k2">(</span><span class="k1">void</span><span class="k3">*</span> callback<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_SAMPLE_INSTANCE"><span class="a">ALLEGRO_SAMPLE_INSTANCE</span></a><span class="k3">*</span> spl, <a href="http://www.allegro.cc/manual/ALLEGRO_MIXER"><span class="a">ALLEGRO_MIXER</span></a><span class="k3">*</span> mixer, <span class="k1">bool</span> finished<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

So if the sample gets destroyed, it could dispatch the callback with finished = false. But this probably would create all kinds of problems I&#39;m not considering.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jmasterx)</author>
		<pubDate>Sun, 19 Oct 2014 02:47:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think the magic happens in MAKE_MIXER, specifically in fix_looped_position.</p><div class="source-code"><div class="toolbar"><span class="name">kcm_mixer.c</span><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number"> 280</span><span class="p">#define MAKE_MIXER(NAME, NEXT_SAMPLE_VALUE, TYPE)                             \</span>
<span class="number"> 281</span><span class="p">static void NAME(void *source, void **vbuf, unsigned int *samples,            \ </span>
<span class="number"> 282</span><span class="p">   ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc)                        \ </span>
<span class="number"> 283</span><span class="p">{                                                                             \ </span>
<span class="number"> 284</span><span class="p">   ALLEGRO_SAMPLE_INSTANCE *spl = (ALLEGRO_SAMPLE_INSTANCE *)source;          \ </span>
<span class="number"> 285</span><span class="p">   TYPE *buf = *vbuf;                                                         \ </span>
<span class="number"> 286</span><span class="p">   size_t maxc = al_get_channel_count(spl-&gt;spl_data.chan_conf);               \ </span>
<span class="number"> 287</span><span class="p">   size_t samples_l = *samples;                                               \ </span>
<span class="number"> 288</span><span class="p">   size_t c;                                                                  \ </span>
<span class="number"> 289</span><span class="p">   int delta, delta_error;                                                    \ </span>
<span class="number"> 290</span><span class="p">   SAMP_BUF samp_buf;                                                         \ </span>
<span class="number"> 291</span><span class="p">                                                                              \ </span>
<span class="number"> 292</span><span class="p">   BRESENHAM;                                                                 \ </span>
<span class="number"> 293</span><span class="p">                                                                              \ </span>
<span class="number"> 294</span><span class="p">   if (!spl-&gt;is_playing)                                                      \ </span>
<span class="number"> 295</span><span class="p">      return;                                                                 \ </span>
<span class="number"> 296</span><span class="p">                                                                              \ </span>
<span class="number"> 297</span><span class="p">   while (samples_l &gt; 0) {                                                    \ </span>
<span class="number"> 298</span><span class="p">      const TYPE *s;                                                          \ </span>
<span class="number"> 299</span><span class="p">      int old_step = spl-&gt;step;                                               \ </span>
<span class="number"> 300</span><span class="p">                                                                              \ </span>
<span class="number"> 301</span><span class="p">      if (!fix_looped_position(spl))                                          \ </span>
<span class="number"> 302</span><span class="p">         return;                                                              \ </span>
<span class="number"> 303</span><span class="p">      if (old_step != spl-&gt;step) {                                            \ </span>
<span class="number"> 304</span><span class="p">         BRESENHAM;                                                           \ </span>
<span class="number"> 305</span><span class="p">      }                                                                       \ </span>
<span class="number"> 306</span><span class="p">                                                                              \ </span>
<span class="number"> 307</span><span class="p">      /* It might be worth preparing multiple sample values at once. */       \ </span>
<span class="number"> 308</span><span class="p">      s = (TYPE *) NEXT_SAMPLE_VALUE(&amp;samp_buf, spl, maxc);                   \ </span>
<span class="number"> 309</span><span class="p">                                                                              \ </span>
<span class="number"> 310</span><span class="p">      for (c = 0; c &lt; dest_maxc; c++) {                                       \ </span>
<span class="number"> 311</span><span class="p">         ALLEGRO_STATIC_ASSERT(kcm_mixer, ALLEGRO_MAX_CHANNELS == 8);         \ </span>
<span class="number"> 312</span><span class="p">         switch (maxc) {                                                      \ </span>
<span class="number"> 313</span><span class="p">            /* Each case falls through. */                                    \ </span>
<span class="number"> 314</span><span class="p">            case 8: *buf += s[7] * spl-&gt;matrix[c*maxc + 7];                   \ </span>
<span class="number"> 315</span><span class="p">            case 7: *buf += s[6] * spl-&gt;matrix[c*maxc + 6];                   \ </span>
<span class="number"> 316</span><span class="p">            case 6: *buf += s[5] * spl-&gt;matrix[c*maxc + 5];                   \ </span>
<span class="number"> 317</span><span class="p">            case 5: *buf += s[4] * spl-&gt;matrix[c*maxc + 4];                   \ </span>
<span class="number"> 318</span><span class="p">            case 4: *buf += s[3] * spl-&gt;matrix[c*maxc + 3];                   \ </span>
<span class="number"> 319</span><span class="p">            case 3: *buf += s[2] * spl-&gt;matrix[c*maxc + 2];                   \ </span>
<span class="number"> 320</span><span class="p">            case 2: *buf += s[1] * spl-&gt;matrix[c*maxc + 1];                   \ </span>
<span class="number"> 321</span><span class="p">            case 1: *buf += s[0] * spl-&gt;matrix[c*maxc + 0];                   \ </span>
<span class="number"> 322</span><span class="p">            default: break;                                                   \ </span>
<span class="number"> 323</span><span class="p">         }                                                                    \ </span>
<span class="number"> 324</span><span class="p">         buf++;                                                               \ </span>
<span class="number"> 325</span><span class="p">      }                                                                       \ </span>
<span class="number"> 326</span><span class="p">                                                                              \ </span>
<span class="number"> 327</span><span class="p">      spl-&gt;pos += delta;                                                      \ </span>
<span class="number"> 328</span><span class="p">      spl-&gt;pos_bresenham_error += delta_error;                                \ </span>
<span class="number"> 329</span><span class="p">      if (spl-&gt;pos_bresenham_error &gt;= spl-&gt;step_denom) {                      \ </span>
<span class="number"> 330</span><span class="p">         spl-&gt;pos++;                                                          \ </span>
<span class="number"> 331</span><span class="p">         spl-&gt;pos_bresenham_error -= spl-&gt;step_denom;                         \ </span>
<span class="number"> 332</span><span class="p">      }                                                                       \ </span>
<span class="number"> 333</span><span class="p">      samples_l--;                                                            \ </span>
<span class="number"> 334</span><span class="p">   }                                                                          \ </span>
<span class="number"> 335</span><span class="p">   fix_looped_position(spl);                                                  \ </span>
<span class="number"> 336</span><span class="p">   (void)buffer_depth;                                                        \ </span>
<span class="number"> 337</span><span class="p">} </span>
<span class="number"> 338</span>
<span class="number"> 339</span>MAKE_MIXER<span class="k2">(</span>read_to_mixer_point_float_32, point_spl32, <span class="k1">float</span><span class="k2">)</span>
<span class="number"> 340</span>MAKE_MIXER<span class="k2">(</span>read_to_mixer_linear_float_32, linear_spl32, <span class="k1">float</span><span class="k2">)</span>
<span class="number"> 341</span>MAKE_MIXER<span class="k2">(</span>read_to_mixer_cubic_float_32, cubic_spl32, <span class="k1">float</span><span class="k2">)</span>
<span class="number"> 342</span>MAKE_MIXER<span class="k2">(</span>read_to_mixer_point_int16_t_16, point_spl16, <span class="k1">int16_t</span><span class="k2">)</span>
<span class="number"> 343</span>MAKE_MIXER<span class="k2">(</span>read_to_mixer_linear_int16_t_16, linear_spl16, <span class="k1">int16_t</span><span class="k2">)</span>
<span class="number"> 344</span>
<span class="number"> 345</span><span class="p">#undef MAKE_MIXER</span>
</div></div><p>

</p><div class="source-code"><div class="toolbar"><span class="name">kcm_mixer.c</span><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number"> 165</span><span class="c">/* fix_looped_position:</span>
<span class="number"> 166</span><span class="c"> *  When a stream loops, this will fix up the position and anything else to</span>
<span class="number"> 167</span><span class="c"> *  allow it to safely continue playing as expected. Returns false if it</span>
<span class="number"> 168</span><span class="c"> *  should stop being mixed.</span>
<span class="number"> 169</span><span class="c"> */</span>
<span class="number"> 170</span><span class="k1">static</span> <span class="k1">bool</span> fix_looped_position<span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_SAMPLE_INSTANCE"><span class="a">ALLEGRO_SAMPLE_INSTANCE</span></a> <span class="k3">*</span>spl<span class="k2">)</span>
<span class="number"> 171</span><span class="k2">{</span>
<span class="number"> 172</span>   <span class="k1">bool</span> is_empty<span class="k2">;</span>
<span class="number"> 173</span>   <a href="http://www.allegro.cc/manual/ALLEGRO_AUDIO_STREAM"><span class="a">ALLEGRO_AUDIO_STREAM</span></a> <span class="k3">*</span>stream<span class="k2">;</span>
<span class="number"> 174</span>
<span class="number"> 175</span>   <span class="c">/* Looping! Should be mostly self-explanatory */</span>
<span class="number"> 176</span>   <span class="k1">switch</span> <span class="k2">(</span>spl-&gt;loop<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 177</span>      <span class="k1">case</span> ALLEGRO_PLAYMODE_LOOP:
<span class="number"> 178</span>         <span class="k1">if</span> <span class="k2">(</span>spl-&gt;loop_end <span class="k3">-</span> spl-&gt;loop_start <span class="k3">!</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 179</span>            <span class="k1">if</span> <span class="k2">(</span>spl-&gt;step <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 180</span>               <span class="k1">while</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">&gt;</span><span class="k3">=</span> spl-&gt;loop_end<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 181</span>                  spl-&gt;pos <span class="k3">-</span><span class="k3">=</span> <span class="k2">(</span>spl-&gt;loop_end <span class="k3">-</span> spl-&gt;loop_start<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 182</span>               <span class="k2">}</span>
<span class="number"> 183</span>            <span class="k2">}</span>
<span class="number"> 184</span>            <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>spl-&gt;step <span class="k3">&lt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 185</span>               <span class="k1">while</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">&lt;</span> spl-&gt;loop_start<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 186</span>                  spl-&gt;pos <span class="k3">+</span><span class="k3">=</span> <span class="k2">(</span>spl-&gt;loop_end <span class="k3">-</span> spl-&gt;loop_start<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 187</span>               <span class="k2">}</span>
<span class="number"> 188</span>            <span class="k2">}</span>
<span class="number"> 189</span>         <span class="k2">}</span>
<span class="number"> 190</span>         <span class="k1">return</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 191</span>
<span class="number"> 192</span>      <span class="k1">case</span> ALLEGRO_PLAYMODE_BIDIR:
<span class="number"> 193</span>         <span class="c">/* When doing bi-directional looping, you need to do a follow-up</span>
<span class="number"> 194</span><span class="c">          * check for the opposite direction if a loop occurred, otherwise</span>
<span class="number"> 195</span><span class="c">          * you could end up misplaced on small, high-step loops.</span>
<span class="number"> 196</span><span class="c">          */</span>
<span class="number"> 197</span>         <span class="k1">if</span> <span class="k2">(</span>spl-&gt;loop_end <span class="k3">-</span> spl-&gt;loop_start <span class="k3">!</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 198</span>            <span class="k1">if</span> <span class="k2">(</span>spl-&gt;step <span class="k3">&gt;</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 199</span>            check_forward:
<span class="number"> 200</span>               <span class="k1">if</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">&gt;</span><span class="k3">=</span> spl-&gt;loop_end<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 201</span>                  spl-&gt;step <span class="k3">=</span> <span class="k3">-</span>spl-&gt;step<span class="k2">;</span>
<span class="number"> 202</span>                  spl-&gt;pos <span class="k3">=</span> spl-&gt;loop_end <span class="k3">-</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">-</span> spl-&gt;loop_end<span class="k2">)</span> <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 203</span>                  <span class="k1">goto</span> check_backward<span class="k2">;</span>
<span class="number"> 204</span>               <span class="k2">}</span>
<span class="number"> 205</span>            <span class="k2">}</span>
<span class="number"> 206</span>            <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 207</span>            check_backward:
<span class="number"> 208</span>               <span class="k1">if</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">&lt;</span> spl-&gt;loop_start <span class="k3">|</span><span class="k3">|</span> spl-&gt;pos <span class="k3">&gt;</span><span class="k3">=</span> spl-&gt;loop_end<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 209</span>                  spl-&gt;step <span class="k3">=</span> <span class="k3">-</span>spl-&gt;step<span class="k2">;</span>
<span class="number"> 210</span>                  spl-&gt;pos <span class="k3">=</span> spl-&gt;loop_start <span class="k3">+</span> <span class="k2">(</span>spl-&gt;loop_start <span class="k3">-</span> spl-&gt;pos<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 211</span>                  <span class="k1">goto</span> check_forward<span class="k2">;</span>
<span class="number"> 212</span>               <span class="k2">}</span>
<span class="number"> 213</span>            <span class="k2">}</span>
<span class="number"> 214</span>         <span class="k2">}</span>
<span class="number"> 215</span>         <span class="k1">return</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 216</span>
<span class="number"> 217</span>      <span class="k1">case</span> ALLEGRO_PLAYMODE_ONCE:
<span class="number"> 218</span>         <span class="k1">if</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">&lt;</span> spl-&gt;spl_data.len<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 219</span>            <span class="k1">return</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 220</span>         <span class="k2">}</span>
<span class="number"> 221</span>         spl-&gt;pos <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 222</span>         spl-&gt;is_playing <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number"> 223</span>         <span class="k1">return</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number"> 224</span>
<span class="number"> 225</span>      <span class="k1">case</span> _ALLEGRO_PLAYMODE_STREAM_ONCE:
<span class="number"> 226</span>      <span class="k1">case</span> _ALLEGRO_PLAYMODE_STREAM_ONEDIR:
<span class="number"> 227</span>         <span class="k1">if</span> <span class="k2">(</span>spl-&gt;pos <span class="k3">&lt;</span> spl-&gt;spl_data.len<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 228</span>            <span class="k1">return</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number"> 229</span>         <span class="k2">}</span>
<span class="number"> 230</span>         stream <span class="k3">=</span> <span class="k2">(</span><a href="http://www.allegro.cc/manual/ALLEGRO_AUDIO_STREAM"><span class="a">ALLEGRO_AUDIO_STREAM</span></a> <span class="k3">*</span><span class="k2">)</span>spl<span class="k2">;</span>
<span class="number"> 231</span>         is_empty <span class="k3">=</span> <span class="k3">!</span>_al_kcm_refill_stream<span class="k2">(</span>stream<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 232</span>         <span class="k1">if</span> <span class="k2">(</span>is_empty <span class="k3">&amp;</span><span class="k3">&amp;</span> stream-&gt;is_draining<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 233</span>            stream-&gt;spl.is_playing <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number"> 234</span>         <span class="k2">}</span>
<span class="number"> 235</span>
<span class="number"> 236</span>         _al_kcm_emit_stream_events<span class="k2">(</span>stream<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 237</span>
<span class="number"> 238</span>         <span class="k1">return</span> <span class="k3">!</span><span class="k2">(</span>is_empty<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 239</span>   <span class="k2">}</span>
<span class="number"> 240</span>
<span class="number"> 241</span>   <a href="http://www.allegro.cc/manual/ASSERT"><span class="a">ASSERT</span></a><span class="k2">(</span><span class="k1">false</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 242</span>   <span class="k1">return</span> <span class="k1">false</span><span class="k2">;</span>
<span class="number"> 243</span><span class="k2">}</span>
</div></div><p>


In the case of ALLEGRO_PLAYMODE_ONCE fix_looped_position returns false. This could be used as a signal by MAKE_MIXER to fire a sample over event. You would also have to account for ALLEGRO_PLAYMODE_LOOP and BIDIR too, but fix_looped_position returns true for those, since they haven&#39;t stopped playing yet.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Sun, 19 Oct 2014 04:40:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve always thought that the audio add-on needed to fire off events. But that never happened.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Mon, 20 Oct 2014 16:27:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well, I think it makes sense to emit events when a sample / stream is over / loops.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Mon, 20 Oct 2014 21:46:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>My problem with using events for this is that it satisfies this use case only, and no other use cases. E.g. what if you wanted to play a second sample as soon as the first ended? You can&#39;t use an event for that, as there will a gap between when the sample ends and when the event is processed.</p><p>So from my point of view, this is where you pull out the good old ALLEGRO_AUDIO_STREAM and stream the samples yourself.</p><p>EDIT: The backends do have a finite buffer that provides you some latency during which this can be done, but there&#39;s no API to configure its size... that&#39;s a failing of the current system, I think. In principle, if you didn&#39;t mind the latency and had a dedicated thread for audio processing, events might work ok.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Tue, 21 Oct 2014 05:38:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/614729/1006208#target">SiegeLord</a> said:</div><div class="quote"><p>
 You can&#39;t use an event for that, as there will a gap between when the sample ends and when the event is processed.
</p></div></div><p>
Allow firing the event some X time before it ends, allowing the handler time to be ready to cue up the next sample.</p><p>Disclaimer: I&#39;ve not used Allegro 5 much.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Tue, 21 Oct 2014 07:09:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/614729/1006211#target">Chris Katko</a> said:</div><div class="quote"><p>  Allow firing the event some X time before it ends, allowing the handler time to be ready to cue up the next sample.</p></div></div><p>The delay is still non-deterministic (the audio runs on a separate thread, there&#39;s no synchronization between it and the main thread). There is also no mechanism to do &#39;conditional playback&#39; of a sample.</p><p>One final alternative to all this is to add a yet another audio source, that is based on callbacks. It&#39;d be very similar to ALLEGRO_AUDIO_STREAM but would have no internal buffering or anything else of the sort.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Tue, 21 Oct 2014 17:06:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/614729/1006208#target">SiegeLord</a> said:</div><div class="quote"><p>So from my point of view, this is where you pull out the good old ALLEGRO_AUDIO_STREAM and stream the samples yourself.</p></div></div><p>

+1
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Tue, 21 Oct 2014 18:38:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>For my use case, having a delay from the time the sample ends to the time the event is sent is perfectly okay. My use case was strictly for memory management purposes; the case when you have 100&#39;s of samples and one of them can be played at any given time, and you want to avoid loading all 100 samples into memory. I could easily stop a prior sample before starting another, but that would not sound right.</p><p>So I&#39;ll probably instead poll and check if my samples are done and destroy them as they finish playing.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jmasterx)</author>
		<pubDate>Tue, 21 Oct 2014 20:27:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What kind of latency are we talking about here? How big is the voice buffer, and how often is it refilled?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Wed, 22 Oct 2014 06:13:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/614729/1006248#target">Edgar Reynaldo</a> said:</div><div class="quote"><p> What kind of latency are we talking about here? How big is the voice buffer, and how often is it refilled? </p></div></div><p>This is backend dependent, which is the crux of the issue here: it&#39;s unpredictable. I haven&#39;t looked if this is just an API oversight, or some backends don&#39;t have a meaningful number you can change/query.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Wed, 22 Oct 2014 18:36:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p> ALLEGRO_AUDIO_STREAM</p></div></div><p>When two devs and Boobuigi recommend the same thing, you should take note.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Gideon Weems)</author>
		<pubDate>Tue, 28 Oct 2014 17:15:39 +0000</pubDate>
	</item>
</rss>
