source: roaraudio/roard/codecfilter_speex.c @ 395:9117c7e72c4d

Last change on this file since 395:9117c7e72c4d was 395:9117c7e72c4d, checked in by phi, 16 years ago

done a lot work on cf speex

File size: 4.2 KB
Line 
1//codecfilter_speex.c:
2
3#include "roard.h"
4#ifdef ROAR_HAVE_LIBSPEEX
5
6int cf_speex_open(CODECFILTER_USERDATA_T * inst, int codec,
7                                            struct roar_stream_server * info,
8                                            struct roar_codecfilter   * filter) {
9 struct codecfilter_speex_inst * self = malloc(sizeof(struct codecfilter_speex_inst));
10 struct roar_stream * s = (struct roar_stream *) info;
11
12 *inst = NULL;
13
14 if (!self)
15  return -1;
16
17 self->encoder = NULL;
18 self->decoder = NULL;
19
20 self->stream  = info;
21
22 self->cd      = NULL;
23
24 self->i_rest  = NULL;
25 self->fi_rest = 0;
26
27 speex_bits_init(&(self->bits));
28
29 s->info.codec    = ROAR_CODEC_DEFAULT;
30 s->info.bits     = 16; // speex hardcoded
31 s->info.channels = 1; // only mono support at the moment
32
33 *inst = (void*) self;
34
35 return 0;
36}
37
38int cf_speex_close(CODECFILTER_USERDATA_T   inst) {
39 struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst;
40
41 if (!self)
42  return -1;
43
44 if ( self->encoder )
45  speex_encoder_destroy(self->decoder);
46
47 self->encoder = NULL;
48
49 if ( self->decoder )
50  speex_decoder_destroy(self->decoder);
51
52 self->decoder = NULL;
53
54 speex_bits_destroy(&(self->bits));
55
56 if ( self->cd )
57  free(self->cd);
58
59 if ( self->i_rest )
60  free(self->i_rest);
61
62 free((void*)self);
63
64 return 0;
65}
66
67int cf_speex_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
68 struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst;
69 struct roar_stream * s = (struct roar_stream *) self->stream;
70 int mode;
71 uint16_t ui;
72 int tmp;
73 int still_todo = len / 2 /* 16 bit */;
74 int ret = 0;
75
76 if ( ! self->decoder ) {
77  ROAR_DBG("cf_speex_read(*): no decoder, starting one!");
78  if ( read(s->fh, &ui, 2) != 2 )
79   return 0;
80
81  mode = ntohs(ui);
82
83  if ( mode == ROAR_SPEEX_MODE_NB ) {
84   self->decoder = speex_decoder_init(&speex_nb_mode);
85  } else if ( mode == ROAR_SPEEX_MODE_WB ) {
86   self->decoder = speex_decoder_init(&speex_wb_mode);
87  } else if ( mode == ROAR_SPEEX_MODE_UWB ) {
88   self->decoder = speex_decoder_init(&speex_uwb_mode);
89  } else {
90   return 0;
91  }
92
93  tmp=1;
94  speex_decoder_ctl(self->decoder, SPEEX_SET_ENH, &tmp);
95
96  speex_decoder_ctl(self->decoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size));
97
98
99
100  ROAR_WARN("cf_speex_read(*): frame_size=%i (%i bytes)", self->frame_size, self->frame_size*2);
101
102  if ( !self->cd ) {
103   self->cd = malloc((self->frame_size)*2);
104   if ( !self->cd )
105    return 0;
106  }
107
108  if ( !self->i_rest ) {
109   self->i_rest = malloc((self->frame_size)*2);
110   if ( !self->i_rest )
111    return 0;
112  }
113 }
114
115 ROAR_WARN("cf_speex_read(*): Have a working decoder!");
116
117 ROAR_WARN("cf_speex_read(*): frame_size=%i (%i bytes)", self->frame_size, self->frame_size*2);
118 ROAR_WARN("cf_speex_read(*): i_rest is %i bytes after cd", self->i_rest - self->cd);
119
120
121 if ( self->fi_rest ) {
122  if ( self->fi_rest > still_todo ) {
123   ROAR_WARN("cf_speex_read(*): discarding input rest data: buffer too long!");
124   self->fi_rest = 0;
125  } else {
126   ROAR_WARN("cf_speex_read(*): using data from input rest buffer: len=%i", self->fi_rest);
127   memcpy(buf, self->i_rest, self->fi_rest);
128   buf += self->fi_rest;
129   self->fi_rest = 0;
130  }
131 }
132
133 while (still_todo) {
134  ROAR_WARN("cf_speex_read(*): we sill need %i frames", still_todo);
135  if ( read(s->fh, &ui, 2) != 2 )
136   return -1;
137
138  ui = ntohs(ui);
139
140  if ( ui > ROAR_SPEEX_MAX_CC )
141   return 0;
142
143  if ( read(s->fh, self->cc, ui) != ui )
144   break;
145
146  speex_bits_read_from(&(self->bits), self->cc, ui);
147
148  speex_decode_int(self->decoder, &(self->bits), self->cd);
149
150  if ( self->frame_size > still_todo ) {
151   memcpy(buf, self->cd, still_todo*2);
152   ret += still_todo*2;
153   self->fi_rest = (self->frame_size - still_todo)*2;
154   ROAR_WARN("cf_speex_read(*): self->fi_rest=%i, off=%i", self->fi_rest, still_todo*2);
155   memcpy(self->i_rest, (self->cd)+(still_todo*2), self->fi_rest);
156   still_todo = 0;
157  } else {
158   memcpy(buf, self->cd, self->frame_size*2);
159   buf        += self->frame_size*2;
160   ret        += self->frame_size*2;
161   still_todo -= self->frame_size;
162  }
163 }
164
165 return ret;
166}
167
168int cf_speex_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
169 struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst;
170
171 return -1;
172}
173
174#endif
175
176//ll
Note: See TracBrowser for help on using the repository browser.