source: roaraudio/libroardsp/transcode_celt.c @ 4708:c9d40761088a

Last change on this file since 4708:c9d40761088a was 4708:c9d40761088a, checked in by phi, 13 years ago

updated copyright statements

File size: 5.3 KB
RevLine 
[2187]1//transcode_celt.c:
2
3/*
[4708]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2011
[2187]5 *
6 *  This file is part of libroardsp 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 *  libroardsp 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
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[2187]23 *
24 */
25
26#include "libroardsp.h"
27
28#ifdef ROAR_HAVE_LIBCELT
29
[2193]30#define _16BIT (16/8)
[2199]31#define _SIZE_LEN 2
[2192]32
[4152]33#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
34typedef celt_int16 celt_int16_t;
35#endif
36
[2188]37int roar_xcoder_celt_init       (struct roar_xcoder * state) {
[3063]38 struct roar_xcoder_celt * self = roar_mm_malloc(sizeof(struct roar_xcoder_celt));
[2191]39 struct roar_audio_info  * info = &(state->info.pcm);
40
41 if ( self == NULL )
42  return -1;
43
44 // curruntly only 16 bit mode is supported
45 if ( info->bits != 16 ) {
[3063]46  roar_mm_free(self);
[2191]47  return -1;
48 }
49
50 memset(self, 0, sizeof(struct roar_xcoder_celt));
51
52 state->inst = self;
53
54 self->frame_size           = 256;
55
[2204]56 self->bufferlen            = info->channels * 32 + _SIZE_LEN;
[3063]57 self->iobuffer             = roar_mm_malloc(self->bufferlen);
[2199]58
59 if ( self->iobuffer == NULL ) {
[3063]60  roar_mm_free(self);
[2199]61  return -1;
62 }
63
[4152]64#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
65 self->mode                 = celt_mode_create(info->rate, self->frame_size, NULL);
66#else
[2191]67 self->mode                 = celt_mode_create(info->rate, info->channels, self->frame_size, NULL);
[4152]68#endif
[2191]69
70 if ( self->mode == NULL ) {
[3063]71  roar_mm_free(self->iobuffer);
72  roar_mm_free(self);
[2191]73  return -1;
74 }
75
76 if (state->encode) {
[4152]77#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
78  self->encoder = celt_encoder_create(self->mode, info->channels, NULL);
79#else
[2191]80  self->encoder = celt_encoder_create(self->mode);
[4152]81#endif
[2191]82  if ( self->encoder == NULL ) {
83   roar_xcoder_celt_uninit(state);
84   return -1;
85  }
86 } else {
[4152]87#ifdef ROAR_HAVE_CELT_VERSION_0_7_1
88  self->decoder = celt_decoder_create(self->mode, info->channels, NULL);
89#else
[2191]90  self->decoder = celt_decoder_create(self->mode);
[4152]91#endif
[2191]92  if ( self->decoder == NULL ) {
93   roar_xcoder_celt_uninit(state);
94   return -1;
95  }
96 }
97
[2197]98 ROAR_DBG("roar_xcoder_celt_init(*) = 0");
99
[2191]100 return 0;
[2188]101}
102
103int roar_xcoder_celt_uninit     (struct roar_xcoder * state) {
[2191]104 struct roar_xcoder_celt * self = state->inst;
105
[2199]106 if ( self->iobuffer )
[3063]107  roar_mm_free(self->iobuffer);
[2199]108
[2191]109 if ( self->encoder )
[2200]110  celt_encoder_destroy(self->encoder);
[2191]111
112 if ( self->decoder )
[2200]113  celt_decoder_destroy(self->decoder);
[2191]114
115 if ( self->mode )
116  celt_mode_destroy(self->mode);
117
[3063]118 roar_mm_free(self);
[2191]119
[2197]120 ROAR_DBG("roar_xcoder_celt_uninit(*) = 0");
121
122 return 0;
[2188]123}
124
125int roar_xcoder_celt_packet_size(struct roar_xcoder * state, int samples) {
[2191]126 struct roar_xcoder_celt * self = state->inst;
[2197]127 register int ret = self->frame_size * _16BIT * state->info.pcm.channels;
[2191]128
[2197]129 ROAR_DBG("roar_xcoder_celt_packet_size(state=%p, samples=%i) = %i", state, samples, ret);
130
131 return ret;
[2188]132}
133
134int roar_xcoder_celt_encode     (struct roar_xcoder * state, void * buf, size_t len) {
[2191]135 struct roar_xcoder_celt * self = state->inst;
[2199]136 uint16_t * lenp = self->iobuffer;
137 void     * cp   = self->iobuffer + _SIZE_LEN;
[2201]138 uint16_t   pkglen;
[2191]139
[2197]140 ROAR_DBG("roar_xcoder_celt_encode(*): test if we are in encoding mode...");
141
[2191]142 if (!state->encode)
143  return -1;
144
[2197]145 ROAR_DBG("roar_xcoder_celt_encode(*): Encoding...");
146
[2193]147 if ( state->stage == ROAR_XCODER_STAGE_INITED ) {
[2192]148  if ( roar_vio_write(state->backend, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN )
149   return -1;
150  state->stage = ROAR_XCODER_STAGE_MAGIC;
[2197]151  ROAR_DBG("roar_xcoder_celt_encode(*): Wrote MAGIC");
[2192]152 }
153
[2201]154 pkglen  = celt_encode(self->encoder, (celt_int16_t *) buf, NULL, cp, self->bufferlen - _SIZE_LEN);
155 *lenp   = ROAR_HOST2NET16(pkglen);
156
157 if ( roar_vio_write(state->backend, self->iobuffer, pkglen+2) == -1 )
158  return -1;
159
160 return 0;
[2188]161}
162
163int roar_xcoder_celt_decode     (struct roar_xcoder * state, void * buf, size_t len) {
[2191]164 struct roar_xcoder_celt * self = state->inst;
[2203]165 uint16_t * lenp = self->iobuffer;
166 void     * cp   = self->iobuffer + _SIZE_LEN;
167 uint16_t   pkglen;
168 char       magic[ROAR_CELT_MAGIC_LEN];
[2191]169
[2197]170 ROAR_DBG("roar_xcoder_celt_decode(*): test if we are in decoding mode...");
171
[2191]172 if (state->encode)
173  return -1;
174
[2203]175 if ( state->stage == ROAR_XCODER_STAGE_INITED ) {
176  if ( roar_vio_read(state->backend, magic, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN )
177   return -1;
178
179  if ( memcmp(magic, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != 0 )
180   return -1;
181
182  state->stage = ROAR_XCODER_STAGE_MAGIC;
183  ROAR_DBG("roar_xcoder_celt_decode(*): Found valid Magic");
184 }
185
186 if ( roar_vio_read(state->backend, lenp, _SIZE_LEN) != _SIZE_LEN )
187  return -1;
188
189 pkglen = ROAR_NET2HOST16(*lenp);
190
191 if ( pkglen > (self->bufferlen - _SIZE_LEN) )
192  return -1;
193
194 if ( roar_vio_read(state->backend, cp, pkglen) != pkglen )
195  return -1;
196
197 if ( celt_decode(self->decoder, cp, pkglen, (celt_int16_t *) buf) < 0 )
198  return -1;
199
200 return 0;
[2188]201}
[2187]202
203#endif
204
205//ll
Note: See TracBrowser for help on using the repository browser.