18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/********************************************************************
28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/                  *
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: simple programmatic interface for encoder mode setup
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: vorbisenc.c 17028 2010-03-25 05:22:15Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h>
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h>
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/vorbisenc.h"
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "os.h"
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* careful with this; it's using static array sizing to make managing
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   all the modes a little less annoying.  If we use a residue backend
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   with > 12 partition types, or a different division of iteration,
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   this needs to be updated. */
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const static_codebook *books[12][4];
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} static_bookblock;
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int res_type;
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int limit_type; /* 0 lowpass limited, 1 point stereo limited */
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int grouping;
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_info_residue0 *res;
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const static_codebook  *book_aux;
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const static_codebook  *book_aux_managed;
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const static_bookblock *books_base;
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const static_bookblock *books_base_managed;
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} vorbis_residue_template;
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_info_mapping0    *map;
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_residue_template *res;
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} vorbis_mapping_template;
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct vp_adjblock{
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int block[P_BANDS];
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} vp_adjblock;
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int data[NOISE_COMPAND_LEVELS];
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} compandblock;
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* high level configuration information for setting things up
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   step-by-step with the detailed vorbis_encode_ctl interface.
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   There's a fair amount of redundancy such that interactive setup
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   does not directly deal with any vorbis_info or codec_setup_info
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   initialization; it's all stored (until full init) in this highlevel
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   setup, then flushed out to the real codec setup structs later. */
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int att[P_NOISECURVES];
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float boost;
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float decay;
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} att3;
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct { int data[P_NOISECURVES]; } adj3;
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int   pre[PACKETBLOBS];
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int   post[PACKETBLOBS];
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float kHz[PACKETBLOBS];
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float lowpasskHz[PACKETBLOBS];
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} adj_stereo;
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int lo;
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hi;
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int fixed;
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} noiseguard;
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int data[P_NOISECURVES][17];
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} noise3;
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int      mappings;
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double  *rate_mapping;
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double  *quality_mapping;
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int      coupling_restriction;
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long     samplerate_min_restriction;
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long     samplerate_max_restriction;
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int     *blocksize_short;
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int     *blocksize_long;
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const att3    *psy_tone_masteratt;
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int     *psy_tone_0dB;
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int     *psy_tone_dBsuppress;
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vp_adjblock *psy_tone_adj_impulse;
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vp_adjblock *psy_tone_adj_long;
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vp_adjblock *psy_tone_adj_other;
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const noiseguard  *psy_noiseguards;
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const noise3      *psy_noise_bias_impulse;
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const noise3      *psy_noise_bias_padding;
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const noise3      *psy_noise_bias_trans;
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const noise3      *psy_noise_bias_long;
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int         *psy_noise_dBsuppress;
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const compandblock  *psy_noise_compand;
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double        *psy_noise_compand_short_mapping;
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double        *psy_noise_compand_long_mapping;
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int      *psy_noise_normal_start[2];
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int      *psy_noise_normal_partition[2];
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double   *psy_noise_normal_thresh;
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int      *psy_ath_float;
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int      *psy_ath_abs;
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double   *psy_lowpass;
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_info_psy_global *global_params;
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double     *global_mapping;
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const adj_stereo *stereo_modes;
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const static_codebook *const *const *const floor_books;
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_info_floor1 *floor_params;
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int floor_mappings;
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const int **floor_mapping_list;
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_mapping_template *maps;
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} ve_setup_data_template;
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* a few static coder conventions */
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const vorbis_info_mode _mode_template[2]={
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {0,0,0,0},
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {1,0,0,1}
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const vorbis_info_mapping0 _map_nominal[2]={
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {1, {0,0}, {0}, {0}, 1,{0},{1}},
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {1, {0,0}, {1}, {1}, 1,{0},{1}}
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_44.h"
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_44u.h"
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_44p51.h"
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_32.h"
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_8.h"
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_11.h"
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_16.h"
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_22.h"
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "modes/setup_X.h"
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const ve_setup_data_template *const setup_list[]={
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_44_stereo,
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_44_51,
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_44_uncoupled,
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_32_stereo,
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_32_uncoupled,
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_22_stereo,
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_22_uncoupled,
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_16_stereo,
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_16_uncoupled,
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_11_stereo,
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_11_uncoupled,
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_8_stereo,
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_8_uncoupled,
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_X_stereo,
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_X_uncoupled,
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_XX_stereo,
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &ve_setup_XX_uncoupled,
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_floor_setup(vorbis_info *vi,int s,
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                     const static_codebook *const *const *const books,
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                     const vorbis_info_floor1 *in,
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                     const int *x){
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,k,is=s;
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f));
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memcpy(f,in+x[is],sizeof(*f));
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* books */
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int partitions=f->partitions;
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int maxclass=-1;
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int maxbook=-1;
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<partitions;i++)
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i];
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<=maxclass;i++){
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(f->class_book[i]>maxbook)maxbook=f->class_book[i];
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      f->class_book[i]+=ci->books;
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<(1<<f->class_subs[i]);k++){
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k];
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books;
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<=maxbook;i++)
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->book_param[ci->books++]=(static_codebook *)books[x[is]][i];
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* for now, we're only using floor 1 */
2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->floor_type[ci->floors]=1;
2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->floor_param[ci->floors]=f;
2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->floors++;
2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                            const vorbis_info_psy_global *in,
2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                            const double *x){
2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,is=s;
2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=s-is;
2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy_global *g=&ci->psy_g_param;
2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memcpy(g,in+(int)x[is],sizeof(*g));
2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ds=x[is]*(1.-ds)+x[is+1]*ds;
2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  is=(int)ds;
2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ds-=is;
2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ds==0 && is>0){
2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    is--;
2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ds=1.;
2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* interpolate the trigger threshholds */
2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<4;i++){
2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds;
2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds;
2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_global_stereo(vorbis_info *vi,
2568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                        const highlevel_encode_setup *const hi,
2578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                        const adj_stereo *p){
2588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float s=hi->stereo_point_setting;
2598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,is=s;
2608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=s-is;
2618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
2628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy_global *g=&ci->psy_g_param;
2638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(p){
2658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS);
2668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS);
2678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(hi->managed){
2698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* interpolate the kHz threshholds */
2708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<PACKETBLOBS;i++){
2718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        float kHz=p[is].kHz[i]*(1.-ds)+p[is+1].kHz[i]*ds;
2728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
2738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
2748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->coupling_pkHz[i]=kHz;
2758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds;
2778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
2788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
2798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
2828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds;
2838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<PACKETBLOBS;i++){
2848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
2858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
2868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->coupling_pkHz[i]=kHz;
2878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds;
2908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<PACKETBLOBS;i++){
2918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
2928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
2938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
2968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<PACKETBLOBS;i++){
2978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      g->sliding_lowpass[0][i]=ci->blocksizes[0];
2988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      g->sliding_lowpass[1][i]=ci->blocksizes[1];
2998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
3028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_psyset_setup(vorbis_info *vi,double s,
3058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                       const int *nn_start,
3068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                       const int *nn_partition,
3078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                       const double *nn_thresh,
3088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                       int block){
3098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
3108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy *p=ci->psy_param[block];
3118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  highlevel_encode_setup *hi=&ci->hi;
3128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int is=s;
3138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(block>=ci->psys)
3158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->psys=block+1;
3168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!p){
3178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p=_ogg_calloc(1,sizeof(*p));
3188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->psy_param[block]=p;
3198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memcpy(p,&_psy_info_template,sizeof(*p));
3228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->blockflag=block>>1;
3238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->noise_normalize_p){
3258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p->normal_p=1;
3268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p->normal_start=nn_start[is];
3278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p->normal_partition=nn_partition[is];
3288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p->normal_thresh=nn_thresh[is];
3298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
3328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block,
3358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const att3 *att,
3368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const int  *max,
3378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const vp_adjblock *in){
3388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,is=s;
3398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=s-is;
3408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
3418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy *p=ci->psy_param[block];
3428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* 0 and 2 are only used by bitmanagement, but there's no harm to always
3448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     filling the values in here */
3458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds;
3468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds;
3478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds;
3488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds;
3498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds;
3508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds;
3528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<P_BANDS;i++)
3548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p->toneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds;
3558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
3568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block,
3608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                        const compandblock *in,
3618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                        const double *x){
3628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,is=s;
3638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=s-is;
3648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
3658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy *p=ci->psy_param[block];
3668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ds=x[is]*(1.-ds)+x[is+1]*ds;
3688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  is=(int)ds;
3698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ds-=is;
3708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ds==0 && is>0){
3718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    is--;
3728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ds=1.;
3738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* interpolate the compander settings */
3768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<NOISE_COMPAND_LEVELS;i++)
3778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    p->noisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds;
3788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
3798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block,
3828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                    const int *suppress){
3838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int is=s;
3848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=s-is;
3858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
3868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy *p=ci->psy_param[block];
3878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds;
3898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
3918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block,
3948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const int *suppress,
3958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const noise3 *in,
3968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const noiseguard *guard,
3978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         double userbias){
3988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,is=s,j;
3998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=s-is;
4008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
4018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy *p=ci->psy_param[block];
4028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds;
4048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->noisewindowlomin=guard[block].lo;
4058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->noisewindowhimin=guard[block].hi;
4068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->noisewindowfixed=guard[block].fixed;
4078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<P_NOISECURVES;j++)
4098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<P_BANDS;i++)
4108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      p->noiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds;
4118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* impulse blocks may take a user specified bias to boost the
4138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     nominal/high noise encoding depth */
4148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<P_NOISECURVES;j++){
4158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float min=p->noiseoff[j][0]+6; /* the lowest it can go */
4168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<P_BANDS;i++){
4178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      p->noiseoff[j][i]+=userbias;
4188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(p->noiseoff[j][i]<min)p->noiseoff[j][i]=min;
4198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
4238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_ath_setup(vorbis_info *vi,int block){
4268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
4278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_psy *p=ci->psy_param[block];
4288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->ath_adjatt=ci->hi.ath_floating_dB;
4308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  p->ath_maxatt=ci->hi.ath_absolute_dB;
4318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return;
4328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int book_dup_or_new(codec_setup_info *ci,const static_codebook *book){
4368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
4378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ci->books;i++)
4388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(ci->book_param[i]==book)return(i);
4398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ci->books++);
4418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_blocksize_setup(vorbis_info *vi,double s,
4448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         const int *shortb,const int *longb){
4458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
4478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int is=s;
4488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int blockshort=shortb[is];
4508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int blocklong=longb[is];
4518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->blocksizes[0]=blockshort;
4528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->blocksizes[1]=blocklong;
4538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_residue_setup(vorbis_info *vi,
4578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                        int number, int block,
4588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                        const vorbis_residue_template *res){
4598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
4618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
4628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *r=ci->residue_param[number]=
4648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_malloc(sizeof(*r));
4658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memcpy(r,res->res,sizeof(*r));
4678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ci->residues<=number)ci->residues=number+1;
4688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  r->grouping=res->grouping;
4708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->residue_type[number]=res->res_type;
4718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* fill in all the books */
4738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
4748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int booklist=0,k;
4758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(ci->hi.managed){
4778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<r->partitions;i++)
4788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<4;k++)
4798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(res->books_base_managed->books[i][k])
4808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            r->secondstages[i]|=(1<<k);
4818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
4838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed;
4848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<r->partitions;i++){
4868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<4;k++){
4878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(res->books_base_managed->books[i][k]){
4888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
4898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            r->booklist[booklist++]=bookid;
4908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k];
4918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
4928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
4938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
4948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
4968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<r->partitions;i++)
4988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<4;k++)
4998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(res->books_base->books[i][k])
5008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            r->secondstages[i]|=(1<<k);
5018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      r->groupbook=book_dup_or_new(ci,res->book_aux);
5038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->book_param[r->groupbook]=(static_codebook *)res->book_aux;
5048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<r->partitions;i++){
5068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<4;k++){
5078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(res->books_base->books[i][k]){
5088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
5098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            r->booklist[booklist++]=bookid;
5108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k];
5118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
5128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
5138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
5148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* lowpass setup/pointlimit */
5188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
5198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    double freq=ci->hi.lowpass_kHz*1000.;
5208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */
5218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    double nyq=vi->rate/2.;
5228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long blocksize=ci->blocksizes[block]>>1;
5238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* lowpass needs to be set in the floor and the residue. */
5258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(freq>nyq)freq=nyq;
5268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* in the floor, the granularity can be very fine; it doesn't alter
5278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       the encoding structure, only the samples used to fit the floor
5288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       approximation */
5298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    f->n=freq/nyq*blocksize;
5308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* this res may by limited by the maximum pointlimit of the mode,
5328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       not the lowpass. the floor is always lowpass limited. */
5338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    switch(res->limit_type){
5348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case 1: /* point stereo limited */
5358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(ci->hi.managed)
5368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
5378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      else
5388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
5398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(freq>nyq)freq=nyq;
5408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      break;
5418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case 2: /* LFE channel; lowpass at ~ 250Hz */
5428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      freq=250;
5438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      break;
5448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    default:
5458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* already set */
5468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      break;
5478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* in the residue, we're constrained, physically, by partition
5508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       boundaries.  We still lowpass 'wherever', but we have to round up
5518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       here to next boundary, or the vorbis spec will round it *down* to
5528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       previous boundary in encode/decode */
5538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(ci->residue_type[number]==2){
5548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* residue 2 bundles together multiple channels; used by stereo
5558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         and surround.  Count the channels in use */
5568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* Multiple maps/submaps can point to the same residue.  In the case
5578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         of residue 2, they all better have the same number of
5588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         channels/samples. */
5598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int j,k,ch=0;
5608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<ci->maps&&ch==0;i++){
5618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i];
5628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(j=0;j<mi->submaps && ch==0;j++)
5638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */
5648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            for(k=0;k<vi->channels;k++)
5658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */
5668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                ch++;
5678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
5688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */
5708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        r->grouping;
5718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* the blocksize and grouping may disagree at the end */
5728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping;
5738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
5758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
5778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        r->grouping;
5788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* the blocksize and grouping may disagree at the end */
5798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping;
5808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(r->end==0)r->end=r->grouping; /* LFE channel */
5848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
5878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* we assume two maps in this encoder */
5898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s,
5908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          const vorbis_mapping_template *maps){
5918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
5938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,j,is=s,modes=2;
5948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_info_mapping0 *map=maps[is].map;
5958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_info_mode *mode=_mode_template;
5968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const vorbis_residue_template *res=maps[is].res;
5978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ci->blocksizes[0]==ci->blocksizes[1])modes=1;
5998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<modes;i++){
6018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->map_param[i]=_ogg_calloc(1,sizeof(*map));
6038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode));
6048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template));
6068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(i>=ci->modes)ci->modes=i+1;
6078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->map_type[i]=0;
6098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memcpy(ci->map_param[i],map+i,sizeof(*map));
6108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(i>=ci->maps)ci->maps=i+1;
6118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<map[i].submaps;j++)
6138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vorbis_encode_residue_setup(vi,map[i].residuesubmap[j],i
6148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  ,res+map[i].residuesubmap[j]);
6158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
6178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic double setting_to_approx_bitrate(vorbis_info *vi){
6198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
6208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  highlevel_encode_setup *hi=&ci->hi;
6218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup;
6228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int is=hi->base_setting;
6238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds=hi->base_setting-is;
6248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ch=vi->channels;
6258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const double *r=setup->rate_mapping;
6268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(r==NULL)
6288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(-1);
6298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return((r[is]*(1.-ds)+r[is+1]*ds)*ch);
6318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
6328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const void *get_setup_template(long ch,long srate,
6348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      double req,int q_or_bitrate,
6358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      double *base_setting){
6368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i=0,j;
6378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(q_or_bitrate)req/=ch;
6388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(setup_list[i]){
6408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(setup_list[i]->coupling_restriction==-1 ||
6418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       setup_list[i]->coupling_restriction==ch){
6428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(srate>=setup_list[i]->samplerate_min_restriction &&
6438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         srate<=setup_list[i]->samplerate_max_restriction){
6448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int mappings=setup_list[i]->mappings;
6458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        const double *map=(q_or_bitrate?
6468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                     setup_list[i]->rate_mapping:
6478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                     setup_list[i]->quality_mapping);
6488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* the template matches.  Does the requested quality mode
6508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           fall within this template's modes? */
6518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(req<map[0]){++i;continue;}
6528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(req>map[setup_list[i]->mappings]){++i;continue;}
6538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(j=0;j<mappings;j++)
6548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(req>=map[j] && req<map[j+1])break;
6558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* an all-points match */
6568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(j==mappings)
6578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          *base_setting=j-.001;
6588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        else{
6598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float low=map[j];
6608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float high=map[j+1];
6618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float del=(req-low)/(high-low);
6628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          *base_setting=j+del;
6638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
6648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        return(setup_list[i]);
6668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
6678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
6688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    i++;
6698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return NULL;
6728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
6738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* encoders will need to use vorbis_info_init beforehand and call
6758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   vorbis_info clear when all done */
6768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* two interfaces; this, more detailed one, and later a convenience
6788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   layer on top */
6798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* the final setup call */
6818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_encode_setup_init(vorbis_info *vi){
6828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,i0=0,singleblock=0;
6838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
6848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ve_setup_data_template *setup=NULL;
6858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  highlevel_encode_setup *hi=&ci->hi;
6868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ci==NULL)return(OV_EINVAL);
6888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!hi->impulse_block_p)i0=1;
6898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* too low/high an ATH floater is nonsensical, but doesn't break anything */
6918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80;
6928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
6938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* again, bound this to avoid the app shooting itself int he foot
6958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     too badly */
6968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.;
6978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
6988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* get the appropriate setup template; matches the fetch in previous
7008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     stages */
7018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  setup=(ve_setup_data_template *)hi->setup;
7028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(setup==NULL)return(OV_EINVAL);
7038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->set_in_stone=1;
7058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* choose block sizes from configured sizes as well as paying
7068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     attention to long_block_p and short_block_p.  If the configured
7078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     short and long blocks are the same length, we set long_block_p
7088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     and unset short_block_p */
7098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_blocksize_setup(vi,hi->base_setting,
7108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->blocksize_short,
7118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->blocksize_long);
7128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
7138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* floor setup; choose proper floor params.  Allocated on the floor
7158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     stack in order; if we alloc only a single long floor, it's 0 */
7168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<setup->floor_mappings;i++)
7178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_floor_setup(vi,hi->base_setting,
7188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->floor_books,
7198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->floor_params,
7208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->floor_mapping_list[i]);
7218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* setup of [mostly] short block detection and stereo*/
7238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
7248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                   setup->global_params,
7258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                   setup->global_mapping);
7268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
7278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* basic psych setup and noise normalization */
7298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_psyset_setup(vi,hi->base_setting,
7308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_noise_normal_start[0],
7318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_noise_normal_partition[0],
7328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_noise_normal_thresh,
7338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             0);
7348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_psyset_setup(vi,hi->base_setting,
7358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_noise_normal_start[0],
7368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_noise_normal_partition[0],
7378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_noise_normal_thresh,
7388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             1);
7398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!singleblock){
7408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_psyset_setup(vi,hi->base_setting,
7418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_noise_normal_start[1],
7428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_noise_normal_partition[1],
7438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                    setup->psy_noise_normal_thresh,
7448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               2);
7458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_psyset_setup(vi,hi->base_setting,
7468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_noise_normal_start[1],
7478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_noise_normal_partition[1],
7488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_noise_normal_thresh,
7498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               3);
7508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* tone masking setup */
7538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
7548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_tone_masteratt,
7558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_tone_0dB,
7568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_tone_adj_impulse);
7578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
7588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_tone_masteratt,
7598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_tone_0dB,
7608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               setup->psy_tone_adj_other);
7618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!singleblock){
7628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
7638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 setup->psy_tone_masteratt,
7648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 setup->psy_tone_0dB,
7658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 setup->psy_tone_adj_other);
7668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
7678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 setup->psy_tone_masteratt,
7688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 setup->psy_tone_0dB,
7698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 setup->psy_tone_adj_long);
7708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* noise companding setup */
7738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
7748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->psy_noise_compand,
7758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->psy_noise_compand_short_mapping);
7768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
7778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->psy_noise_compand,
7788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              setup->psy_noise_compand_short_mapping);
7798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!singleblock){
7808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2,
7818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_compand,
7828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_compand_long_mapping);
7838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
7848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_compand,
7858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_compand_long_mapping);
7868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* peak guarding setup  */
7898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
7908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           setup->psy_tone_dBsuppress);
7918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
7928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           setup->psy_tone_dBsuppress);
7938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!singleblock){
7948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
7958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_tone_dBsuppress);
7968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
7978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                             setup->psy_tone_dBsuppress);
7988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* noise bias setup */
8018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
8028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_dBsuppress,
8038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_bias_impulse,
8048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noiseguards,
8058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                (i0==0?hi->impulse_noisetune:0.));
8068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
8078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_dBsuppress,
8088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noise_bias_padding,
8098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                setup->psy_noiseguards,0.);
8108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!singleblock){
8118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
8128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  setup->psy_noise_dBsuppress,
8138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  setup->psy_noise_bias_trans,
8148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  setup->psy_noiseguards,0.);
8158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
8168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  setup->psy_noise_dBsuppress,
8178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  setup->psy_noise_bias_long,
8188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                  setup->psy_noiseguards,0.);
8198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_ath_setup(vi,0);
8228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_ath_setup(vi,1);
8238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!singleblock){
8248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_ath_setup(vi,2);
8258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_encode_ath_setup(vi,3);
8268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps);
8298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* set bitrate readonlies and management */
8318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->bitrate_av>0)
8328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vi->bitrate_nominal=hi->bitrate_av;
8338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  else{
8348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vi->bitrate_nominal=setting_to_approx_bitrate(vi);
8358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vi->bitrate_lower=hi->bitrate_min;
8388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vi->bitrate_upper=hi->bitrate_max;
8398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->bitrate_av)
8408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av;
8418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  else
8428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vi->bitrate_window=0.;
8438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(hi->managed){
8458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->bi.avg_rate=hi->bitrate_av;
8468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->bi.min_rate=hi->bitrate_min;
8478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->bi.max_rate=hi->bitrate_max;
8488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->bi.reservoir_bits=hi->bitrate_reservoir;
8508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->bi.reservoir_bias=
8518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      hi->bitrate_reservoir_bias;
8528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ci->bi.slew_damp=hi->bitrate_av_damp;
8548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
8588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
8608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void vorbis_encode_setup_setting(vorbis_info *vi,
8628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                       long  channels,
8638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                       long  rate){
8648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,is;
8658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
8668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  highlevel_encode_setup *hi=&ci->hi;
8678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  const ve_setup_data_template *setup=hi->setup;
8688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double ds;
8698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vi->version=0;
8718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vi->channels=channels;
8728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vi->rate=rate;
8738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->impulse_block_p=1;
8758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->noise_normalize_p=1;
8768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  is=hi->base_setting;
8788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ds=hi->base_setting-is;
8798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->stereo_point_setting=hi->base_setting;
8818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!hi->lowpass_altered)
8838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    hi->lowpass_kHz=
8848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
8858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
8878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    setup->psy_ath_float[is+1]*ds;
8888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+
8898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    setup->psy_ath_abs[is+1]*ds;
8908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->amplitude_track_dBpersec=-6.;
8928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->trigger_setting=hi->base_setting;
8938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<4;i++){
8958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    hi->block[i].tone_mask_setting=hi->base_setting;
8968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    hi->block[i].tone_peaklimit_setting=hi->base_setting;
8978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    hi->block[i].noise_bias_setting=hi->base_setting;
8988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    hi->block[i].noise_compand_setting=hi->base_setting;
8998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_encode_setup_vbr(vorbis_info *vi,
9038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                            long  channels,
9048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                            long  rate,
9058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                            float quality){
9068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
9078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  highlevel_encode_setup *hi=&ci->hi;
9088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  quality+=.0000001;
9108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(quality>=1.)quality=.9999;
9118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->req=quality;
9138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting);
9148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!hi->setup)return OV_EIMPL;
9158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_setup_setting(vi,channels,rate);
9178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->managed=0;
9188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->coupling_p=1;
9198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return 0;
9218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_encode_init_vbr(vorbis_info *vi,
9248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           long channels,
9258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           long rate,
9268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           float base_quality /* 0. to 1. */
9288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           ){
9298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=0;
9308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
9328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ret){
9348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info_clear(vi);
9358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return ret;
9368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ret=vorbis_encode_setup_init(vi);
9388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ret)
9398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info_clear(vi);
9408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
9418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_encode_setup_managed(vorbis_info *vi,
9448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                long channels,
9458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                long rate,
9468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                long max_bitrate,
9488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                long nominal_bitrate,
9498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                long min_bitrate){
9508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
9528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  highlevel_encode_setup *hi=&ci->hi;
9538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double tnominal=nominal_bitrate;
9548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(nominal_bitrate<=0.){
9568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(max_bitrate>0.){
9578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(min_bitrate>0.)
9588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        nominal_bitrate=(max_bitrate+min_bitrate)*.5;
9598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      else
9608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        nominal_bitrate=max_bitrate*.875;
9618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
9628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(min_bitrate>0.){
9638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        nominal_bitrate=min_bitrate;
9648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
9658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        return(OV_EINVAL);
9668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->req=nominal_bitrate;
9718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting);
9728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!hi->setup)return OV_EIMPL;
9738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_encode_setup_setting(vi,channels,rate);
9758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* initialize management with sane defaults */
9778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->coupling_p=1;
9788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->managed=1;
9798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->bitrate_min=min_bitrate;
9808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->bitrate_max=max_bitrate;
9818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->bitrate_av=tnominal;
9828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
9838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->bitrate_reservoir=nominal_bitrate*2;
9848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
9858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
9878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_encode_init(vorbis_info *vi,
9918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       long channels,
9928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       long rate,
9938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       long max_bitrate,
9958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       long nominal_bitrate,
9968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       long min_bitrate){
9978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=vorbis_encode_setup_managed(vi,channels,rate,
9998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      max_bitrate,
10008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      nominal_bitrate,
10018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      min_bitrate);
10028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ret){
10038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info_clear(vi);
10048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(ret);
10058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
10068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ret=vorbis_encode_setup_init(vi);
10088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ret)
10098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info_clear(vi);
10108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
10118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
10128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
10148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vi){
10158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    codec_setup_info *ci=vi->codec_setup;
10168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    highlevel_encode_setup *hi=&ci->hi;
10178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int setp=(number&0xf); /* a read request has a low nibble of 0 */
10188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(setp && hi->set_in_stone)return(OV_EINVAL);
10208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    switch(number){
10228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* now deprecated *****************/
10248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_RATEMANAGE_GET:
10258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
10268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        struct ovectl_ratemanage_arg *ai=
10288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (struct ovectl_ratemanage_arg *)arg;
10298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->management_active=hi->managed;
10318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_hard_window=ai->bitrate_av_window=
10328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (double)hi->bitrate_reservoir/vi->rate;
10338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_av_window_center=1.;
10348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_hard_min=hi->bitrate_min;
10358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_hard_max=hi->bitrate_max;
10368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_av_lo=hi->bitrate_av;
10378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_av_hi=hi->bitrate_av;
10388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
10418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* now deprecated *****************/
10438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_RATEMANAGE_SET:
10448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
10458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        struct ovectl_ratemanage_arg *ai=
10468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (struct ovectl_ratemanage_arg *)arg;
10478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ai==NULL){
10488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->managed=0;
10498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
10508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->managed=ai->management_active;
10518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg);
10528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg);
10538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
10548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return 0;
10568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* now deprecated *****************/
10588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_RATEMANAGE_AVG:
10598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
10608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        struct ovectl_ratemanage_arg *ai=
10618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (struct ovectl_ratemanage_arg *)arg;
10628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ai==NULL){
10638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_av=0;
10648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
10658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
10668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
10678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
10698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* now deprecated *****************/
10708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_RATEMANAGE_HARD:
10718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
10728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        struct ovectl_ratemanage_arg *ai=
10738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (struct ovectl_ratemanage_arg *)arg;
10748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ai==NULL){
10758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_min=0;
10768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_max=0;
10778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
10788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_min=ai->bitrate_hard_min;
10798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_max=ai->bitrate_hard_max;
10808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_reservoir=ai->bitrate_hard_window*
10818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (hi->bitrate_max+hi->bitrate_min)*.5;
10828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
10838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(hi->bitrate_reservoir<128.)
10848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_reservoir=128.;
10858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
10878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* replacement ratemanage interface */
10898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_RATEMANAGE2_GET:
10908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
10918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        struct ovectl_ratemanage2_arg *ai=
10928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (struct ovectl_ratemanage2_arg *)arg;
10938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ai==NULL)return OV_EINVAL;
10948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->management_active=hi->managed;
10968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_limit_min_kbps=hi->bitrate_min/1000;
10978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_limit_max_kbps=hi->bitrate_max/1000;
10988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_average_kbps=hi->bitrate_av/1000;
10998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_average_damping=hi->bitrate_av_damp;
11008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir;
11018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias;
11028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return (0);
11048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_RATEMANAGE2_SET:
11058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        struct ovectl_ratemanage2_arg *ai=
11078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (struct ovectl_ratemanage2_arg *)arg;
11088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ai==NULL){
11098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->managed=0;
11108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
11118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* sanity check; only catch invariant violations */
11128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_limit_min_kbps>0 &&
11138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             ai->bitrate_average_kbps>0 &&
11148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps)
11158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_limit_max_kbps>0 &&
11188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             ai->bitrate_average_kbps>0 &&
11198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             ai->bitrate_limit_max_kbps<ai->bitrate_average_kbps)
11208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_limit_min_kbps>0 &&
11238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             ai->bitrate_limit_max_kbps>0 &&
11248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps)
11258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_average_damping <= 0.)
11288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_limit_reservoir_bits < 0)
11318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_limit_reservoir_bias < 0.)
11348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ai->bitrate_limit_reservoir_bias > 1.)
11378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            return OV_EINVAL;
11388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->managed=ai->management_active;
11408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000;
11418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000;
11428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_av=ai->bitrate_average_kbps * 1000;
11438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_av_damp=ai->bitrate_average_damping;
11448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits;
11458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias;
11468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
11478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return 0;
11498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_LOWPASS_GET:
11518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        double *farg=(double *)arg;
11538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        *farg=hi->lowpass_kHz;
11548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
11568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_LOWPASS_SET:
11578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        double *farg=(double *)arg;
11598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi->lowpass_kHz=*farg;
11608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
11628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
11638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi->lowpass_altered=1;
11648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
11668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_IBLOCK_GET:
11678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        double *farg=(double *)arg;
11698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        *farg=hi->impulse_noisetune;
11708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
11728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_IBLOCK_SET:
11738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        double *farg=(double *)arg;
11758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi->impulse_noisetune=*farg;
11768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.;
11788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
11798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
11818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_COUPLING_GET:
11828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int *iarg=(int *)arg;
11848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        *iarg=hi->coupling_p;
11858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
11868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
11878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    case OV_ECTL_COUPLING_SET:
11888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
11898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        const void *new_template;
11908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        double new_base=0.;
11918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int *iarg=(int *)arg;
11928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi->coupling_p=((*iarg)!=0);
11938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
11948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* Fetching a new template can alter the base_setting, which
11958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           many other parameters are based on.  Right now, the only
11968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           parameter drawn from the base_setting that can be altered
11978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           by an encctl is the lowpass, so that is explictly flagged
11988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           to not be overwritten when we fetch a new template and
11998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           recompute the dependant settings */
12008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
12018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          vi->rate,
12028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          hi->req,
12038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          hi->managed,
12048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          &new_base);
12058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(!hi->setup)return OV_EIMPL;
12068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi->setup=new_template;
12078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi->base_setting=new_base;
12088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
12098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
12108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(0);
12118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
12128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(OV_EIMPL);
12138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
12148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(OV_EINVAL);
12158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1216