unsigned int subdivision; /* requested subdivision */
size_t period_bytes; /* requested period size */
unsigned int periods;
- size_t buffer_bytes; /* requested period size */
+ size_t buffer_bytes; /* requested buffer size */
size_t bytes; /* total # bytes processed */
size_t mmap_bytes;
char *buffer; /* vmallocated period */
- size_t buffer_used; /* used length from buffer */
+ size_t buffer_used; /* used length from period buffer */
snd_pcm_plugin_t *plugin_first;
snd_pcm_plugin_t *plugin_last;
unsigned int prev_hw_ptr_interrupt;
return 0;
}
+static int snd_pcm_oss_sync1(snd_pcm_substream_t *substream, size_t size)
+{
+ snd_pcm_runtime_t *runtime;
+ ssize_t result = 0;
+ wait_queue_t wait;
+
+ runtime = substream->runtime;
+ init_waitqueue_entry(&wait, current);
+ add_wait_queue(&runtime->sleep, &wait);
+ while (1) {
+ result = snd_pcm_oss_write2(substream, runtime->oss.buffer, size, 1);
+ if (result > 0) {
+ runtime->oss.buffer_used = 0;
+ result = 0;
+ break;
+ }
+ if (result != 0 && result != -EAGAIN)
+ break;
+ result = 0;
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ if (signal_pending(current)) {
+ result = -ERESTARTSYS;
+ break;
+ }
+ set_current_state(TASK_RUNNING);
+ }
+ remove_wait_queue(&runtime->sleep, &wait);
+ return result;
+}
+
static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file)
{
int err = 0;
unsigned int saved_f_flags;
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
- ssize_t result;
- wait_queue_t wait;
+ size_t size;
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
if (substream != NULL) {
if ((err = snd_pcm_oss_make_ready(substream)) < 0)
return err;
-
runtime = substream->runtime;
if (runtime->oss.buffer_used > 0) {
snd_pcm_format_set_silence(runtime->format,
runtime->oss.buffer + runtime->oss.buffer_used,
bytes_to_samples(runtime, runtime->oss.period_bytes - runtime->oss.buffer_used));
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&runtime->sleep, &wait);
- while (1) {
- result = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
- if (result > 0) {
- runtime->oss.buffer_used = 0;
- break;
- }
- if (result != 0 && result != -EAGAIN)
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- if (signal_pending(current)) {
- result = -ERESTARTSYS;
- break;
- }
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&runtime->sleep, &wait);
- if (result < 0)
- return result;
+ err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
+ if (err < 0)
+ return err;
+ }
+ size = runtime->control->appl_ptr % runtime->period_size;
+ if (size > 0) {
+ size = runtime->period_size - size;
+ size *= runtime->channels;
+ snd_pcm_format_set_silence(runtime->format,
+ runtime->oss.buffer,
+ size);
+ err = snd_pcm_oss_sync1(substream, samples_to_bytes(runtime, size));
+ if (err < 0)
+ return err;
}
saved_f_flags = substream->ffile->f_flags;
substream->ffile->f_flags &= ~O_NONBLOCK;