source: roaraudio/roard/codecfilter_celt.c @ 3517:1a3218a3fc5b

Last change on this file since 3517:1a3218a3fc5b was 3517:1a3218a3fc5b, checked in by phi, 14 years ago

updated license headers, FSF moved office

File size: 8.0 KB
Line 
1//codecfilter_celt.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
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
29int cf_celt_open(CODECFILTER_USERDATA_T * inst, int codec,
30                                            struct roar_stream_server * info,
31                                            struct roar_codecfilter   * filter) {
32 struct codecfilter_celt_inst * self = malloc(sizeof(struct codecfilter_celt_inst));
33 struct roar_stream * s = ROAR_STREAM(info);
34
35 if ( !self )
36  return -1;
37
38/*
39 CELTMode * mode;
40 CELTEncoder * encoder;
41 CELTDecoder * decoder;
42 int frame_size;
43 int lookahead;
44 int out_size;
45 char * ibuf;
46 char * obuf;
47 char * rest;
48 int s_buf;
49 int f_rest; /-* how much is in rest? *-/
50*/
51
52 self->stream               = info;
53 self->frame_size           = 256;
54 self->lookahead            = self->frame_size;
55 self->encoder              = NULL;
56 self->decoder              = NULL;
57 self->opened_encoder       = 0;
58 self->opened_decoder       = 0;
59 self->s_buf                = s->info.channels * self->frame_size * 2;
60 self->ibuf                 = malloc(self->s_buf);
61 self->obuf                 = malloc(self->s_buf);
62 self->i_rest               = malloc(self->s_buf);
63 self->o_rest               = malloc(self->s_buf);
64 self->fi_rest              = 0;
65 self->fo_rest              = 0;
66
67 if ( !(self->ibuf && self->obuf && self->i_rest && self->o_rest) ) {
68  if ( self->ibuf )
69   free(self->ibuf);
70
71  if ( self->obuf )
72   free(self->obuf);
73
74  if ( self->i_rest )
75   free(self->o_rest);
76
77  if ( self->o_rest )
78   free(self->o_rest);
79
80  free(self);
81  return -1;
82 }
83 
84 self->mode                 = celt_mode_create(s->info.rate, s->info.channels, self->frame_size, NULL);
85
86 if ( !self->mode ) {
87  free(self);
88  return -1;
89 }
90
91 if ( s->dir == ROAR_DIR_PLAY ) {
92   self->decoder = celt_decoder_create(self->mode);
93 } else if ( s->dir == ROAR_DIR_MONITOR || s->dir == ROAR_DIR_OUTPUT ) {
94   self->encoder = celt_encoder_create(self->mode);
95 } else if ( s->dir == ROAR_DIR_BIDIR ) {
96   self->decoder = celt_decoder_create(self->mode);
97   self->encoder = celt_encoder_create(self->mode);
98 } else {
99  celt_mode_destroy(self->mode);
100  free(self);
101  return -1;
102 }
103
104 *inst = (CODECFILTER_USERDATA_T) self;
105
106 s->info.codec = ROAR_CODEC_DEFAULT;
107 s->info.bits  = 16; // CELT hardcoded
108
109 return 0;
110}
111
112int cf_celt_close(CODECFILTER_USERDATA_T   inst) {
113 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
114
115 if ( !inst )
116  return -1;
117
118 if ( self->encoder )
119  celt_encoder_destroy(self->encoder);
120
121 if ( self->decoder )
122  celt_decoder_destroy(self->decoder);
123
124 if ( self->mode )
125  celt_mode_destroy(self->mode);
126
127 if ( self->ibuf )
128  free(self->ibuf);
129
130 if ( self->obuf )
131  free(self->obuf);
132
133 if ( self->i_rest )
134  free(self->i_rest);
135
136 if ( self->o_rest )
137  free(self->o_rest);
138
139 free(inst);
140 return 0;
141}
142
143int cf_celt_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
144 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
145 int r = 0;
146 uint16_t fs;
147 char * cbuf;
148 char magic[ROAR_CELT_MAGIC_LEN];
149
150// printf("buf=%p, len=%i\n", buf, len);
151
152 if ( !self->opened_decoder ) {
153  errno = ENOSYS;
154  if ( stream_vio_s_read(self->stream, magic, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN )
155   return -1;
156  if ( memcmp(magic, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != 0 )
157   return -1;
158
159  errno = 0;
160  self->opened_decoder = 1;
161 }
162
163 if ( self->fi_rest ) {
164  memcpy(buf, self->i_rest, self->fi_rest);
165  r += self->fi_rest;
166  self->fi_rest = 0;
167 }
168
169 while ( r <= (len - self->s_buf) ) {
170  if ( stream_vio_s_read(self->stream, &fs, 2) != 2 )
171   break;
172
173  fs = ROAR_NET2HOST16(fs);
174
175//  ROAR_WARN("0:fs=%i", fs);
176
177  if ( fs > self->s_buf )
178   return -1;
179
180  if ( stream_vio_s_read(self->stream, self->ibuf, fs) != fs )
181   return -1;
182
183  cbuf = buf + r;
184
185//  printf("buf=%p, r=%i // cbuf=%p\n", buf, r, cbuf);
186  if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) cbuf) < 0 )
187   return -1;
188
189  r += self->s_buf;
190 }
191
192 if ( r < len ) {
193//  printf("r < len!\n");
194  if ( stream_vio_s_read(self->stream, &fs, 2) == 2 ) {
195   fs = ROAR_NET2HOST16(fs);
196//  ROAR_WARN("1:fs=%i", fs);
197//   printf("next: fs=%i\n", fs);
198   if ( fs > self->s_buf )
199    return -1;
200   if ( stream_vio_s_read(self->stream, self->ibuf, fs) == fs ) {
201//    printf("got data!\n");
202    if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) self->obuf) >= 0 ) {
203//     printf("{ // decode rest\n");
204//     printf(" r=%i // need %i Bytes\n", r, len - r);
205//     printf(" memcpy(buf+%i, self->obuf, %i) = ?\n", r, len - r);
206     memcpy(buf+r, self->obuf, len - r);
207     self->fi_rest = self->s_buf + r - len;
208     memcpy(self->i_rest, self->obuf + len - r, self->fi_rest);
209//     printf(" len=%i, r=%i, fi_rest=%i, s_buf=%i\n", len, r, self->fi_rest, self->s_buf);
210     r = len;
211//     printf("}\n");
212    }
213   }
214  }
215 }
216
217 ROAR_DBG("cf_celt_read(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, r);
218 return r;
219}
220
221#define BS (ROAR_STREAM(self->stream)->info.channels * 32)
222int cf_celt_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
223 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
224 int have = 0;
225 int org_len = len;
226 int diff;
227 int fs2 = self->frame_size * 2 * ROAR_STREAM(self->stream)->info.channels;
228 int sid;
229 uint16_t pkglen_net, pkglen;
230 unsigned char cbits[BS+2];
231 void * prethru;
232
233 if ( !self->opened_encoder ) {
234  sid = ROAR_STREAM(self->stream)->id;
235
236  if ( stream_prethru_destroy(sid) == -1 ) {
237   return -1;
238  }
239
240  if ( stream_prethru_add_data(sid, &prethru, ROAR_CELT_MAGIC_LEN) == -1 ) {
241   return -1;
242  }
243
244  memcpy(prethru, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN);
245
246  if ( stream_vio_s_write(self->stream, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN )
247   return -1;
248  self->opened_encoder = 1;
249 }
250
251 if ( (self->fo_rest + len) > fs2 ) {
252  if ( self->fo_rest ) {
253   memcpy(self->obuf, self->o_rest, self->fo_rest);
254   have = self->fo_rest;
255   self->fo_rest = 0;
256  }
257
258  memcpy(self->obuf+have, buf, (diff=fs2-have));
259  buf += diff;
260  len -= diff;
261
262  pkglen     = celt_encode(self->encoder, (celt_int16_t *) self->obuf, NULL, cbits+2, BS);
263  pkglen_net = ROAR_HOST2NET16(pkglen);
264  *(uint16_t*)cbits = pkglen_net;
265
266  if ( stream_vio_s_write(self->stream, cbits, pkglen+2) == -1 )
267   return -1;
268
269  while (len >= fs2) {
270   pkglen     = celt_encode(self->encoder, (celt_int16_t *) buf, NULL, cbits+2, BS);
271   pkglen_net = ROAR_HOST2NET16(pkglen);
272   *(uint16_t*)cbits = pkglen_net;
273
274   if ( stream_vio_s_write(self->stream, cbits, pkglen+2) == -1 )
275    return -1;
276   len -= fs2;
277   buf += fs2;
278  }
279 }
280
281 if ( len ) {
282  memcpy(self->o_rest + self->fo_rest, buf, len);
283  self->fo_rest += len;
284  len            = 0;
285 }
286
287 return org_len;
288}
289
290int cf_celt_delay(CODECFILTER_USERDATA_T   inst, uint_least32_t * delay) {
291 struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst;
292
293 ROAR_DBG("cf_celt_delay(*) = ?");
294
295 if ( self == NULL ) {
296  *delay = (1000000 * 256) / ROAR_RATE_DEFAULT;
297  return 0;
298 } else {
299  *delay = (1000000 * self->frame_size) / ROAR_STREAM(self->stream)->info.rate;
300  ROAR_DBG("cf_celt_delay(*): frame_size=%i, rate=%i, *delay=%i",
301                  self->frame_size, ROAR_STREAM(self->stream)->info.rate, *delay);
302  return 0;
303 }
304
305 return -1;
306}
307
308#endif
309//ll
Note: See TracBrowser for help on using the repository browser.