source: roaraudio/roard/codecfilter_celt.c @ 3358:7f9d211148e0

Last change on this file since 3358:7f9d211148e0 was 2816:b9e357b0dc43, checked in by phi, 15 years ago

added prethru support and updated list of codecs a bit

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