squeak-vm/squeak-vm-4.10.2.2614-alsa-fixes.patch

158 lines
6.6 KiB
Diff
Raw Normal View History

--- trunk/platforms/unix/vm-sound-ALSA/sqUnixSoundALSA.c 2013/03/26 01:49:32 2711
+++ trunk/platforms/unix/vm-sound-ALSA/sqUnixSoundALSA.c 2013/04/04 05:05:14 2712
@@ -2,7 +2,7 @@
*
* Author: Ian.Piumarta@squeakland.org
*
- * Last edited: 2010-04-01 13:48:37 by piumarta on emilia-2.local
+ * Last edited: 2013-04-04 13:59:35 by piumarta on linux32
*
* Copyright (C) 2006 by Ian Piumarta
* All rights reserved.
@@ -65,8 +65,10 @@
/* output */
+#if 0
#define SQ_SND_PLAY_START_THRESHOLD 7/8
#define SQ_SND_PLAY_AVAIL_MIN 4/8
+#endif
static snd_pcm_t *output_handle= 0;
static snd_async_handler_t *output_handler= 0;
@@ -99,8 +101,8 @@
int err;
snd_pcm_hw_params_t *hwparams;
snd_pcm_sw_params_t *swparams;
+ snd_pcm_uframes_t period_size;
unsigned int uval;
- int dir;
if (output_handle) sound_Stop();
@@ -114,18 +116,25 @@
snd_pcm_hw_params_set_format(output_handle, hwparams, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(output_handle, hwparams, output_channels);
uval= samplesPerSec;
- snd_pcm_hw_params_set_rate_near(output_handle, hwparams, &uval, &dir);
+ snd_pcm_hw_params_set_rate_near(output_handle, hwparams, &uval, 0);
output_buffer_period_size= frameCount;
- snd_pcm_hw_params_set_period_size_near(output_handle, hwparams, &output_buffer_period_size, &dir);
+ snd_pcm_hw_params_set_period_size_near(output_handle, hwparams, &output_buffer_period_size, 0);
snd(pcm_hw_params(output_handle, hwparams), "sound_Start: snd_pcm_hw_params");
snd_pcm_sw_params_alloca(&swparams);
snd(pcm_sw_params_current(output_handle, swparams), "sound_Start: snd_pcm_sw_params_current");
+#if 0
snd(pcm_sw_params_set_start_threshold(output_handle, swparams, frameCount * SQ_SND_PLAY_START_THRESHOLD), "sound_Start: snd_pcm_sw_params_set_start_threshold");
snd(pcm_sw_params_set_avail_min(output_handle, swparams, frameCount * SQ_SND_PLAY_AVAIL_MIN), "sound_Start: snd_pcm_sw_parama_set_avail_min");
+#endif
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");
+
+ snd(pcm_hw_params_get_period_size(hwparams, &period_size, 0), "sound_Start: pcm_hw_params_get_period_size");
snd(pcm_hw_params_get_buffer_size(hwparams, &output_buffer_size), "sound_Start: pcm_hw_params_get_buffer_size");
+ snd(pcm_sw_params_set_avail_min(output_handle, swparams, period_size), "sound_Start: snd_pcm_sw_parama_set_avail_min");
+ snd(pcm_sw_params_set_start_threshold(output_handle, swparams, output_buffer_size), "sound_Start: snd_pcm_sw_params_set_start_threshold");
+
output_buffer_frames_available= 1;
max_delay_frames= output_buffer_period_size * 2; /* set initial delay frames */
@@ -200,6 +209,7 @@
static sqInt sound_PlaySamplesFromAtLength(sqInt frameCount, void *srcBufPtr, sqInt startIndex)
{
+#if 0
if (output_handle)
{
void *samples= srcBufPtr + startIndex * output_channels * 2;
@@ -222,6 +232,41 @@
return count;
}
success(false);
+#else
+ if (!output_handle)
+ success(false);
+ else {
+ void *samples= srcBufPtr + startIndex * output_channels * 2;
+ int count= snd_pcm_writei(output_handle, samples, frameCount);
+
+ if (count < frameCount / 2)
+ output_buffer_frames_available= 0;
+
+ if (count >= 0)
+ return count;
+
+ switch (count) {
+ case -EPIPE: { /* under-run */
+ int err= snd_pcm_prepare(output_handle);
+ if (err < 0) fprintf(stderr, "sound_PlaySamples: can't recover from underrun, snd_pcm_prepare failed: %s", snd_strerror(err));
+ break;
+ }
+ case -ESTRPIPE: { /* stream suspended */
+ int err;
+ int timeout= 5; /* half a second */
+ while (-EAGAIN == (err= snd_pcm_resume(output_handle)) && timeout--)
+ usleep(100000); /* wait 1/10 of a second for suspend flag to be released */
+ if (-EAGAIN == err) break; /* return to interpreter and try to recover next time around */
+ if (err < 0) err= snd_pcm_prepare(output_handle);
+ if (err < 0) fprintf(stderr, "sound_PlaySamples: can't recover from suspend, snd_pcm_prepare failed: %s", snd_strerror(err));
+ break;
+ }
+ default:
+ fprintf(stderr, "snd_pcm_writei returned %i\n", count);
+ break;
+ }
+ }
+#endif
return 0;
}
@@ -231,8 +276,10 @@
/* input */
+#if 0
#define SQ_SND_REC_START_THRESHOLD 4/8
#define SQ_SND_REC_AVAIL_MIN 4/8
+#endif
static snd_pcm_t *input_handle= 0;
static snd_async_handler_t *input_handler= 0;
@@ -262,7 +309,8 @@
snd_pcm_hw_params_t *hwparams;
snd_pcm_sw_params_t *swparams;
snd_pcm_uframes_t frames;
- int dir;
+ snd_pcm_uframes_t period_size;
+ snd_pcm_uframes_t buffer_size;
if (input_handle) sound_StopRecording();
@@ -276,15 +324,23 @@
snd_pcm_hw_params_set_format(input_handle, hwparams, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(input_handle, hwparams, input_channels);
input_rate= desiredSamplesPerSec;
- snd_pcm_hw_params_set_rate_near(input_handle, hwparams, &input_rate, &dir);
+ snd_pcm_hw_params_set_rate_near(input_handle, hwparams, &input_rate, 0);
frames= 4096;
- snd_pcm_hw_params_set_period_size_near(input_handle, hwparams, &frames, &dir);
+ snd_pcm_hw_params_set_period_size_near(input_handle, hwparams, &frames, 0);
snd(pcm_hw_params(input_handle, hwparams), "sound_StartRecording: snd_pcm_hw_params");
+ snd(pcm_hw_params_get_period_size(hwparams, &period_size, 0), "sound_Start: pcm_hw_params_get_period_size");
+ snd(pcm_hw_params_get_buffer_size(hwparams, &buffer_size), "sound_Start: pcm_hw_params_get_buffer_size");
+
snd_pcm_sw_params_alloca(&swparams);
snd(pcm_sw_params_current(input_handle, swparams), "sound_StartRecording: snd_pcm_sw_params_current");
+#if 0
snd(pcm_sw_params_set_start_threshold(input_handle, swparams, frames * SQ_SND_REC_START_THRESHOLD), "sound_StartRecording: snd_pcm_sw_params_set_start_threshold");
snd(pcm_sw_params_set_avail_min(input_handle, swparams, frames * SQ_SND_REC_AVAIL_MIN), "sound_StartRecording: snd_pcm_sw_parama_set_avail_min");
+#else
+ snd(pcm_sw_params_set_start_threshold(input_handle, swparams, buffer_size), "sound_StartRecording: snd_pcm_sw_params_set_start_threshold");
+ snd(pcm_sw_params_set_avail_min(input_handle, swparams, period_size), "sound_StartRecording: snd_pcm_sw_parama_set_avail_min");
+#endif
snd(pcm_sw_params_set_xfer_align(input_handle, swparams, 1), "sound_StartRecording: snd_pcm_sw_params_set_xfer_align");
snd(pcm_sw_params(input_handle, swparams), "sound_StartRecording: snd_pcm_sw_params");