//codecfilter_celt.c: #include "roard.h" #ifdef ROAR_HAVE_LIBCELT int cf_celt_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_celt_inst * self = malloc(sizeof(struct codecfilter_celt_inst)); struct roar_stream * s = ROAR_STREAM(info); if ( !self ) return -1; /* CELTMode * mode; CELTEncoder * encoder; CELTDecoder * decoder; int frame_size; int lookahead; int out_size; char * ibuf; char * obuf; char * rest; int s_buf; int f_rest; /-* how much is in rest? *-/ */ self->stream = info; self->frame_size = 256; self->lookahead = self->frame_size; self->encoder = NULL; self->decoder = NULL; self->s_buf = s->info.channels * self->frame_size * 2; self->ibuf = malloc(self->s_buf); self->obuf = malloc(self->s_buf); self->i_rest = malloc(self->s_buf); self->o_rest = malloc(self->s_buf); self->fi_rest = 0; self->fo_rest = 0; if ( !(self->ibuf && self->obuf && self->i_rest && self->o_rest) ) { if ( self->ibuf ) free(self->ibuf); if ( self->obuf ) free(self->obuf); if ( self->i_rest ) free(self->o_rest); if ( self->o_rest ) free(self->o_rest); free(self); return -1; } self->mode = celt_mode_create(s->info.rate, s->info.channels, self->frame_size, NULL); if ( !self->mode ) { free(self); return -1; } if ( s->dir == ROAR_DIR_PLAY ) { self->decoder = celt_decoder_create(self->mode); } else if ( s->dir == ROAR_DIR_MONITOR ) { self->encoder = celt_encoder_create(self->mode); } else { celt_mode_destroy(self->mode); free(self); return -1; } *inst = (CODECFILTER_USERDATA_T) self; s->info.codec = ROAR_CODEC_DEFAULT; s->info.bits = 16; // CELT hardcoded return 0; } int cf_celt_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; if ( !inst ) return -1; if ( self->encoder ) celt_encoder_destroy(self->encoder); if ( self->decoder ) celt_decoder_destroy(self->decoder); if ( self->mode ) celt_mode_destroy(self->mode); if ( self->ibuf ) free(self->ibuf); if ( self->obuf ) free(self->obuf); if ( self->i_rest ) free(self->i_rest); if ( self->o_rest ) free(self->o_rest); free(inst); return 0; } int cf_celt_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; int r = 0; uint16_t fs; char * cbuf; // printf("buf=%p, len=%i\n", buf, len); if ( self->fi_rest ) { memcpy(buf, self->i_rest, self->fi_rest); r += self->fi_rest; self->fi_rest = 0; } while ( r <= (len - self->s_buf) ) { if ( stream_vio_s_read(self->stream, &fs, 2) != 2 ) break; fs = ROAR_NET2HOST16(fs); if ( stream_vio_s_read(self->stream, self->ibuf, fs) != fs ) break; cbuf = buf + r; // printf("buf=%p, r=%i // cbuf=%p\n", buf, r, cbuf); if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) cbuf) < 0 ) break; r += self->s_buf; } if ( r < len ) { // printf("r < len!\n"); if ( stream_vio_s_read(self->stream, &fs, 2) == 2 ) { fs = ROAR_NET2HOST16(fs); // printf("next: fs=%i\n", fs); if ( stream_vio_s_read(self->stream, self->ibuf, fs) == fs ) { // printf("got data!\n"); if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) self->obuf) >= 0 ) { // printf("{ // decode rest\n"); // printf(" r=%i // need %i Bytes\n", r, len - r); // printf(" memcpy(buf+%i, self->obuf, %i) = ?\n", r, len - r); memcpy(buf+r, self->obuf, len - r); self->fi_rest = self->s_buf + r - len; memcpy(self->i_rest, self->obuf + len - r, self->fi_rest); // printf(" len=%i, r=%i, fi_rest=%i, s_buf=%i\n", len, r, self->fi_rest, self->s_buf); r = len; // printf("}\n"); } } } } ROAR_DBG("cf_celt_read(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, r); return r; } int cf_celt_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; return 0; } #endif //ll