diff options
author | Monty <xiphmont@xiph.org> | 2010-03-23 03:44:44 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2010-03-23 03:44:44 +0000 |
commit | 3efb9e123b30cf8b023debd809953f14fb34fa8b (patch) | |
tree | c9c392f158fc544d716e349c30b50c8237104a1e | |
parent | e6d6258c0fcd2c3c3a609229c9ba88af59e92998 (diff) | |
download | libvorbis-git-3efb9e123b30cf8b023debd809953f14fb34fa8b.tar.gz |
Add ectl to disable/reenable channel coupling
svn path=/trunk/vorbis/; revision=16995
-rw-r--r-- | doc/vorbisenc/vorbis_encode_ctl.html | 14 | ||||
-rw-r--r-- | include/vorbis/vorbisenc.h | 20 | ||||
-rw-r--r-- | lib/highlevel.h | 8 | ||||
-rw-r--r-- | lib/vorbisenc.c | 109 |
4 files changed, 102 insertions, 49 deletions
diff --git a/doc/vorbisenc/vorbis_encode_ctl.html b/doc/vorbisenc/vorbis_encode_ctl.html index 48f63a78..ca337da3 100644 --- a/doc/vorbisenc/vorbis_encode_ctl.html +++ b/doc/vorbisenc/vorbis_encode_ctl.html @@ -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> diff --git a/include/vorbis/vorbisenc.h b/include/vorbis/vorbisenc.h index 684a41c4..0b93eea1 100644 --- a/include/vorbis/vorbisenc.h +++ b/include/vorbis/vorbisenc.h @@ -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 */ /** diff --git a/lib/highlevel.h b/lib/highlevel.h index 61e6dc47..0891181d 100644 --- a/lib/highlevel.h +++ b/lib/highlevel.h @@ -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; diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c index a6de76cb..3730dfaa 100644 --- a/lib/vorbisenc.c +++ b/lib/vorbisenc.c @@ -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); |