source: mediastreamer2/src/gsm.c @ 1410:032eb23d23a7

Last change on this file since 1410:032eb23d23a7 was 1410:032eb23d23a7, checked in by Nikita Kozlov <nikita@…>, 2 years ago

our gsm sources have headers in a gsm dir

File size: 4.5 KB
Line 
1/*
2mediastreamer2 library - modular sound and video processing and streaming
3Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18*/
19
20#include "mediastreamer2/msfilter.h"
21#ifdef ANDROID
22#include "gsm/gsm.h"
23#else
24#include <gsm/gsm.h>
25#endif
26
27#ifdef _MSC_VER
28#include <malloc.h>
29#define alloca _alloca
30#endif
31
32typedef struct EncState{
33        gsm state;
34        uint32_t ts;
35        int ptime;
36        MSBufferizer *bufferizer;
37} EncState;
38
39static int set_ptime(MSFilter *f, int ptime){
40        EncState *s=(EncState*)f->data;
41        if (ptime<=0 || ptime>140) return -1;
42        s->ptime=(ptime/20)*20;
43        ms_message("MSGsmEnc: got ptime=%i using [%i]",ptime,s->ptime);
44        return 0;
45}
46
47static int enc_add_fmtp(MSFilter *f, void *arg){
48        const char *fmtp=(const char *)arg;
49        char tmp[30];
50       
51        if (fmtp_get_value(fmtp,"ptime",tmp,sizeof(tmp))){
52                return set_ptime(f,atoi(tmp));
53        }
54        return 0;
55}
56
57static int enc_add_attr(MSFilter *f, void *arg){
58        const char *attr=(const char *)arg;
59        if (strstr(attr,"ptime:")!=NULL){
60                int ptime = atoi(attr+6);
61                return set_ptime(f,ptime);
62        }
63        return 0;
64}
65
66static void enc_init(MSFilter *f){
67        EncState *s=(EncState *)ms_new(EncState,1);
68        s->state=gsm_create();
69        s->ts=0;
70        s->ptime=20;
71        s->bufferizer=ms_bufferizer_new();
72        f->data=s;
73}
74
75static void enc_uninit(MSFilter *f){
76        EncState *s=(EncState*)f->data;
77        gsm_destroy(s->state);
78        ms_bufferizer_destroy(s->bufferizer);
79        ms_free(s);
80}
81
82
83
84static void enc_process(MSFilter *f){
85        EncState *s=(EncState*)f->data;
86        mblk_t *im;
87        unsigned int unitary_buff_size = sizeof(int16_t)*160;
88        unsigned int buff_size = unitary_buff_size*s->ptime/20;
89        int16_t* buff;
90        int offset;
91       
92        while((im=ms_queue_get(f->inputs[0]))!=NULL){
93                ms_bufferizer_put(s->bufferizer,im);
94        }
95        while(ms_bufferizer_get_avail(s->bufferizer) >= buff_size) {
96                mblk_t *om=allocb(33*s->ptime/20,0);
97                buff = (int16_t *)alloca(buff_size);
98                ms_bufferizer_read(s->bufferizer,(uint8_t*)buff,buff_size);
99               
100                for (offset=0;offset<buff_size;offset+=unitary_buff_size) {
101                        gsm_encode(s->state,(gsm_signal*)&buff[offset/sizeof(int16_t)],(gsm_byte*)om->b_wptr);
102                        om->b_wptr+=33;
103                }
104                mblk_set_timestamp_info(om,s->ts);
105                ms_queue_put(f->outputs[0],om);
106                s->ts+=buff_size/sizeof(int16_t)/*sizeof(buf)/2*/;
107        }
108}
109static MSFilterMethod enc_methods[]={
110        {       MS_FILTER_ADD_FMTP              ,       enc_add_fmtp},
111        {    MS_FILTER_ADD_ATTR        ,    enc_add_attr},
112        {       0                               ,       NULL            }
113};
114
115#ifdef _MSC_VER
116
117MSFilterDesc ms_gsm_enc_desc={
118        MS_GSM_ENC_ID,
119        "MSGsmEnc",
120        N_("The GSM full-rate codec"),
121        MS_FILTER_ENCODER,
122        "gsm",
123        1,
124        1,
125        enc_init,
126        NULL,
127        enc_process,
128        NULL,
129        enc_uninit,
130        enc_methods
131};
132
133#else
134
135MSFilterDesc ms_gsm_enc_desc={
136        .id=MS_GSM_ENC_ID,
137        .name="MSGsmEnc",
138        .text=N_("The GSM full-rate codec"),
139        .category=MS_FILTER_ENCODER,
140        .enc_fmt="gsm",
141        .ninputs=1,
142        .noutputs=1,
143        .init=enc_init,
144        .process=enc_process,
145        .uninit=enc_uninit,
146        .methods = enc_methods
147};
148
149#endif
150
151static void dec_init(MSFilter *f){
152        f->data=gsm_create();
153}
154
155static void dec_uninit(MSFilter *f){
156        gsm s=(gsm)f->data;
157        gsm_destroy(s);
158}
159
160
161static void dec_process(MSFilter *f){
162        gsm s=(gsm)f->data;
163        mblk_t *im;
164        mblk_t *om;
165        const int frsz=160*2;
166
167        while((im=ms_queue_get(f->inputs[0]))!=NULL){
168                for (;(im->b_wptr-im->b_rptr)>=33;im->b_rptr+=33) {
169                        om=allocb(frsz,0);
170                        if (gsm_decode(s,(gsm_byte*)im->b_rptr,(gsm_signal*)om->b_wptr)<0){
171                                ms_warning("gsm_decode error!");
172                                freemsg(om);
173                        }else{
174                                om->b_wptr+=frsz;
175                                ms_queue_put(f->outputs[0],om);
176                        }
177                }
178                freemsg(im);
179        }
180}
181
182#ifdef _MSC_VER
183
184MSFilterDesc ms_gsm_dec_desc={
185        MS_GSM_DEC_ID,
186        "MSGsmDec",
187        N_("The GSM codec"),
188        MS_FILTER_DECODER,
189        "gsm",
190        1,
191        1,
192        dec_init,
193        NULL,
194        dec_process,
195        NULL,
196        dec_uninit,
197        NULL
198};
199
200#else
201
202MSFilterDesc ms_gsm_dec_desc={
203        .id=MS_GSM_DEC_ID,
204        .name="MSGsmDec",
205        .text=N_("The GSM codec"),
206        .category=MS_FILTER_DECODER,
207        .enc_fmt="gsm",
208        .ninputs=1,
209        .noutputs=1,
210        .init=dec_init,
211        .process=dec_process,
212        .uninit=dec_uninit
213};
214
215#endif
216
217MS_FILTER_DESC_EXPORT(ms_gsm_dec_desc)
218MS_FILTER_DESC_EXPORT(ms_gsm_enc_desc)
Note: See TracBrowser for help on using the repository browser.