source: roaraudio/libroardsp/transcode_celt.c @ 3329:d939b3aedbc5

Last change on this file since 3329:d939b3aedbc5 was 3063:955233719a84, checked in by phi, 14 years ago

use memory functions from libroar, not libc, fixed a small memory leak

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