source: roaraudio/roard/codecfilter_celt.c @ 5826:edb28d83ca21

Last change on this file since 5826:edb28d83ca21 was 5823:f9f70dbaa376, checked in by phi, 11 years ago

updated copyright

File size: 8.9 KB
Line 
1//codecfilter_celt.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "roard.h"
27#ifdef ROAR_HAVE_LIBCELT
28
29#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
30typedef celt_int16 celt_int16_t;
31#endif
32
33int cf_celt_open(CODECFILTER_USERDATA_T * inst, int codec,
34                                            struct roar_stream_server * info,
35                                            struct roar_codecfilter   * filter) {
36 struct codecfilter_celt_inst * self = roar_mm_malloc(sizeof(struct codecfilter_celt_inst));
37 struct roar_stream * s = ROAR_STREAM(info);
38
39 (void)codec, (void)filter;
40
41 if ( self == NULL )
42  return -1;
43
44/*
45 CELTMode * mode;
46 CELTEncoder * encoder;
47 CELTDecoder * decoder;
48 int frame_size;
49 int lookahead;
50 int out_size;
51 char * ibuf;
52 char * obuf;
53 char * rest;
54 int s_buf;
55 int f_rest; /-* how much is in rest? *-/
56*/
57
58 self->stream               = info;
59 self->frame_size           = 256;
60 self->lookahead            = self->frame_size;
61 self->encoder              = NULL;
62 self->decoder              = NULL;
63 self->opened_encoder       = 0;
64 self->opened_decoder       = 0;
65 self->s_buf                = s->info.channels * self->frame_size * 2;
66 self->ibuf                 = roar_mm_malloc(self->s_buf);
67 self->obuf                 = roar_mm_malloc(self->s_buf);
68 self->i_rest               = roar_mm_malloc(self->s_buf);
69 self->o_rest               = roar_mm_malloc(self->s_buf);
70 self->fi_rest              = 0;
71 self->fo_rest              = 0;
72
73 if ( !(self->ibuf && self->obuf && self->i_rest && self->o_rest) ) {
74  if ( self->ibuf != NULL )
75   roar_mm_free(self->ibuf);
76
77  if ( self->obuf != NULL )
78   roar_mm_free(self->obuf);
79
80  if ( self->i_rest != NULL )
81   roar_mm_free(self->o_rest);
82
83  if ( self->o_rest != NULL )
84   roar_mm_free(self->o_rest);
85
86  roar_mm_free(self);
87  return -1;
88 }
89
90#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
91 self->mode                 = celt_mode_create(s->info.rate, self->frame_size, NULL);
92#else
93 self->mode                 = celt_mode_create(s->info.rate, s->info.channels, self->frame_size, NULL);
94#endif
95
96 if ( !self->mode ) {
97  roar_mm_free(self);
98  return -1;
99 }
100
101 if ( s->dir == ROAR_DIR_PLAY ) {
102#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
103   self->decoder = celt_decoder_create(self->mode, s->info.channels, NULL);
104#else
105   self->decoder = celt_decoder_create(self->mode);
106#endif
107 } else if ( s->dir == ROAR_DIR_MONITOR || s->dir == ROAR_DIR_OUTPUT ) {
108#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
109   self->encoder = celt_encoder_create(self->mode, s->info.channels, NULL);
110#else
111   self->encoder = celt_encoder_create(self->mode);
112#endif
113 } else if ( s->dir == ROAR_DIR_BIDIR || s->dir == ROAR_DIR_RECPLAY ) {
114#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
115   self->decoder = celt_decoder_create(self->mode, s->info.channels, NULL);
116   self->encoder = celt_encoder_create(self->mode, s->info.channels, NULL);
117#else
118   self->decoder = celt_decoder_create(self->mode);
119   self->encoder = celt_encoder_create(self->mode);
120#endif
121 } else {
122  celt_mode_destroy(self->mode);
123  roar_mm_free(self);
124  return -1;
125 }
126
127 *inst = (CODECFILTER_USERDATA_T) self;
128
129 s->info.codec = ROAR_CODEC_DEFAULT;
130 s->info.bits  = 16; // CELT hardcoded
131
132 return 0;
133}
134
135int cf_celt_close(CODECFILTER_USERDATA_T   inst) {
136 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
137
138 if ( !inst )
139  return -1;
140
141 if ( self->encoder != NULL )
142  celt_encoder_destroy(self->encoder);
143
144 if ( self->decoder != NULL )
145  celt_decoder_destroy(self->decoder);
146
147 if ( self->mode != NULL )
148  celt_mode_destroy(self->mode);
149
150 if ( self->ibuf != NULL )
151  roar_mm_free(self->ibuf);
152
153 if ( self->obuf != NULL )
154  roar_mm_free(self->obuf);
155
156 if ( self->i_rest != NULL )
157  roar_mm_free(self->i_rest);
158
159 if ( self->o_rest != NULL )
160  roar_mm_free(self->o_rest);
161
162 roar_mm_free(inst);
163 return 0;
164}
165
166int cf_celt_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
167 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
168 int r = 0;
169 uint16_t fs;
170 char * cbuf;
171 char magic[ROAR_CELT_MAGIC_LEN];
172
173// printf("buf=%p, len=%i\n", buf, len);
174
175 if ( !self->opened_decoder ) {
176  errno = ENOSYS;
177  if ( stream_vio_s_read(self->stream, magic, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN )
178   return -1;
179  if ( memcmp(magic, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != 0 )
180   return -1;
181
182  errno = 0;
183  self->opened_decoder = 1;
184 }
185
186 if ( self->fi_rest ) {
187  memcpy(buf, self->i_rest, self->fi_rest);
188  r += self->fi_rest;
189  self->fi_rest = 0;
190 }
191
192 while ( r <= (len - self->s_buf) ) {
193  if ( stream_vio_s_read(self->stream, &fs, 2) != 2 )
194   break;
195
196  fs = ROAR_NET2HOST16(fs);
197
198//  ROAR_WARN("0:fs=%i", fs);
199
200  if ( fs > self->s_buf )
201   return -1;
202
203  if ( stream_vio_s_read(self->stream, self->ibuf, fs) != fs )
204   return -1;
205
206  cbuf = buf + r;
207
208//  printf("buf=%p, r=%i // cbuf=%p\n", buf, r, cbuf);
209  if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) cbuf) < 0 )
210   return -1;
211
212  r += self->s_buf;
213 }
214
215 if ( r < len ) {
216//  printf("r < len!\n");
217  if ( stream_vio_s_read(self->stream, &fs, 2) == 2 ) {
218   fs = ROAR_NET2HOST16(fs);
219//  ROAR_WARN("1:fs=%i", fs);
220//   printf("next: fs=%i\n", fs);
221   if ( fs > self->s_buf )
222    return -1;
223   if ( stream_vio_s_read(self->stream, self->ibuf, fs) == fs ) {
224//    printf("got data!\n");
225    if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) self->obuf) >= 0 ) {
226//     printf("{ // decode rest\n");
227//     printf(" r=%i // need %i Bytes\n", r, len - r);
228//     printf(" memcpy(buf+%i, self->obuf, %i) = ?\n", r, len - r);
229     memcpy(buf+r, self->obuf, len - r);
230     self->fi_rest = self->s_buf + r - len;
231     memcpy(self->i_rest, self->obuf + len - r, self->fi_rest);
232//     printf(" len=%i, r=%i, fi_rest=%i, s_buf=%i\n", len, r, self->fi_rest, self->s_buf);
233     r = len;
234//     printf("}\n");
235    }
236   }
237  }
238 }
239
240 ROAR_DBG("cf_celt_read(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, r);
241 return r;
242}
243
244#define BS (ROAR_STREAM(self->stream)->info.channels * 32)
245int cf_celt_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
246 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
247 int have = 0;
248 int org_len = len;
249 int diff;
250 int fs2 = self->frame_size * 2 * ROAR_STREAM(self->stream)->info.channels;
251 int sid;
252 uint16_t pkglen_net, pkglen;
253 unsigned char cbits[BS+2];
254 void * prethru;
255
256 if ( !self->opened_encoder ) {
257  sid = ROAR_STREAM(self->stream)->id;
258
259  if ( stream_prethru_destroy(sid) == -1 ) {
260   return -1;
261  }
262
263  if ( stream_prethru_add_data(sid, &prethru, ROAR_CELT_MAGIC_LEN) == -1 ) {
264   return -1;
265  }
266
267  memcpy(prethru, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN);
268
269  if ( stream_vio_s_write(self->stream, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN )
270   return -1;
271  self->opened_encoder = 1;
272 }
273
274 if ( (self->fo_rest + len) > fs2 ) {
275  if ( self->fo_rest ) {
276   memcpy(self->obuf, self->o_rest, self->fo_rest);
277   have = self->fo_rest;
278   self->fo_rest = 0;
279  }
280
281  memcpy(self->obuf+have, buf, (diff=fs2-have));
282  buf += diff;
283  len -= diff;
284
285  pkglen     = celt_encode(self->encoder, (celt_int16_t *) self->obuf, NULL, cbits+2, BS);
286  pkglen_net = ROAR_HOST2NET16(pkglen);
287  *(uint16_t*)cbits = pkglen_net;
288
289  if ( stream_vio_s_write(self->stream, cbits, pkglen+2) == -1 )
290   return -1;
291
292  while (len >= fs2) {
293   pkglen     = celt_encode(self->encoder, (celt_int16_t *) buf, NULL, cbits+2, BS);
294   pkglen_net = ROAR_HOST2NET16(pkglen);
295   *(uint16_t*)cbits = pkglen_net;
296
297   if ( stream_vio_s_write(self->stream, cbits, pkglen+2) == -1 )
298    return -1;
299   len -= fs2;
300   buf += fs2;
301  }
302 }
303
304 if ( len ) {
305  memcpy(self->o_rest + self->fo_rest, buf, len);
306  self->fo_rest += len;
307  len            = 0;
308 }
309
310 return org_len;
311}
312
313int cf_celt_delay(CODECFILTER_USERDATA_T   inst, uint_least32_t * delay) {
314 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
315
316 ROAR_DBG("cf_celt_delay(*) = ?");
317
318 if ( self == NULL ) {
319  *delay = (1000000 * 256) / ROAR_RATE_DEFAULT;
320  return 0;
321 } else {
322  *delay = (1000000 * self->frame_size) / ROAR_STREAM(self->stream)->info.rate;
323  ROAR_DBG("cf_celt_delay(*): frame_size=%i, rate=%i, *delay=%i",
324                  self->frame_size, ROAR_STREAM(self->stream)->info.rate, *delay);
325  return 0;
326 }
327
328 return -1;
329}
330
331#endif
332//ll
Note: See TracBrowser for help on using the repository browser.