158 lines
6.6 KiB
Diff
158 lines
6.6 KiB
Diff
|
--- 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");
|
||
|
|