Commit 3efb9e12 authored by Monty's avatar Monty
Browse files

Add ectl to disable/reenable channel coupling


svn path=/trunk/vorbis/; revision=16995
parent e6d6258c
......@@ -92,6 +92,20 @@ is -15.0 to 0.0 [default]. A negative impulse block bias will direct
to encoder to use more bits when incoding short blocks that contain
strong impulses, thus improving the accuracy of impulse encoding.</dd><p>
<dt><i>OV_ECTL_COUPLING_GET</i></dt>
<dd><b>Argument: int *</b><br>
Returns the current encoder coupling enabled/disabled
setting in the int pointed to by arg.
</dd><p>
<dt><i>OV_ECTL_COUPLING_SET</i></dt>
<dd><b>Argument: int *</b><br>
Enables/disables channel coupling in multichannel encoding according to arg.
*arg of zero disables all channel coupling, nonzero allows the encoder to use
coupling if a coupled mode is available for the input. At present, coupling
is available for stereo and 5.1 input modes.
</dd><p>
<dt><i>OV_ECTL_RATEMANAGE_GET [deprecated]</i></dt>
<dd>
......
......@@ -358,6 +358,26 @@ struct ovectl_ratemanage2_arg {
*/
#define OV_ECTL_IBLOCK_SET 0x31
/**
* Returns the current encoder coupling setting in the int pointed
* to by arg.
*
* Argument: <tt>int *</tt>
*/
#define OV_ECTL_COUPLING_GET 0x40
/**
* Enables/disables channel coupling in multichannel encoding according to arg.
*
* Argument: <tt>int *</tt>
*
* Zero disables channel coupling for multichannel inputs, nonzer enables
* channel coupling. Setting has no effect on monophonic encoding or
* multichannel counts that do not offer coupling. At present, coupling is
* available for stereo and 5.1 encoding.
*/
#define OV_ECTL_COUPLING_SET 0x41
/* deprecated rate management supported only for compatability */
/**
......
......@@ -23,12 +23,14 @@ typedef struct highlevel_byblocktype {
} highlevel_byblocktype;
typedef struct highlevel_encode_setup {
const void *setup;
int set_in_stone;
const void *setup;
double base_setting;
double impulse_noisetune;
/* bitrate management below all settable */
float req;
int managed;
long bitrate_min;
long bitrate_av;
......@@ -39,9 +41,11 @@ typedef struct highlevel_encode_setup {
int impulse_block_p;
int noise_normalize_p;
int coupling_p;
double stereo_point_setting;
double lowpass_kHz;
int lowpass_altered;
double ath_floating_dB;
double ath_absolute_dB;
......
......@@ -187,18 +187,6 @@ static const ve_setup_data_template *const setup_list[]={
0
};
static int vorbis_encode_toplevel_setup(vorbis_info *vi,int ch,long rate){
if(vi && vi->codec_setup){
vi->version=0;
vi->channels=ch;
vi->rate=rate;
return(0);
}
return(OV_EINVAL);
}
static void vorbis_encode_floor_setup(vorbis_info *vi,int s,
const static_codebook *const *const *const books,
const vorbis_info_floor1 *in,
......@@ -642,12 +630,10 @@ static double setting_to_approx_bitrate(vorbis_info *vi){
return((r[is]*(1.-ds)+r[is+1]*ds)*ch);
}
static void get_setup_template(vorbis_info *vi,
long ch,long srate,
double req,int q_or_bitrate){
static const void *get_setup_template(long ch,long srate,
double req,int q_or_bitrate,
double *base_setting){
int i=0,j;
codec_setup_info *ci=vi->codec_setup;
highlevel_encode_setup *hi=&ci->hi;
if(q_or_bitrate)req/=ch;
while(setup_list[i]){
......@@ -667,23 +653,22 @@ static void get_setup_template(vorbis_info *vi,
for(j=0;j<mappings;j++)
if(req>=map[j] && req<map[j+1])break;
/* an all-points match */
hi->setup=setup_list[i];
if(j==mappings)
hi->base_setting=j-.001;
*base_setting=j-.001;
else{
float low=map[j];
float high=map[j+1];
float del=(req-low)/(high-low);
hi->base_setting=j+del;
*base_setting=j+del;
}
return;
return(setup_list[i]);
}
}
i++;
}
hi->setup=NULL;
return NULL;
}
/* encoders will need to use vorbis_info_init beforehand and call
......@@ -873,29 +858,30 @@ int vorbis_encode_setup_init(vorbis_info *vi){
}
static int vorbis_encode_setup_setting(vorbis_info *vi,
static void vorbis_encode_setup_setting(vorbis_info *vi,
long channels,
long rate){
int ret=0,i,is;
int i,is;
codec_setup_info *ci=vi->codec_setup;
highlevel_encode_setup *hi=&ci->hi;
const ve_setup_data_template *setup=hi->setup;
double ds;
ret=vorbis_encode_toplevel_setup(vi,channels,rate);
if(ret)return(ret);
is=hi->base_setting;
ds=hi->base_setting-is;
hi->managed=0;
vi->version=0;
vi->channels=channels;
vi->rate=rate;
hi->impulse_block_p=1;
hi->noise_normalize_p=1;
is=hi->base_setting;
ds=hi->base_setting-is;
hi->stereo_point_setting=hi->base_setting;
hi->lowpass_kHz=
setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
if(!hi->lowpass_altered)
hi->lowpass_kHz=
setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
setup->psy_ath_float[is+1]*ds;
......@@ -911,8 +897,6 @@ static int vorbis_encode_setup_setting(vorbis_info *vi,
hi->block[i].noise_bias_setting=hi->base_setting;
hi->block[i].noise_compand_setting=hi->base_setting;
}
return(ret);
}
int vorbis_encode_setup_vbr(vorbis_info *vi,
......@@ -925,10 +909,15 @@ int vorbis_encode_setup_vbr(vorbis_info *vi,
quality+=.0000001;
if(quality>=1.)quality=.9999;
get_setup_template(vi,channels,rate,quality,0);
hi->req=quality;
hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting);
if(!hi->setup)return OV_EIMPL;
return vorbis_encode_setup_setting(vi,channels,rate);
vorbis_encode_setup_setting(vi,channels,rate);
hi->managed=0;
hi->coupling_p=1;
return 0;
}
int vorbis_encode_init_vbr(vorbis_info *vi,
......@@ -962,7 +951,6 @@ int vorbis_encode_setup_managed(vorbis_info *vi,
codec_setup_info *ci=vi->codec_setup;
highlevel_encode_setup *hi=&ci->hi;
double tnominal=nominal_bitrate;
int ret=0;
if(nominal_bitrate<=0.){
if(max_bitrate>0.){
......@@ -979,16 +967,14 @@ int vorbis_encode_setup_managed(vorbis_info *vi,
}
}
get_setup_template(vi,channels,rate,nominal_bitrate,1);
hi->req=nominal_bitrate;
hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting);
if(!hi->setup)return OV_EIMPL;
ret=vorbis_encode_setup_setting(vi,channels,rate);
if(ret){
vorbis_info_clear(vi);
return ret;
}
vorbis_encode_setup_setting(vi,channels,rate);
/* initialize management with sane defaults */
hi->coupling_p=1;
hi->managed=1;
hi->bitrate_min=min_bitrate;
hi->bitrate_max=max_bitrate;
......@@ -997,7 +983,7 @@ int vorbis_encode_setup_managed(vorbis_info *vi,
hi->bitrate_reservoir=nominal_bitrate*2;
hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
return(ret);
return(0);
}
......@@ -1174,6 +1160,7 @@ int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
hi->lowpass_altered=1;
}
return(0);
case OV_ECTL_IBLOCK_GET:
......@@ -1191,9 +1178,37 @@ int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
}
return(0);
case OV_ECTL_COUPLING_GET:
{
int *iarg=(int *)arg;
*iarg=hi->coupling_p;
}
return(0);
case OV_ECTL_COUPLING_SET:
{
void *new_template;
double new_base;
int *iarg=(int *)arg;
hi->coupling_p=((*iarg)!=0);
/* Fetching a new template can alter the base_setting, which
many other parameters are based on. Right now, the only
parameter drawn from the base_setting that can be altered
by an encctl is the lowpass, so that is explictly flagged
to not be overwritten when we fetch a new template and
recompute the dependant settings */
new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
vi->rate,
hi->req,
hi->managed,
&new_base);
if(!hi->setup)return OV_EIMPL;
hi->setup=new_template;
hi->base_setting=new_base;
vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
}
return(0);
}
return(OV_EIMPL);
}
return(OV_EINVAL);
......
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