[Etoys] Patch to fix sound delay issue

Yoshiki Ohshima yoshiki at squeakland.org
Mon Dec 4 15:45:44 EST 2006


  Takashi,

  The attached vm-sound-ALSA does shorten the delay when I play sound
from PianoKeyboard, but for a longer sound, it doesn't work as
expected.  The buffer underrun seems to be happening a lot, and also I
might guess that the index to fill the buffer may be wrong.

  Now you have one, try

  SampledSound stereoBachFugue play

and see (hear) how it sounds.

-- Yoshiki

Takashi Yamamiya wrote:
> 
> [1  <text/plain; ISO-2022-JP (7bit)>]
> Hi Ian, and folks,
> 
> I fixed the issue of sound latency in ALSA. I tried minimize the delay
> as well as possible. I have tested it on my Fedora Core with VMWare,
> and A-board.
> 
> - Minimum delay size depends on the sound buffer size (periods
>   frames in ALSA term).
> - If underrun error happens, the delay is extended longer.
> - If nothing wrong, the delay becomes shorter.
> - sound_AvailableSpace() (#primSoundAvailableBytes) answers always the
>   buffer size (periods frames) if the delay is short enough.
> 
> Yoshiki, could you test it on B-Board?
> 
> Thank you,
> - Takashi
> [2 alsa-fixDelay-tak.diff <text/plain (base64)>]
> Index: platforms/unix/vm-sound-ALSA/sqUnixSoundALSA.c
> ===================================================================
> --- platforms/unix/vm-sound-ALSA/sqUnixSoundALSA.c	(revision 1592)
> +++ platforms/unix/vm-sound-ALSA/sqUnixSoundALSA.c	(working copy)
> @@ -69,6 +69,7 @@
>  static int			 output_channels= 0;
>  static int			 output_buffer_frames_size= 0;
>  static int			 output_buffer_frames_available= 0;
> +static double			 max_delay_frames = 0;
>  
>  static void output_callback(snd_async_handler_t *handler)
>  {
> @@ -120,8 +121,9 @@
>    snd(pcm_sw_params_set_xfer_align(output_handle, swparams, 1), "sound_Start: snd_pcm_sw_params_set_xfer_align");
>    snd(pcm_sw_params(output_handle, swparams), "sound_Start: snd_pcm_sw_params");
>  
> -  output_buffer_frames_size= frameCount;
> +  output_buffer_frames_size= frames;
>    output_buffer_frames_available= 1;
> +  max_delay_frames = frames * 1.5; /* set initial delay frames */
>  
>    snd(pcm_nonblock(output_handle, 1), "sound_Start: snd_pcm_nonblock");
>    snd(async_add_pcm_handler(&output_handler, output_handle, output_callback, 0), "soundStart: snd_add_pcm_handler");
> @@ -152,17 +154,35 @@
>    return 1;
>  }
>  
> +/* Answers periods frame size, or zero if the delay is over. */
> +
>  static sqInt sound_AvailableSpace(void)
>  {
> -  if (output_handle)
> -    {
> -      int count = snd_pcm_avail_update(output_handle);
> -      if (count >= 0)
> -	return count;
> -      fprintf(stderr, "sound_AvailableSpace: snd_pcm_avail_update: %s\n", snd_strerror(count));
> -      snd_pcm_prepare(output_handle);
> -    }
> -  return 0;
> +  snd_pcm_sframes_t delay; /* distance to playback point (in frames) */
> +  snd_pcm_state_t state;
> +  sqInt avail = 0;
> +
> +  if (!output_handle) return 0;
> +      
> +  snd_pcm_delay(output_handle, &delay);
> +  state = snd_pcm_state (output_handle);
> +
> +  /* if underrun causes, max delay is loosened */
> +  if (state == SND_PCM_STATE_XRUN) {
> +    max_delay_frames = max_delay_frames * 1.5;
> +  }
> +
> +  /* if the state is not running, new sound is needed bacause nobody can
> +     signal the semaphore. */
> +  if (delay < max_delay_frames || state != SND_PCM_STATE_RUNNING) {
> +    avail = output_buffer_frames_size;
> +    double new_delay = max_delay_frames * 0.9995;
> +    max_delay_frames = new_delay > output_buffer_frames_size ?
> +      new_delay : output_buffer_frames_size;  
> +  }
> +  //  fprintf(stderr, "delay=%i, avail=%i, state=%i, delay=%.1fms\n",
> +  //	  (int) delay, avail, state, 1000 * max_delay_frames / 22050);
> +  return avail * output_channels * 2; /* bytes */
>  }
>  
>  static sqInt  sound_InsertSamplesFromLeadTime(sqInt frameCount, sqInt srcBufPtr, sqInt samplesOfLeadTime)	FAIL(frameCount)
> [3 vm-sound-ALSA.gz <application/gzip (base64)>]
> 
> [4  <text/plain; us-ascii (7bit)>]
> _______________________________________________
> Etoys mailing list
> Etoys at laptop.org
> http://mailman.laptop.org/mailman/listinfo/etoys


More information about the Etoys mailing list