source: roaraudio/roard/codecfilter_speex.c @ 614:ba67ef04df1e

Last change on this file since 614:ba67ef04df1e was 614:ba67ef04df1e, checked in by phi, 16 years ago

got cf speex working for reading, freqs are correct now, cleaned up debug code, introused magic and done some small changes

File size: 5.0 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 = 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 int mode;
70 uint16_t ui;
71 int tmp;
72 int still_todo = len / 2 /* 16 bit */;
73 int ret = 0;
74 int fs2; // = self->frame_size * 2;
75 char magic[ROAR_SPEEX_MAGIC_LEN];
76
77 ROAR_DBG("cf_speex_read(inst=%p, buf=%p, len=%i) = ?", inst, buf, len);
78
79 if ( ! self->decoder ) {
80  ROAR_DBG("cf_speex_read(*): no decoder, starting one!");
81
82  if ( stream_vio_s_read(self->stream, magic, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN )
83   return 0;
84
85  if ( memcmp(magic, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != 0 )
86   return -1;
87
88  if ( stream_vio_s_read(self->stream, &ui, 2) != 2 )
89   return 0;
90
91  mode = ntohs(ui);
92
93  if ( mode == ROAR_SPEEX_MODE_NB ) {
94   self->decoder = speex_decoder_init(&speex_nb_mode);
95  } else if ( mode == ROAR_SPEEX_MODE_WB ) {
96   self->decoder = speex_decoder_init(&speex_wb_mode);
97  } else if ( mode == ROAR_SPEEX_MODE_UWB ) {
98   self->decoder = speex_decoder_init(&speex_uwb_mode);
99  } else {
100   return 0;
101  }
102
103  tmp=1;
104  speex_decoder_ctl(self->decoder, SPEEX_SET_ENH, &tmp);
105
106  speex_decoder_ctl(self->decoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size));
107
108  fs2 = self->frame_size * 2;
109
110  ROAR_DBG("cf_speex_read(*): frame_size=%i (%i bytes)", self->frame_size, fs2);
111
112  if ( !self->cd ) {
113   self->cd = malloc(fs2);
114   if ( !self->cd )
115    return 0;
116  }
117
118  if ( !self->i_rest ) {
119   self->i_rest = malloc(fs2);
120   if ( !self->i_rest )
121    return 0;
122  }
123 }
124 fs2 = self->frame_size * 2;
125
126 ROAR_DBG("cf_speex_read(*): Have a working decoder!");
127
128 ROAR_DBG("cf_speex_read(*): frame_size=%i (%i bytes)", self->frame_size, fs2);
129 ROAR_DBG("cf_speex_read(*): i_rest is %i bytes after cd", ((void*)self->i_rest - (void*)self->cd));
130
131
132 if ( self->fi_rest ) {
133  if ( self->fi_rest > (still_todo*2) ) {
134   ROAR_DBG("cf_speex_read(*): using data from input rest buffer: len=%i (no need to read new data)", self->fi_rest);
135   still_todo *= 2; // we will set this to zero one way or another,
136                    // so we don't need to care about soring a 'warong' value here.
137   memcpy(buf, self->i_rest, still_todo);
138   memmove(self->i_rest, self->i_rest + still_todo, self->fi_rest - still_todo);
139   self->fi_rest -= still_todo;
140   ret += still_todo;
141   still_todo = 0;
142  } else {
143   ROAR_DBG("cf_speex_read(*): using data from input rest buffer: len=%i", self->fi_rest);
144   memcpy(buf, self->i_rest, self->fi_rest);
145   buf += self->fi_rest;
146   still_todo -= self->fi_rest/2;
147   ret += self->fi_rest;
148   self->fi_rest = 0;
149  }
150 }
151
152 while (still_todo) {
153  ROAR_DBG("cf_speex_read(*): we sill need %i frames", still_todo);
154  if ( stream_vio_s_read(self->stream, &ui, 2) != 2 )
155   return -1;
156
157  ui = ntohs(ui);
158
159  if ( ui > ROAR_SPEEX_MAX_CC )
160   return 0;
161
162  if ( stream_vio_s_read(self->stream, self->cc, ui) != ui )
163   break;
164
165  speex_bits_read_from(&(self->bits), self->cc, ui);
166
167  speex_decode_int(self->decoder, &(self->bits), self->cd);
168
169  if ( self->frame_size > still_todo ) {
170   memcpy(buf, self->cd, still_todo*2);
171   ret += still_todo*2;
172   self->fi_rest = (self->frame_size - still_todo)*2;
173   ROAR_DBG("cf_speex_read(*): self->fi_rest=%i, off=%i", self->fi_rest, still_todo*2);
174   memcpy(self->i_rest, (self->cd)+(still_todo*2), self->fi_rest);
175   still_todo = 0;
176  } else {
177   memcpy(buf, self->cd, fs2);
178   buf        += fs2;
179   ret        += fs2;
180   still_todo -= self->frame_size;
181  }
182 }
183
184 if ( still_todo ) {
185  ROAR_DBG("cf_speex_read(*): could not read all reqquested data, returning %i byte less", still_todo*2);
186 }
187
188 ROAR_DBG("cf_speex_read(*) = %i", ret);
189
190 return ret;
191}
192
193int cf_speex_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
194 struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst;
195
196 return -1;
197}
198
199#endif
200
201//ll
Note: See TracBrowser for help on using the repository browser.