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