source: roaraudio/roard/codecfilter_speex.c @ 608:745a06132506

Last change on this file since 608:745a06132506 was 608:745a06132506, checked in by phi, 16 years ago

make codec filter fuse vio

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