~ubuntu-branches/ubuntu/quantal/linphone/quantal

« back to all changes in this revision

Viewing changes to mediastreamer/msspeexenc.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2004-06-30 13:58:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040630135816-wwx75gdlodkqbabb
Tags: upstream-0.12.2
ImportĀ upstreamĀ versionĀ 0.12.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  The mediastreamer library aims at providing modular media processing and I/O
 
3
        for linphone, but also for any telephony application.
 
4
  Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
 
5
                                                                                
 
6
  This library is free software; you can redistribute it and/or
 
7
  modify it under the terms of the GNU Lesser General Public
 
8
  License as published by the Free Software Foundation; either
 
9
  version 2.1 of the License, or (at your option) any later version.
 
10
 
 
11
  This library is distributed in the hope that it will be useful,
 
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
  Lesser General Public License for more details.
 
15
 
 
16
  You should have received a copy of the GNU Lesser General Public
 
17
  License along with this library; if not, write to the Free Software
 
18
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
*/
 
20
 
 
21
 
 
22
 
 
23
#include "msspeexenc.h"
 
24
#include "ms.h"
 
25
extern MSCodecInfo speex_info;
 
26
 
 
27
static MSSpeexEncClass * ms_speex_enc_class=NULL;
 
28
 
 
29
MSFilter * ms_speex_enc_new(SpeexMode *mode, gint quality)
 
30
{
 
31
        MSSpeexEnc *obj=g_new(MSSpeexEnc,1);
 
32
        
 
33
        if (ms_speex_enc_class==NULL){
 
34
                ms_speex_enc_class=g_new(MSSpeexEncClass,1);
 
35
                ms_speex_enc_class_init(ms_speex_enc_class,mode);
 
36
        }
 
37
        MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_speex_enc_class);
 
38
        ms_speex_enc_init(MS_SPEEX_ENC(obj));
 
39
        return MS_FILTER(obj);
 
40
}
 
41
 
 
42
void ms_speex_enc_init(MSSpeexEnc *obj)
 
43
{
 
44
        ms_filter_init(MS_FILTER(obj));
 
45
        MS_FILTER(obj)->infifos=obj->inf;
 
46
        MS_FILTER(obj)->outqueues=obj->outq;
 
47
        obj->inf[0]=NULL;
 
48
        obj->outq[0]=NULL;
 
49
        obj->frequency=8000;
 
50
        obj->bitrate=30000;
 
51
  obj->initialized=0;
 
52
}
 
53
 
 
54
void ms_speex_enc_init_core(MSSpeexEnc *obj,SpeexMode *mode, gint bitrate)
 
55
{
 
56
        int proc_type, proc_speed;
 
57
        gchar *proc_vendor;
 
58
        int tmp;
 
59
        int frame_size;
 
60
        
 
61
        obj->speex_state=speex_encoder_init(mode);
 
62
        speex_bits_init(&obj->bits);
 
63
        
 
64
        if (bitrate>0) {
 
65
                bitrate++;
 
66
                speex_encoder_ctl(obj->speex_state, SPEEX_SET_BITRATE, &bitrate);
 
67
                g_message("Setting speex output bitrate less or equal than %i",bitrate-1);
 
68
        }
 
69
 
 
70
        proc_speed=ms_proc_get_speed();
 
71
        proc_vendor=ms_proc_get_param("vendor_id");
 
72
        if (proc_speed<0 || proc_vendor==NULL){
 
73
                g_warning("Can't guess processor features: setting speex encoder to its lowest complexity.");
 
74
                tmp=1;
 
75
                speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp);
 
76
        }else if ((proc_speed!=-1) && (proc_speed<200)){
 
77
                g_warning("A cpu speed less than 200 Mhz is not enough: let's reduce the complexity of the speex codec.");
 
78
                tmp=1;
 
79
                speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp);
 
80
        }else if (proc_vendor!=NULL) {
 
81
                if (strncmp(proc_vendor,"GenuineIntel",strlen("GenuineIntel"))==0){
 
82
                        proc_type=ms_proc_get_type();
 
83
                        if (proc_type==5){
 
84
                                g_warning("A pentium I is not enough fast for speex codec in normal mode: let's reduce its complexity.");
 
85
                                tmp=1;
 
86
                                speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp);
 
87
                        }
 
88
                }
 
89
                g_free(proc_vendor);
 
90
        }
 
91
        /* guess the used input frame size */
 
92
        speex_mode_query(mode, SPEEX_MODE_FRAME_SIZE, &frame_size);
 
93
        MS_FILTER(obj)->r_mingran=frame_size*2;
 
94
        ms_trace("ms_speex_init: using frame size of %i.",MS_FILTER(obj)->r_mingran);
 
95
        
 
96
        obj->inbuf=g_malloc(sizeof(float)*frame_size);
 
97
        obj->initialized=1;
 
98
}
 
99
 
 
100
/* must be called before the encoder is running*/
 
101
int ms_speex_enc_set_property(MSSpeexEnc *obj,int property,int *value)
 
102
{
 
103
        if (obj->initialized){
 
104
                /* we are called when speex is running !! forbid that! */
 
105
                ms_warning("ms_speex_enc_set_property: cannot call this function when running!");
 
106
                return -1;
 
107
        }
 
108
        switch(property){
 
109
                case MS_FILTER_PROPERTY_FREQ:
 
110
                        obj->frequency=value[0];
 
111
                break;
 
112
                case MS_FILTER_PROPERTY_BITRATE: /* to specify max bitrate */
 
113
                        obj->bitrate=value[0];
 
114
                break;
 
115
        }
 
116
        return 0;
 
117
}
 
118
 
 
119
void ms_speex_enc_setup(MSSpeexEnc *obj)
 
120
{
 
121
        SpeexMode *mode;
 
122
        int quality;
 
123
        g_message("Speex encoder setup: freq=%i",obj->frequency);
 
124
        if ( obj->frequency< 16000) mode=&speex_nb_mode;
 
125
        else mode=&speex_wb_mode;
 
126
        ms_speex_enc_init_core(obj,mode,obj->bitrate);
 
127
        
 
128
}
 
129
 
 
130
void ms_speex_enc_unsetup(MSSpeexEnc *obj)
 
131
{
 
132
        ms_speex_enc_uninit_core(obj);
 
133
}
 
134
 
 
135
void ms_speex_enc_class_init(MSSpeexEncClass *klass, SpeexMode *mode)
 
136
{
 
137
        gint frame_size=0;
 
138
        
 
139
        ms_filter_class_init(MS_FILTER_CLASS(klass));
 
140
        /* we take the larger (wb) frame size */
 
141
        speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size);
 
142
        MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_enc_process;
 
143
        MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_enc_destroy;
 
144
        MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_enc_setup;
 
145
        MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_enc_unsetup;
 
146
        MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_enc_set_property;
 
147
        ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexEncoder");
 
148
        MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info;
 
149
        MS_FILTER_CLASS(klass)->max_finputs=1;
 
150
        MS_FILTER_CLASS(klass)->max_qoutputs=1;
 
151
        MS_FILTER_CLASS(klass)->r_maxgran=frame_size*2;
 
152
        ms_trace("ms_speex_enc_class_init: r_maxgran is %i.",MS_FILTER_CLASS(klass)->r_maxgran);
 
153
}
 
154
 
 
155
void ms_speex_enc_uninit_core(MSSpeexEnc *obj)
 
156
{
 
157
        if (obj->initialized){
 
158
                speex_encoder_destroy(obj->speex_state);
 
159
                g_free(obj->inbuf);
 
160
                obj->initialized=0;
 
161
        }
 
162
}
 
163
 
 
164
void ms_speex_enc_destroy(MSSpeexEnc *obj)
 
165
{
 
166
        ms_speex_enc_uninit_core(obj);
 
167
        g_free(obj);
 
168
}
 
169
 
 
170
void ms_speex_enc_process(MSSpeexEnc *obj)
 
171
{
 
172
        MSFifo *inf=obj->inf[0];
 
173
        MSQueue *outq=obj->outq[0];
 
174
        gint16 *input;
 
175
        gint gran=MS_FILTER(obj)->r_mingran;
 
176
        gint i;
 
177
        MSMessage *m;
 
178
        
 
179
        g_return_if_fail(inf!=NULL);
 
180
        g_return_if_fail(outq!=NULL);
 
181
        
 
182
        ms_fifo_get_read_ptr(inf,gran,(void**)&input);
 
183
        g_return_if_fail(input!=NULL);
 
184
        /* convert into float */
 
185
        for (i=0;i<gran/2;i++) obj->inbuf[i]=input[i];
 
186
        /* encode */
 
187
        speex_bits_reset(&obj->bits);
 
188
        speex_encode(obj->speex_state,obj->inbuf,&obj->bits);
 
189
        m=ms_message_new(speex_bits_nbytes(&obj->bits));
 
190
        m->size=speex_bits_write(&obj->bits,m->data,m->size);
 
191
        ms_queue_put(outq,m);
 
192
}