summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2010-03-23 03:44:44 +0000
committerMonty <xiphmont@xiph.org>2010-03-23 03:44:44 +0000
commit3efb9e123b30cf8b023debd809953f14fb34fa8b (patch)
treec9c392f158fc544d716e349c30b50c8237104a1e
parente6d6258c0fcd2c3c3a609229c9ba88af59e92998 (diff)
downloadlibvorbis-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.html14
-rw-r--r--include/vorbis/vorbisenc.h20
-rw-r--r--lib/highlevel.h8
-rw-r--r--lib/vorbisenc.c109
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);