source: roaraudio/libroardsp/transcode_speex.c @ 2637:38fc8e7a38c9

Last change on this file since 2637:38fc8e7a38c9 was 2315:1907cbac71d4, checked in by phi, 15 years ago

set rate :)

File size: 7.5 KB
RevLine 
[2295]1//transcode_speex.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_LIBSPEEX
28
29#define _16BIT (16/8)
30#define _SIZE_LEN 2
31
[2296]32int roar_xcoder_speex_init       (struct roar_xcoder * state) {
[2298]33 struct roar_xcoder_speex * self = malloc(sizeof(struct roar_xcoder_speex));
34 struct roar_audio_info  * info = &(state->info.pcm);
35 int tmp;
36
[2311]37 ROAR_DBG("roar_xcoder_speex_init(*): sizeof(*self) = %lu", (unsigned long)sizeof(*self));
38
[2298]39 if ( self == NULL )
40  return -1;
41
42 // curruntly only 16 bit mode is supported
43 if ( info->bits != 16 ) {
44  free(self);
45  return -1;
46 }
47
[2305]48 // only mono/stereo mode is supported
49 switch (info->channels) {
50  case 1: self->stereo = 0; break;
51  case 2: self->stereo = 1; break;
52  default:
53    free(self);
54    return -1;
[2298]55 }
56
57 memset(self, 0, sizeof(struct roar_xcoder_speex));
58
59 state->inst = self;
60
61 self->mode  = ROAR_SPEEX_MODE_UWB;
62
63 if (state->encode) {
64  switch (self->mode) {
65   case ROAR_SPEEX_MODE_NB:  self->xcoder = speex_encoder_init(&speex_nb_mode);  break;
66   case ROAR_SPEEX_MODE_WB:  self->xcoder = speex_encoder_init(&speex_wb_mode);  break;
67   case ROAR_SPEEX_MODE_UWB: self->xcoder = speex_encoder_init(&speex_uwb_mode); break;
68  }
69  tmp = 8;
[2302]70  speex_encoder_ctl(self->xcoder, SPEEX_SET_QUALITY,       &tmp);
71  tmp = info->rate;
72  speex_encoder_ctl(self->xcoder, SPEEX_SET_SAMPLING_RATE, &tmp);
73  speex_encoder_ctl(self->xcoder, SPEEX_GET_FRAME_SIZE,    &(self->frame_size));
[2298]74 } else {
75  self->xcoder = NULL;
76 }
77
78 speex_bits_init(&(self->bits));
79
80 return 0;
[2296]81}
82
83int roar_xcoder_speex_uninit     (struct roar_xcoder * state) {
[2298]84 struct roar_xcoder_speex * self = state->inst;
85
86 if ( self->xcoder != NULL ) {
87  if (state->encode) {
88   speex_encoder_destroy(self->xcoder);
89  } else {
90   speex_decoder_destroy(self->xcoder);
91  }
92 }
93
94 speex_bits_destroy(&(self->bits));
95
96 free(self);
97
98 return 0;
[2296]99}
100
101int roar_xcoder_speex_packet_size(struct roar_xcoder * state, int samples) {
[2298]102 struct roar_xcoder_speex * self = state->inst;
[2300]103
104 if (!state->encode)
105  if (state->stage != ROAR_XCODER_STAGE_OPENED)
106   return -1;
[2298]107
[2305]108 return _16BIT * self->frame_size * (self->stereo ? 2 : 1);
[2296]109}
110
111int roar_xcoder_speex_encode     (struct roar_xcoder * state, void * buf, size_t len) {
[2299]112 struct roar_xcoder_speex * self = state->inst;
113 uint16_t tmp_net;
114 int pkg_len;
115
116 if (!state->encode)
117  return -1;
118
119 ROAR_DBG("roar_xcoder_speex_encode(*): Encoding...");
120
121 if ( state->stage == ROAR_XCODER_STAGE_INITED ) {
122  if ( roar_vio_write(state->backend, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN )
123   return -1;
124  state->stage = ROAR_XCODER_STAGE_MAGIC;
125  ROAR_DBG("roar_xcoder_speex_encode(*): Wrote MAGIC");
126
127  state->stage = ROAR_XCODER_STAGE_OPENING;
128
129  tmp_net = ROAR_HOST2NET16(self->mode);
130  if ( roar_vio_write(state->backend, &tmp_net, 2) != 2 )
131   return -1;
132
133  state->stage = ROAR_XCODER_STAGE_OPENED;
134 }
135
136 speex_bits_reset(&(self->bits));
137
[2305]138 if ( self->stereo )
139  speex_encode_stereo_int((spx_int16_t *) buf, self->frame_size, &(self->bits));
140
[2299]141 speex_encode_int(self->xcoder, (spx_int16_t *) buf, &(self->bits));
142
143 pkg_len = speex_bits_write(&(self->bits), self->cc, ROAR_SPEEX_MAX_CC);
144
145 tmp_net = ROAR_HOST2NET16(pkg_len);
146
147 if ( roar_vio_write(state->backend, &tmp_net, 2) != 2 )
148  return -1;
149
150 if ( roar_vio_write(state->backend, self->cc, pkg_len) != pkg_len )
151   return -1;
152
153 return 0;
[2296]154}
155
[2305]156// TODO: move all the init thingys into a seperate function
[2296]157int roar_xcoder_speex_decode     (struct roar_xcoder * state, void * buf, size_t len) {
[2300]158 struct roar_xcoder_speex * self = state->inst;
159 char magic[ROAR_SPEEX_MAGIC_LEN];
160 uint16_t tmp_net;
161 int pkg_len;
162 int tmp;
[2305]163 SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
164 SpeexCallback callback;
[2300]165
[2311]166 ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len);
167
[2300]168 if ( state->stage == ROAR_XCODER_STAGE_INITED ) {
[2311]169  ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): state->stage = INITED", state, buf, (unsigned long)len);
[2300]170  if ( roar_vio_read(state->backend, magic, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN )
171   return -1;
172
173  if ( memcmp(magic, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != 0 )
174   return -1;
175
176  state->stage = ROAR_XCODER_STAGE_MAGIC;
[2311]177  ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): state->stage = MAGIC", state, buf, (unsigned long)len);
[2300]178
179  if ( roar_vio_read(state->backend, &tmp_net, 2) != 2 )
180   return -1;
181
182  self->mode = ROAR_NET2HOST16(tmp_net);
183
184  state->stage = ROAR_XCODER_STAGE_OPENING;
[2311]185  ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): state->stage = OPENING", state, buf, (unsigned long)len);
[2300]186
187  switch (self->mode) {
188   case ROAR_SPEEX_MODE_NB:  self->xcoder = speex_decoder_init(&speex_nb_mode);  break;
189   case ROAR_SPEEX_MODE_WB:  self->xcoder = speex_decoder_init(&speex_wb_mode);  break;
190   case ROAR_SPEEX_MODE_UWB: self->xcoder = speex_decoder_init(&speex_uwb_mode); break;
191   default:
192     return -1;
193    break;
194  }
195
[2311]196  ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): opened decoder state", state, buf, (unsigned long)len);
197
[2300]198  tmp=1;
199  speex_decoder_ctl(self->xcoder, SPEEX_SET_ENH, &tmp);
[2302]200  tmp = state->info.pcm.rate;
[2315]201  speex_decoder_ctl(self->xcoder, SPEEX_SET_SAMPLING_RATE, &tmp);
[2300]202  speex_decoder_ctl(self->xcoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size));
203
[2311]204  ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): self->stereo = %i", state, buf, (unsigned long)len, self->stereo);
205
[2305]206  if ( self->stereo ) {
207   memcpy(&(self->stereo_state), &stereo, sizeof(self->stereo_state));
208
209   callback.callback_id = SPEEX_INBAND_STEREO;
210   callback.func = speex_std_stereo_request_handler;
211   callback.data = &(self->stereo_state);
212
213   speex_decoder_ctl(self->xcoder, SPEEX_SET_HANDLER, &callback);
214  }
215
[2300]216  state->stage = ROAR_XCODER_STAGE_OPENED;
[2311]217  ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): state->stage = OPENED", state, buf, (unsigned long)len);
[2300]218 }
219
[2311]220 ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): state->stage = %s", state, buf, (unsigned long)len,
221          state->stage == ROAR_XCODER_STAGE_OPENED ? "OPENED" : "???"
222         );
223
[2300]224 if ( roar_vio_read(state->backend, &tmp_net, 2) != 2 )
225  return -1;
226
227 pkg_len = ROAR_NET2HOST16(tmp_net);
228
229 if ( pkg_len > ROAR_SPEEX_MAX_CC )
230  return -1;
231
[2311]232 ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len);
233
[2300]234 if ( roar_vio_read(state->backend, self->cc, pkg_len) != pkg_len )
235  return -1;
236
237 speex_bits_read_from(&(self->bits), self->cc, pkg_len);
238
239 speex_decode_int(self->xcoder, &(self->bits), buf);
240
[2305]241 if ( self->stereo ) {
242  speex_decode_stereo_int(buf, self->frame_size, &(self->stereo_state));
243 }
244
[2311]245 ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu) = 0", state, buf, (unsigned long)len);
[2300]246 return 0;
[2296]247}
248
[2295]249#endif
250
251//ll
Note: See TracBrowser for help on using the repository browser.