final beta 4 commit
[platform/upstream/libvorbis.git] / lib / vorbisenc.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
9  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
10
11  ********************************************************************
12
13  function: simple programmatic interface for encoder mode setup
14  last mod: $Id: vorbisenc.c,v 1.6 2001/02/26 03:50:43 xiphmont Exp $
15
16  ********************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21
22 #include "vorbis/codec.h"
23 #include "vorbis/vorbisenc.h"
24
25 #include "codec_internal.h"
26 #include "registry.h"
27 #include "modes/modes.h"
28
29 #include "os.h"
30 #include "misc.h"
31
32
33 /* deepcopy all but the codebooks; in this usage, they're static
34    (don't copy as they could be big) */
35 static void codec_setup_partialcopy(codec_setup_info *ci,
36                                  codec_setup_info *cs){
37   int i;
38
39   memcpy(ci,cs,sizeof(codec_setup_info)); /* to get the flat numbers */
40
41   /* codebooks */
42   for(i=0;i<ci->books;i++){
43     ci->book_param[i]=cs->book_param[i];
44   }
45
46   /* time backend settings */
47   for(i=0;i<ci->times;i++){
48     ci->time_param[i]=_time_P[ci->time_type[i]]->
49       copy_info(cs->time_param[i]);
50   }
51
52   /* floor backend settings */
53   for(i=0;i<ci->floors;i++){
54     ci->floor_param[i]=_floor_P[ci->floor_type[i]]->
55       copy_info(cs->floor_param[i]);
56   }
57
58   /* residue backend settings */
59   for(i=0;i<ci->residues;i++){
60     ci->residue_param[i]=_residue_P[ci->residue_type[i]]->
61       copy_info(cs->residue_param[i]);
62   }
63
64   /* map backend settings */
65   for(i=0;i<ci->maps;i++){
66     ci->map_param[i]=_mapping_P[ci->map_type[i]]->
67       copy_info(cs->map_param[i]);
68   }
69   
70   /* mode settings */
71   for(i=0;i<ci->modes;i++){
72     ci->mode_param[i]=_ogg_calloc(1,sizeof(vorbis_info_mode));
73     ci->mode_param[i]->blockflag=cs->mode_param[i]->blockflag;
74     ci->mode_param[i]->windowtype=cs->mode_param[i]->windowtype;
75     ci->mode_param[i]->transformtype=cs->mode_param[i]->transformtype;
76     ci->mode_param[i]->mapping=cs->mode_param[i]->mapping;
77   }
78
79   /* psy settings */
80   for(i=0;i<ci->psys;i++){
81     ci->psy_param[i]=_vi_psy_copy(cs->psy_param[i]);
82   }
83
84 }
85
86 /* right now, this just encapsultes the old modes behind the interface
87    we'll be using from here on out.  After beta 3, the new bitrate
88    tracking/modding/tuning engine will lurk inside */
89 /* encoders will need to use vorbis_info_init beforehand and call
90    vorbis_info clear when all done */
91
92 int vorbis_encode_init(vorbis_info *vi,
93                        long channels,
94                        long rate,
95
96                        long max_bitrate,
97                        long nominal_bitrate,
98                        long min_bitrate){
99
100   long bpch;
101   int i,j;
102   codec_setup_info *ci=vi->codec_setup;
103   codec_setup_info *mode=NULL;
104   if(!ci)return(OV_EFAULT);
105
106   vi->version=0;
107   vi->channels=channels;
108   vi->rate=rate;
109   
110   vi->bitrate_upper=max_bitrate;
111   vi->bitrate_nominal=nominal_bitrate;
112   vi->bitrate_lower=min_bitrate;
113   vi->bitrate_window=2;
114
115   /* copy a mode into our allocated storage */
116   bpch=nominal_bitrate/channels;
117   if(bpch<60000){
118     /* mode A */
119     mode=&info_AA;
120   }else if(bpch<75000){
121     /* mode A */
122     mode=&info_A;
123   }else if(bpch<90000){
124     /* mode B */
125     mode=&info_B;
126   }else if(bpch<110000){
127     /* mode C */
128     mode=&info_C;
129   }else if(bpch<160000){
130     /* mode D */
131     mode=&info_D;
132   }else{
133     /* mode E */
134     mode=&info_E;
135   }
136
137   /* now we have to deepcopy */
138   codec_setup_partialcopy(ci,mode);
139
140   /* adjust for sample rate */
141   for(i=0;i<ci->floors;i++)
142     ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate;
143
144   /* adjust for channels; all our mappings use submap zero now */
145   /* yeah, OK, _ogg_calloc did this for us.  But it's a reminder/placeholder */
146   for(i=0;i<ci->maps;i++)
147     for(j=0;j<channels;j++)
148       ((vorbis_info_mapping0 *)ci->map_param[i])->chmuxlist[j]=0;
149
150   return(0);
151 }
152
153 int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
154   return(OV_EIMPL);
155 }
156