Commit d29ead01 authored by Laurent Aimar's avatar Laurent Aimar

Split out aout_mixer_t from aout_instance_t.

It will allow to sanetize aout_instance_t.
parent 8d6e134e
......@@ -174,25 +174,6 @@ typedef struct aout_alloc_t
#define AOUT_ALLOC_STACK 1
#define AOUT_ALLOC_HEAP 2
/** audio output mixer */
typedef struct aout_mixer_t
{
audio_sample_format_t mixer;
aout_alloc_t output_alloc;
module_t * p_module;
struct aout_mixer_sys_t * p_sys;
void (* pf_do_work)( struct aout_instance_t *,
struct aout_buffer_t * );
/** If b_error == 1, there is no mixer. */
bool b_error;
/** Multiplier used to raise or lower the volume of the sound in
* software. Beware, this creates sound distortion and should be avoided
* as much as possible. This isn't available for non-float32 mixer. */
float f_multiplier;
} aout_mixer_t;
/** audio output buffer FIFO */
struct aout_fifo_t
{
......@@ -201,6 +182,9 @@ struct aout_fifo_t
date_t end_date;
};
/* FIXME to remove once aout.h is cleaned a bit more */
#include <vlc_aout_mixer.h>
/* */
typedef struct
{
......@@ -266,12 +250,8 @@ struct aout_input_t
mtime_t i_resamp_start_date;
int i_resamp_start_drift;
aout_fifo_t fifo;
/* Mixer information */
uint8_t * p_first_byte_to_mix;
audio_replay_gain_t replay_gain;
float f_multiplier;
/* If b_restart == 1, the input pipeline will be re-created. */
bool b_restart;
......@@ -295,6 +275,9 @@ struct aout_input_t
/* */
bool b_recycle_vout;
aout_request_vout_t request_vout;
/* */
aout_mixer_input_t mixer;
};
/** an output stream for the audio output */
......@@ -351,7 +334,10 @@ struct aout_instance_t
int i_nb_inputs;
/* Mixer */
aout_mixer_t mixer;
audio_sample_format_t mixer_format;
aout_alloc_t mixer_allocation;
float mixer_multiplier;
aout_mixer_t *p_mixer;
/* Output plug-in */
aout_output_t output;
......
/*****************************************************************************
* vlc_aout_mixer.h : audio output mixer interface
*****************************************************************************
* Copyright (C) 2002-2009 the VideoLAN team
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_AOUT_MIXER_H
#define VLC_AOUT_MIXER_H 1
/**
* \file
* This file defines functions, structures and macros for audio output mixer object
*/
#ifdef __cplusplus
extern "C" {
#endif
//#include <vlc_aout.h>
/* */
typedef struct aout_mixer_sys_t aout_mixer_sys_t;
typedef struct aout_mixer_t aout_mixer_t;
typedef struct {
/* Is the input to be ignored while mixing */
bool is_invalid;
/* */
aout_fifo_t fifo;
/* Pointer on the first byte of data to mix.
*
* It points in the first buffer of fifo
*/
uint8_t *begin;
/* Software multiplier */
float multiplier;
} aout_mixer_input_t;
/**
* audio output mixer
*/
struct aout_mixer_t {
VLC_COMMON_MEMBERS
/* Module */
module_t *module;
/* Mixer format.
*
* You cannot modify it.
*/
audio_sample_format_t fmt;
/* Mixer output buffer allocation method.
*
* You can override it in the open function only.
*/
aout_alloc_t allocation;
/* Multiplier used to raise or lower the volume of the sound in
* software.
*/
float multiplier;
/* Array of mixer inputs */
unsigned input_count;
aout_mixer_input_t **input;
/* Mix input into the given buffer (mandatory) */
void (*mix)(aout_mixer_t *, struct aout_buffer_t *);
/* Private place holder for the aout_mixer_t module (optional)
*
* A module is free to use it as it wishes.
*/
aout_mixer_sys_t *sys;
};
#ifdef __cplusplus
}
#endif
#endif
......@@ -46,6 +46,7 @@ pluginsinclude_HEADERS = \
../include/vlc_access.h \
../include/vlc_acl.h \
../include/vlc_aout.h \
../include/vlc_aout_mixer.h \
../include/vlc_arrays.h \
../include/vlc_avcodec.h \
../include/vlc_bits.h \
......
......@@ -43,6 +43,9 @@
static inline void aout_assert_fifo_locked( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
{
#ifndef NDEBUG
if( !p_aout )
return;
if( p_fifo == &p_aout->output.fifo )
vlc_assert_locked( &p_aout->output_fifo_lock );
else
......@@ -50,7 +53,7 @@ static inline void aout_assert_fifo_locked( aout_instance_t * p_aout, aout_fifo_
int i;
for( i = 0; i < p_aout->i_nb_inputs; i++ )
{
if( p_fifo == &p_aout->pp_inputs[i]->fifo)
if( p_fifo == &p_aout->pp_inputs[i]->mixer.fifo)
{
vlc_assert_locked( &p_aout->input_fifos_lock );
break;
......@@ -88,8 +91,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
vlc_mutex_init( &p_aout->mixer_lock );
vlc_mutex_init( &p_aout->output_fifo_lock );
p_aout->i_nb_inputs = 0;
p_aout->mixer.f_multiplier = 1.0;
p_aout->mixer.b_error = 1;
p_aout->mixer_multiplier = 1.0;
p_aout->p_mixer = NULL;
p_aout->output.b_error = 1;
p_aout->output.b_starving = 1;
......
......@@ -112,7 +112,7 @@ static aout_input_t * DecNew( aout_instance_t * p_aout,
p_aout->pp_inputs[p_aout->i_nb_inputs] = p_input;
p_aout->i_nb_inputs++;
if ( p_aout->mixer.b_error )
if ( !p_aout->p_mixer )
{
int i;
......@@ -379,7 +379,7 @@ void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b
if( i_duration != 0 )
{
aout_lock_mixer( p_aout );
for( aout_buffer_t *p = p_input->fifo.p_first; p != NULL; p = p->p_next )
for( aout_buffer_t *p = p_input->mixer.fifo.p_first; p != NULL; p = p->p_next )
{
p->start_date += i_duration;
p->end_date += i_duration;
......@@ -392,8 +392,8 @@ void aout_DecFlush( aout_instance_t *p_aout, aout_input_t *p_input )
{
aout_lock_input_fifos( p_aout );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
p_input->p_first_byte_to_mix = NULL;
aout_FifoSet( p_aout, &p_input->mixer.fifo, 0 );
p_input->mixer.begin = NULL;
aout_unlock_input_fifos( p_aout );
}
......
......@@ -83,8 +83,8 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
p_input->i_nb_resamplers = p_input->i_nb_filters = 0;
/* Prepare FIFO. */
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
p_input->p_first_byte_to_mix = NULL;
aout_FifoInit( p_aout, &p_input->mixer.fifo, p_aout->p_mixer->fmt.i_rate );
p_input->mixer.begin = NULL;
/* */
if( p_request_vout )
......@@ -98,10 +98,8 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
}
/* Prepare format structure */
memcpy( &chain_input_format, &p_input->input,
sizeof(audio_sample_format_t) );
memcpy( &chain_output_format, &p_aout->mixer.mixer,
sizeof(audio_sample_format_t) );
chain_input_format = p_input->input;
chain_output_format = p_aout->p_mixer->fmt;
chain_output_format.i_rate = p_input->input.i_rate;
aout_FormatPrepare( &chain_output_format );
......@@ -419,12 +417,12 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
p_input->input_alloc.i_bytes_per_sec = -1;
/* Create resamplers. */
if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer.mixer ) )
if ( !AOUT_FMT_NON_LINEAR( &p_aout->p_mixer->fmt ) )
{
chain_output_format.i_rate = (__MAX(p_input->input.i_rate,
p_aout->mixer.mixer.i_rate)
p_aout->p_mixer->fmt.i_rate)
* (100 + AOUT_MAX_RESAMPLING)) / 100;
if ( chain_output_format.i_rate == p_aout->mixer.mixer.i_rate )
if ( chain_output_format.i_rate == p_aout->p_mixer->fmt.i_rate )
{
/* Just in case... */
chain_output_format.i_rate++;
......@@ -432,7 +430,7 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_resamplers,
&p_input->i_nb_resamplers,
&chain_output_format,
&p_aout->mixer.mixer ) < 0 )
&p_aout->p_mixer->fmt ) < 0 )
{
inputFailure( p_aout, p_input, "couldn't set a resampler pipeline");
return -1;
......@@ -500,7 +498,7 @@ int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
aout_FiltersDestroyPipeline( p_aout, p_input->pp_resamplers,
p_input->i_nb_resamplers );
p_input->i_nb_resamplers = 0;
aout_FifoDestroy( p_aout, &p_input->fifo );
aout_FifoDestroy( p_aout, &p_input->mixer.fifo );
return 0;
}
......@@ -530,18 +528,18 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
/* A little trick to avoid loosing our input fifo and properties */
p_first_byte_to_mix = p_input->p_first_byte_to_mix;
fifo = p_input->fifo;
p_first_byte_to_mix = p_input->mixer.begin;
fifo = p_input->mixer.fifo;
b_paused = p_input->b_paused;
i_pause_date = p_input->i_pause_date;
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
aout_FifoInit( p_aout, &p_input->mixer.fifo, p_aout->p_mixer->fmt.i_rate );
aout_InputDelete( p_aout, p_input );
aout_InputNew( p_aout, p_input, &p_input->request_vout );
p_input->p_first_byte_to_mix = p_first_byte_to_mix;
p_input->fifo = fifo;
p_input->mixer.begin = p_first_byte_to_mix;
p_input->mixer.fifo = fifo;
p_input->b_paused = b_paused;
p_input->i_pause_date = i_pause_date;
......@@ -591,7 +589,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
* this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */
aout_lock_input_fifos( p_aout );
start_date = aout_FifoNextStart( p_aout, &p_input->fifo );
start_date = aout_FifoNextStart( p_aout, &p_input->mixer.fifo );
aout_unlock_input_fifos( p_aout );
if ( start_date != 0 && start_date < mdate() )
......@@ -602,8 +600,8 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
msg_Warn( p_aout, "computed PTS is out of range (%"PRId64"), "
"clearing out", mdate() - start_date );
aout_lock_input_fifos( p_aout );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
p_input->p_first_byte_to_mix = NULL;
aout_FifoSet( p_aout, &p_input->mixer.fifo, 0 );
p_input->mixer.begin = NULL;
aout_unlock_input_fifos( p_aout );
if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
msg_Warn( p_aout, "timing screwed, stopping resampling" );
......@@ -632,8 +630,8 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
msg_Warn( p_aout, "audio drift is too big (%"PRId64"), clearing out",
start_date - p_buffer->start_date );
aout_lock_input_fifos( p_aout );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
p_input->p_first_byte_to_mix = NULL;
aout_FifoSet( p_aout, &p_input->mixer.fifo, 0 );
p_input->mixer.begin = NULL;
aout_unlock_input_fifos( p_aout );
if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
msg_Warn( p_aout, "timing screwed, stopping resampling" );
......@@ -760,7 +758,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
p_buffer->start_date = start_date;
aout_lock_input_fifos( p_aout );
aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
aout_FifoPush( p_aout, &p_input->mixer.fifo, p_buffer );
aout_unlock_input_fifos( p_aout );
return 0;
}
......@@ -780,7 +778,7 @@ static void inputFailure( aout_instance_t * p_aout, aout_input_t * p_input,
p_input->i_nb_filters );
aout_FiltersDestroyPipeline( p_aout, p_input->pp_resamplers,
p_input->i_nb_resamplers );
aout_FifoDestroy( p_aout, &p_input->fifo );
aout_FifoDestroy( p_aout, &p_input->mixer.fifo );
var_Destroy( p_aout, "visual" );
var_Destroy( p_aout, "equalizer" );
var_Destroy( p_aout, "audio-filter" );
......@@ -934,7 +932,8 @@ static int ReplayGainCallback( vlc_object_t *p_this, char const *psz_cmd,
ReplayGainSelect( p_aout, p_aout->pp_inputs[i] );
/* Restart the mixer (a trivial mixer may be in use) */
aout_MixerMultiplierSet( p_aout, p_aout->mixer.f_multiplier );
if( p_aout->p_mixer )
aout_MixerMultiplierSet( p_aout, p_aout->mixer_multiplier );
aout_unlock_mixer( p_aout );
return VLC_SUCCESS;
......@@ -948,7 +947,7 @@ static void ReplayGainSelect( aout_instance_t *p_aout, aout_input_t *p_input )
int i_use;
float f_gain;
p_input->f_multiplier = 1.0;
p_input->mixer.multiplier = 1.0;
if( !psz_replay_gain )
return;
......@@ -979,14 +978,14 @@ static void ReplayGainSelect( aout_instance_t *p_aout, aout_input_t *p_input )
f_gain = var_GetFloat( p_aout, "audio-replay-gain-default" );
else
f_gain = 0.0;
p_input->f_multiplier = pow( 10.0, f_gain / 20.0 );
p_input->mixer.multiplier = pow( 10.0, f_gain / 20.0 );
/* */
if( p_input->replay_gain.pb_peak[i_use] &&
var_GetBool( p_aout, "audio-replay-gain-peak-protection" ) &&
p_input->replay_gain.pf_peak[i_use] * p_input->f_multiplier > 1.0 )
p_input->replay_gain.pf_peak[i_use] * p_input->mixer.multiplier > 1.0 )
{
p_input->f_multiplier = 1.0f / p_input->replay_gain.pf_peak[i_use];
p_input->mixer.multiplier = 1.0f / p_input->replay_gain.pf_peak[i_use];
}
free( psz_replay_gain );
......
......@@ -79,7 +79,7 @@ int __aout_VolumeGet( vlc_object_t * p_object, audio_volume_t * pi_volume )
}
aout_lock_mixer( p_aout );
if ( !p_aout->mixer.b_error )
if ( p_aout->p_mixer )
{
i_result = p_aout->output.pf_volume_get( p_aout, pi_volume );
}
......@@ -110,11 +110,12 @@ int __aout_VolumeSet( vlc_object_t * p_object, audio_volume_t i_volume )
return VLC_SUCCESS;
int i_result = VLC_SUCCESS;
aout_lock_mixer( p_aout );
if ( !p_aout->mixer.b_error )
aout_lock_mixer( p_aout );
aout_lock_input_fifos( p_aout );
if ( p_aout->p_mixer )
i_result = p_aout->output.pf_volume_set( p_aout, i_volume );
aout_unlock_input_fifos( p_aout );
aout_unlock_mixer( p_aout );
var_SetBool( p_aout, "intf-change", true );
......
This diff is collapsed.
......@@ -170,28 +170,27 @@ int aout_OutputNew( aout_instance_t * p_aout,
aout_FormatPrint( p_aout, "output", &p_aout->output.output );
/* Calculate the resulting mixer output format. */
memcpy( &p_aout->mixer.mixer, &p_aout->output.output,
sizeof(audio_sample_format_t) );
p_aout->mixer_format = p_aout->output.output;
if ( !AOUT_FMT_NON_LINEAR(&p_aout->output.output) )
{
/* Non-S/PDIF mixer only deals with float32 or fixed32. */
p_aout->mixer.mixer.i_format
p_aout->mixer_format.i_format
= (vlc_CPU() & CPU_CAPABILITY_FPU) ?
VLC_CODEC_FL32 : VLC_CODEC_FI32;
aout_FormatPrepare( &p_aout->mixer.mixer );
aout_FormatPrepare( &p_aout->mixer_format );
}
else
{
p_aout->mixer.mixer.i_format = p_format->i_format;
p_aout->mixer_format.i_format = p_format->i_format;
}
aout_FormatPrint( p_aout, "mixer", &p_aout->mixer.mixer );
aout_FormatPrint( p_aout, "mixer", &p_aout->mixer_format );
/* Create filters. */
p_aout->output.i_nb_filters = 0;
if ( aout_FiltersCreatePipeline( p_aout, p_aout->output.pp_filters,
&p_aout->output.i_nb_filters,
&p_aout->mixer.mixer,
&p_aout->mixer_format,
&p_aout->output.output ) < 0 )
{
msg_Err( p_aout, "couldn't create audio output pipeline" );
......@@ -200,15 +199,15 @@ int aout_OutputNew( aout_instance_t * p_aout,
}
/* Prepare hints for the buffer allocator. */
p_aout->mixer.output_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
p_aout->mixer.output_alloc.i_bytes_per_sec
= p_aout->mixer.mixer.i_bytes_per_frame
* p_aout->mixer.mixer.i_rate
/ p_aout->mixer.mixer.i_frame_length;
p_aout->mixer_allocation.i_alloc_type = AOUT_ALLOC_HEAP;
p_aout->mixer_allocation.i_bytes_per_sec
= p_aout->mixer_format.i_bytes_per_frame
* p_aout->mixer_format.i_rate
/ p_aout->mixer_format.i_frame_length;
aout_FiltersHintBuffers( p_aout, p_aout->output.pp_filters,
p_aout->output.i_nb_filters,
&p_aout->mixer.output_alloc );
&p_aout->mixer_allocation );
p_aout->output.b_error = 0;
return 0;
......@@ -350,7 +349,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
aout_lock_input_fifos( p_aout );
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_fifo_t * p_fifo = &p_aout->pp_inputs[i]->fifo;
aout_fifo_t * p_fifo = &p_aout->pp_inputs[i]->mixer.fifo;
aout_FifoMoveDates( p_aout, p_fifo, difference );
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment