gint xmms_output_read (xmms_output_t *output, char *buffer, gint len) { gint ret; xmms_error_t err; xmms_error_reset (&err); g_return_val_if_fail (output, -1); g_return_val_if_fail (buffer, -1); g_mutex_lock (output->filler_mutex); xmms_ringbuf_wait_used (output->filler_buffer, len, output->filler_mutex); ret = xmms_ringbuf_read (output->filler_buffer, buffer, len); if (ret == 0 && xmms_ringbuf_iseos (output->filler_buffer)) { xmms_output_status_set (output, XMMS_PLAYBACK_STATUS_STOP); g_mutex_unlock (output->filler_mutex); return -1; } g_mutex_unlock (output->filler_mutex); update_playtime (output, ret); if (ret < len) { XMMS_DBG ("Underrun %d of %d (%d)", ret, len, xmms_sample_frame_size_get (output->format)); if ((ret % xmms_sample_frame_size_get (output->format)) != 0) { xmms_log_error ("***********************************"); xmms_log_error ("* Read non-multiple of sample size,"); xmms_log_error ("* you probably hear noise now :)"); xmms_log_error ("***********************************"); } output->buffer_underruns++; } output->bytes_written += ret; return ret; }
/** * Same as #xmms_ringbuf_read but blocks until you have all the data you want. * * @sa xmms_ringbuf_read */ guint xmms_ringbuf_read_wait (xmms_ringbuf_t *ringbuf, gpointer data, guint len, GMutex *mtx) { guint r = 0, res; guint8 *dest = data; g_return_val_if_fail (ringbuf, 0); g_return_val_if_fail (data, 0); g_return_val_if_fail (len > 0, 0); g_return_val_if_fail (mtx, 0); while (r < len) { res = xmms_ringbuf_read (ringbuf, dest + r, len - r); r += res; if (r == len || ringbuf->eos) { break; } if (!res) g_cond_wait (ringbuf->used_cond, mtx); } return r; }