source: roaraudio/libroardsp/transcode_speex.c @ 2302:f9147317b974

Last change on this file since 2302:f9147317b974 was 2302:f9147317b974, checked in by phi, 15 years ago

set sample rate

File size: 5.4 KB
Line 
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
32int roar_xcoder_speex_init       (struct roar_xcoder * state) {
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
37 if ( self == NULL )
38  return -1;
39
40 // curruntly only 16 bit mode is supported
41 if ( info->bits != 16 ) {
42  free(self);
43  return -1;
44 }
45
46 // curruntly only mono mode is supported
47 if ( info->channels != 1 ) {
48  free(self);
49  return -1;
50 }
51
52 memset(self, 0, sizeof(struct roar_xcoder_speex));
53
54 state->inst = self;
55
56 self->mode  = ROAR_SPEEX_MODE_UWB;
57
58 if (state->encode) {
59  switch (self->mode) {
60   case ROAR_SPEEX_MODE_NB:  self->xcoder = speex_encoder_init(&speex_nb_mode);  break;
61   case ROAR_SPEEX_MODE_WB:  self->xcoder = speex_encoder_init(&speex_wb_mode);  break;
62   case ROAR_SPEEX_MODE_UWB: self->xcoder = speex_encoder_init(&speex_uwb_mode); break;
63  }
64  tmp = 8;
65  speex_encoder_ctl(self->xcoder, SPEEX_SET_QUALITY,       &tmp);
66  tmp = info->rate;
67  speex_encoder_ctl(self->xcoder, SPEEX_SET_SAMPLING_RATE, &tmp);
68  speex_encoder_ctl(self->xcoder, SPEEX_GET_FRAME_SIZE,    &(self->frame_size));
69 } else {
70  self->xcoder = NULL;
71 }
72
73 speex_bits_init(&(self->bits));
74
75 return 0;
76}
77
78int roar_xcoder_speex_uninit     (struct roar_xcoder * state) {
79 struct roar_xcoder_speex * self = state->inst;
80
81 if ( self->xcoder != NULL ) {
82  if (state->encode) {
83   speex_encoder_destroy(self->xcoder);
84  } else {
85   speex_decoder_destroy(self->xcoder);
86  }
87 }
88
89 speex_bits_destroy(&(self->bits));
90
91 free(self);
92
93 return 0;
94}
95
96int roar_xcoder_speex_packet_size(struct roar_xcoder * state, int samples) {
97 struct roar_xcoder_speex * self = state->inst;
98
99 if (!state->encode)
100  if (state->stage != ROAR_XCODER_STAGE_OPENED)
101   return -1;
102
103 return _16BIT * self->frame_size;
104}
105
106int roar_xcoder_speex_encode     (struct roar_xcoder * state, void * buf, size_t len) {
107 struct roar_xcoder_speex * self = state->inst;
108 uint16_t tmp_net;
109 int pkg_len;
110
111 if (!state->encode)
112  return -1;
113
114 ROAR_DBG("roar_xcoder_speex_encode(*): Encoding...");
115
116 if ( state->stage == ROAR_XCODER_STAGE_INITED ) {
117  if ( roar_vio_write(state->backend, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN )
118   return -1;
119  state->stage = ROAR_XCODER_STAGE_MAGIC;
120  ROAR_DBG("roar_xcoder_speex_encode(*): Wrote MAGIC");
121
122  state->stage = ROAR_XCODER_STAGE_OPENING;
123
124  tmp_net = ROAR_HOST2NET16(self->mode);
125  if ( roar_vio_write(state->backend, &tmp_net, 2) != 2 )
126   return -1;
127
128  state->stage = ROAR_XCODER_STAGE_OPENED;
129 }
130
131 speex_bits_reset(&(self->bits));
132
133 speex_encode_int(self->xcoder, (spx_int16_t *) buf, &(self->bits));
134
135 pkg_len = speex_bits_write(&(self->bits), self->cc, ROAR_SPEEX_MAX_CC);
136
137 tmp_net = ROAR_HOST2NET16(pkg_len);
138
139 if ( roar_vio_write(state->backend, &tmp_net, 2) != 2 )
140  return -1;
141
142 if ( roar_vio_write(state->backend, self->cc, pkg_len) != pkg_len )
143   return -1;
144
145 return 0;
146}
147
148int roar_xcoder_speex_decode     (struct roar_xcoder * state, void * buf, size_t len) {
149 struct roar_xcoder_speex * self = state->inst;
150 char magic[ROAR_SPEEX_MAGIC_LEN];
151 uint16_t tmp_net;
152 int pkg_len;
153 int tmp;
154
155 if ( state->stage == ROAR_XCODER_STAGE_INITED ) {
156  if ( roar_vio_read(state->backend, magic, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN )
157   return -1;
158
159  if ( memcmp(magic, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != 0 )
160   return -1;
161
162  state->stage = ROAR_XCODER_STAGE_MAGIC;
163
164  if ( roar_vio_read(state->backend, &tmp_net, 2) != 2 )
165   return -1;
166
167  self->mode = ROAR_NET2HOST16(tmp_net);
168
169  state->stage = ROAR_XCODER_STAGE_OPENING;
170
171  switch (self->mode) {
172   case ROAR_SPEEX_MODE_NB:  self->xcoder = speex_decoder_init(&speex_nb_mode);  break;
173   case ROAR_SPEEX_MODE_WB:  self->xcoder = speex_decoder_init(&speex_wb_mode);  break;
174   case ROAR_SPEEX_MODE_UWB: self->xcoder = speex_decoder_init(&speex_uwb_mode); break;
175   default:
176     return -1;
177    break;
178  }
179
180  tmp=1;
181  speex_decoder_ctl(self->xcoder, SPEEX_SET_ENH, &tmp);
182  tmp = state->info.pcm.rate;
183  speex_encoder_ctl(self->xcoder, SPEEX_SET_SAMPLING_RATE, &tmp);
184  speex_decoder_ctl(self->xcoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size));
185
186  state->stage = ROAR_XCODER_STAGE_OPENED;
187 }
188
189 if ( roar_vio_read(state->backend, &tmp_net, 2) != 2 )
190  return -1;
191
192 pkg_len = ROAR_NET2HOST16(tmp_net);
193
194 if ( pkg_len > ROAR_SPEEX_MAX_CC )
195  return -1;
196
197 if ( roar_vio_read(state->backend, self->cc, pkg_len) != pkg_len )
198  return -1;
199
200 speex_bits_read_from(&(self->bits), self->cc, pkg_len);
201
202 speex_decode_int(self->xcoder, &(self->bits), buf);
203
204 return 0;
205}
206
207#endif
208
209//ll
Note: See TracBrowser for help on using the repository browser.