source: mediastreamer2/src/gsm.c @ 926:466243d373ea

Last change on this file since 926:466243d373ea was 926:466243d373ea, checked in by Jehan Monnier <jehan.monnier@…>, 3 years ago

Merge branch 'master' of belledonne-communications.com:mediastreamer2-private

File size: 4.3 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
22#include <gsm/gsm.h>
23
24#ifdef _MSC_VER
25#include <malloc.h>
26#define alloca _alloca
27#endif
28
29typedef struct EncState{
30        gsm state;
31        uint32_t ts;
32        int ptime;
33        MSBufferizer *bufferizer;
34} EncState;
35
36static int enc_add_fmtp(MSFilter *f, void *arg){
37        const char *fmtp=(const char *)arg;
38        EncState *s=(EncState*)f->data;
39        char tmp[30];
40        if (fmtp_get_value(fmtp,"ptime",tmp,sizeof(tmp))){
41                int ptime = atoi(tmp);
42                switch (ptime) {
43                case 20:
44                case 40:
45                case 60:
46                case 80:
47                case 100:
48                        s->ptime = atoi(tmp);
49                        break;
50                default:
51                        ms_warning("MSGsmEnc: unsupported ptime [%i] using default",ptime);
52                }
53                ms_message("MSGsmEnc: got ptime=%i using [%i]",ptime,s->ptime);
54        }
55        return 0;
56}
57
58static void enc_init(MSFilter *f){
59        EncState *s=(EncState *)ms_new(EncState,1);
60        s->state=gsm_create();
61        s->ts=0;
62        s->ptime=20;
63        s->bufferizer=ms_bufferizer_new();
64        f->data=s;
65}
66
67static void enc_uninit(MSFilter *f){
68        EncState *s=(EncState*)f->data;
69        gsm_destroy(s->state);
70        ms_bufferizer_destroy(s->bufferizer);
71        ms_free(s);
72}
73
74
75
76static void enc_process(MSFilter *f){
77        EncState *s=(EncState*)f->data;
78        mblk_t *im;
79        unsigned int unitary_buff_size = sizeof(int16_t)*160;
80        unsigned int buff_size = unitary_buff_size*s->ptime/20;
81        int16_t* buff;
82        int offset;
83       
84        while((im=ms_queue_get(f->inputs[0]))!=NULL){
85                ms_bufferizer_put(s->bufferizer,im);
86        }
87        while(ms_bufferizer_get_avail(s->bufferizer) >= buff_size) {
88                buff = (int16_t *)alloca(buff_size);
89                ms_bufferizer_read(s->bufferizer,(uint8_t*)buff,buff_size);
90                mblk_t *om=allocb(33*s->ptime/20,0);
91
92                for (offset=0;offset<buff_size;offset+=unitary_buff_size) {
93                        gsm_encode(s->state,(gsm_signal*)&buff[offset/sizeof(int16_t)],(gsm_byte*)om->b_wptr);
94                        om->b_wptr+=33;
95                }
96                mblk_set_timestamp_info(om,s->ts);
97                ms_queue_put(f->outputs[0],om);
98                s->ts+=buff_size/sizeof(int16_t)/*sizeof(buf)/2*/;
99        }
100}
101static MSFilterMethod enc_methods[]={
102        {       MS_FILTER_ADD_FMTP              ,       enc_add_fmtp},
103        {       0                               ,       NULL            }
104};
105
106#ifdef _MSC_VER
107
108MSFilterDesc ms_gsm_enc_desc={
109        MS_GSM_ENC_ID,
110        "MSGsmEnc",
111        N_("The GSM full-rate codec"),
112        MS_FILTER_ENCODER,
113        "gsm",
114        1,
115        1,
116        enc_init,
117        NULL,
118        enc_process,
119        NULL,
120        enc_uninit,
121        enc_methods
122};
123
124#else
125
126MSFilterDesc ms_gsm_enc_desc={
127        .id=MS_GSM_ENC_ID,
128        .name="MSGsmEnc",
129        .text=N_("The GSM full-rate codec"),
130        .category=MS_FILTER_ENCODER,
131        .enc_fmt="gsm",
132        .ninputs=1,
133        .noutputs=1,
134        .init=enc_init,
135        .process=enc_process,
136        .uninit=enc_uninit,
137        .methods = enc_methods
138};
139
140#endif
141
142static void dec_init(MSFilter *f){
143        f->data=gsm_create();
144}
145
146static void dec_uninit(MSFilter *f){
147        gsm s=(gsm)f->data;
148        gsm_destroy(s);
149}
150
151
152static void dec_process(MSFilter *f){
153        gsm s=(gsm)f->data;
154        mblk_t *im;
155        mblk_t *om;
156        const int frsz=160*2;
157
158        while((im=ms_queue_get(f->inputs[0]))!=NULL){
159                for (;(im->b_wptr-im->b_rptr)>=33;im->b_rptr+=33) {
160                        om=allocb(frsz,0);
161                        if (gsm_decode(s,(gsm_byte*)im->b_rptr,(gsm_signal*)om->b_wptr)<0){
162                                ms_warning("gsm_decode error!");
163                                freemsg(om);
164                        }else{
165                                om->b_wptr+=frsz;
166                                ms_queue_put(f->outputs[0],om);
167                        }
168                }
169                freemsg(im);
170        }
171}
172
173#ifdef _MSC_VER
174
175MSFilterDesc ms_gsm_dec_desc={
176        MS_GSM_DEC_ID,
177        "MSGsmDec",
178        N_("The GSM codec"),
179        MS_FILTER_DECODER,
180        "gsm",
181        1,
182        1,
183        dec_init,
184        NULL,
185        dec_process,
186        NULL,
187        dec_uninit,
188        NULL
189};
190
191#else
192
193MSFilterDesc ms_gsm_dec_desc={
194        .id=MS_GSM_DEC_ID,
195        .name="MSGsmDec",
196        .text=N_("The GSM codec"),
197        .category=MS_FILTER_DECODER,
198        .enc_fmt="gsm",
199        .ninputs=1,
200        .noutputs=1,
201        .init=dec_init,
202        .process=dec_process,
203        .uninit=dec_uninit
204};
205
206#endif
207
208MS_FILTER_DESC_EXPORT(ms_gsm_dec_desc)
209MS_FILTER_DESC_EXPORT(ms_gsm_enc_desc)
Note: See TracBrowser for help on using the repository browser.