+
+static void Pause( audio_output_t *aout, bool pause, mtime_t date )
+{
+ VLC_UNUSED( date );
+
+ aout_sys_t *sys = aout->sys;
+
+ if( pause )
+ kaiPause( sys->hkai );
+ else
+ kaiResume( sys->hkai );
+}
+
+static void Flush( audio_output_t *aout, bool drain )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ if( drain )
+ {
+ while( buffer->length > 0 )
+ vlc_cond_wait( &buffer->cond, &buffer->mutex );
+ }
+ else
+ {
+ buffer->read_pos = buffer->write_pos;
+ buffer->length = 0;
+ }
+
+ vlc_mutex_unlock( &buffer->mutex );
+}
+
+static int TimeGet( audio_output_t *aout, mtime_t *restrict delay )
+{
+ aout_sys_t *sys = aout->sys;
+ audio_sample_format_t *format = &sys->format;
+ audio_buffer_t *buffer = sys->buffer;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ *delay = ( buffer->length / format->i_bytes_per_frame ) * CLOCK_FREQ /
+ format->i_rate;
+
+ vlc_mutex_unlock( &buffer->mutex );
+
+ return 0;
+}
+
+static int CreateBuffer( audio_output_t *aout, int size )
+{
+ audio_buffer_t *buffer;
+
+ buffer = calloc( 1, sizeof( *buffer ));
+ if( !buffer )
+ return -1;
+
+ buffer->data = malloc( size );
+ if( !buffer->data )
+ {
+ free( buffer );
+
+ return -1;
+ }
+
+ buffer->size = size;
+
+ vlc_mutex_init( &buffer->mutex );
+ vlc_cond_init( &buffer->cond );
+
+ aout->sys->buffer = buffer;
+
+ return 0;
+}
+
+static void DestroyBuffer( audio_output_t *aout )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+
+ vlc_mutex_destroy( &buffer->mutex );
+ vlc_cond_destroy( &buffer->cond );
+
+ free( buffer->data );
+ free( buffer );
+}
+
+static int ReadBuffer( audio_output_t *aout, uint8_t *data, int size )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+ int len;
+ int remain_len = 0;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ len = MIN( buffer->length, size );
+ if( buffer->read_pos + len > buffer->size )
+ {
+ remain_len = len;
+ len = buffer->size - buffer->read_pos;
+ remain_len -= len;
+ }
+
+ memcpy( data, buffer->data + buffer->read_pos, len );
+ if( remain_len )
+ memcpy( data + len, buffer->data, remain_len );
+
+ len += remain_len;
+
+ buffer->read_pos += len;
+ buffer->read_pos %= buffer->size;
+
+ buffer->length -= len;
+
+ vlc_cond_signal( &buffer->cond );
+
+ vlc_mutex_unlock( &buffer->mutex );
+
+ return len;
+}
+
+static int WriteBuffer( audio_output_t *aout, uint8_t *data, int size )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+ int len;
+ int remain_len = 0;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ while( buffer->length + size > buffer->size )
+ vlc_cond_wait( &buffer->cond, &buffer->mutex );
+
+ len = size;
+ if( buffer->write_pos + len > buffer->size )
+ {
+ remain_len = len;
+ len = buffer->size - buffer->write_pos;
+ remain_len -= len;
+ }
+
+ memcpy( buffer->data + buffer->write_pos, data, len );
+ if( remain_len )
+ memcpy( buffer->data, data + len, remain_len );
+
+ buffer->write_pos += size;
+ buffer->write_pos %= buffer->size;
+
+ buffer->length += size;
+
+ vlc_mutex_unlock( &buffer->mutex );
+
+ return size;
+}