source: roaraudio/libroar/stream.c @ 537:4c587d327dd8

Last change on this file since 537:4c587d327dd8 was 537:4c587d327dd8, checked in by phi, 16 years ago

added roar_str2codec() and roar_codec2str()

File size: 6.7 KB
Line 
1//stream.c:
2
3#include "libroar.h"
4
5int roar_stream_connect (struct roar_connection * con, struct roar_stream * s, int dir) {
6 struct roar_message m;
7
8 s->dir = dir;
9
10 m.cmd     = ROAR_CMD_NEW_STREAM;
11 m.stream  = -1;
12 m.pos     = 0;
13
14 roar_stream_s2m(s, &m);
15
16 if ( roar_req(con, &m, NULL) != 0 )
17  return -1;
18
19 if ( m.cmd == ROAR_CMD_OK ) {
20  s->id = m.stream;
21
22  ROAR_DBG("roar_stream_connect(*) = 0");
23  return 0;
24 }
25
26 ROAR_ERR("roar_stream_connect(*): Connecting new stream faild!");
27 ROAR_DBG("roar_stream_connect(*) = -1");
28 return -1;
29}
30
31int roar_stream_new (struct roar_stream * s, unsigned int rate,
32                     unsigned int channels, unsigned int bits, unsigned int codec) {
33
34
35 s->fh         = -1;
36 s->id         = -1;
37 s->pos        = 0;
38 s->pos_rel_id = -1;
39
40 s->dir        = ROAR_DIR_DEFAULT;
41
42 s->datalen    = 0;
43 s->offset     = 0;
44
45 s->database   = NULL;
46 s->dataoff    = NULL;
47
48 s->info.rate     = rate;
49 s->info.channels = channels;
50 s->info.bits     = bits;
51 s->info.codec    = codec;
52
53 if ( bits > ROAR_BITS_MAX )
54  return -1;
55
56 return 0;
57}
58
59int roar_stream_exec    (struct roar_connection * con, struct roar_stream * s) {
60 struct roar_message m;
61
62 m.cmd     = ROAR_CMD_EXEC_STREAM;
63 m.stream  = s->id;
64 m.datalen = 0;
65 m.pos     = 0;
66
67 if ( roar_req(con, &m, NULL) == -1 )
68  return -1;
69
70 if ( m.cmd == ROAR_CMD_OK )
71  return 0;
72 return -1;
73}
74
75int roar_stream_connect_to (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port) {
76 struct roar_message m;
77
78 if ( roar_stream_connect_to_ask(con, s, type, host, port) == -1 )
79  return -1;
80
81 if ( roar_recv_message(con, &m, NULL) == -1 )
82  return -1;
83
84 if ( m.cmd == ROAR_CMD_OK )
85  return 0;
86 return -1;
87}
88
89int roar_stream_connect_to_ask (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port) {
90 struct roar_message m;
91 int len = 0;
92
93 if ( host == NULL )
94  return -1;
95
96 ROAR_DBG("roar_stream_connect_to_ask(*): Ask the server to connect to: %s:%i", host, port);
97
98 m.cmd     = ROAR_CMD_CON_STREAM;
99 m.stream  = s->id;
100 m.pos     = 0;
101
102 m.data[0] = 0;
103 m.data[1] = type;
104 ((uint16_t*)&(m.data))[1] = ROAR_HOST2NET16(port);
105
106 len = strlen(host);
107
108 if ( len > 76 )
109  return -1;
110
111 strncpy(&(m.data[4]), host, len);
112
113 m.datalen = len + 4;
114
115 if ( roar_send_message(con, &m, NULL) == -1 )
116  return -1;
117
118 return 0;
119}
120
121int roar_stream_add_data (struct roar_connection * con, struct roar_stream * s, char * data, size_t len) {
122 struct roar_message m;
123
124 m.cmd     = ROAR_CMD_ADD_DATA;
125 m.stream  = s->id;
126 m.pos     = 0;
127 m.datalen = len;
128
129// if ( roar_req(con, &m, (void**)&data) == -1 )
130//  return -1;
131 if ( roar_send_message(con, &m, data) != 0 )
132  return -1;
133
134 if ( roar_recv_message(con, &m, NULL) == -1 )
135  return -1;
136
137 if ( m.cmd == ROAR_CMD_OK )
138  return 0;
139 return -1;
140}
141
142int roar_stream_send_data (struct roar_connection * con, struct roar_stream * s, char * data, size_t len) {
143 if ( ! s )
144  return -1;
145
146 if ( s->fh == -1 ) {
147  if ( !con )
148   return -1;
149
150  if ( roar_stream_add_data(con, s, data, len) == -1 )
151   return -1;
152
153  return len;
154 }
155
156 return write(s->fh, data, len);
157}
158
159int roar_stream_get_info (struct roar_connection * con, struct roar_stream * s, struct roar_stream_info * info) {
160 struct roar_message m;
161 uint16_t * data = (uint16_t *) m.data;
162 int i;
163
164 m.cmd     = ROAR_CMD_GET_STREAM_PARA;
165 m.stream  = s->id;
166 m.datalen = 4;
167 m.pos     = 0;
168
169 data[0] = 0; // Version and reserved
170 data[1] = 1; // stream
171
172 for (i = 0; i < m.datalen/2; i++) {
173  data[i] = ROAR_HOST2NET16(data[i]);
174 }
175
176 if ( roar_req(con, &m, NULL) == -1 )
177  return -1;
178
179 if ( m.cmd != ROAR_CMD_OK )
180  return -1;
181
182 for (i = 0; i < m.datalen/2; i++) {
183  data[i] = ROAR_NET2HOST16(data[i]);
184 }
185
186 if ( m.datalen < 3*2 )
187  return -1;
188
189 if ( data[0] != 0 || data[1] != 1 )
190  return -1;
191
192 info->block_size     = data[2];
193 info->pre_underruns  = data[3];
194 info->post_underruns = data[4];
195
196 return 0;
197}
198
199#define _ROAR_STREAM_MESSAGE_LEN ((5+1)*4)
200
201int roar_stream_s2m     (struct roar_stream * s, struct roar_message * m) {
202 uint32_t * data;
203 int i;
204
205 if ( !(s && m) )
206  return -1;
207
208 m->datalen = _ROAR_STREAM_MESSAGE_LEN;
209 data = (uint32_t*) m->data;
210
211 data[0] = s->dir;
212 data[1] = s->pos_rel_id;
213 data[2] = s->info.rate;
214 data[3] = s->info.bits;
215 data[4] = s->info.channels;
216 data[5] = s->info.codec;
217
218 for (i = 0; i < _ROAR_STREAM_MESSAGE_LEN/4; i++)
219  data[i] = ROAR_HOST2NET32(data[i]);
220
221 ROAR_DBG("roar_stream_s2m(*): s->info:");
222 roar_debug_audio_info_print(&s->info);
223
224 return 0;
225}
226int roar_stream_m2s     (struct roar_stream * s, struct roar_message * m) {
227 uint32_t * data;
228 int i;
229
230 if ( !(s && m) )
231  return -1;
232
233 if ( m->datalen != _ROAR_STREAM_MESSAGE_LEN )
234  return -1;
235
236 data = (uint32_t*) m->data;
237
238 for (i = 0; i < _ROAR_STREAM_MESSAGE_LEN/4; i++)
239  data[i] = ROAR_NET2HOST32(data[i]);
240
241 s->id            = m->stream;
242 s->dir           = data[0];
243 s->pos_rel_id    = data[1];
244 s->info.rate     = data[2];
245 s->info.bits     = data[3];
246 s->info.channels = data[4];
247 s->info.codec    = data[5];
248
249 ROAR_DBG("roar_stream_m2s(*): s->info:");
250 roar_debug_audio_info_print(&s->info);
251
252 return 0;
253}
254
255
256// codec funcs:
257
258/*
259#define roar_codec2str(x) ((x) == ROAR_CODEC_PCM_S_LE  ? "pcm_s_le"  : (x) == ROAR_CODEC_PCM_S_BE  ? "pcm_s_be"  : \
260                           (x) == ROAR_CODEC_PCM_S_PDP ? "pcm_s_pdp" : (x) == ROAR_CODEC_MIDI_FILE ? "midi_file" : \
261                           "unknown" )
262*/
263
264struct {
265 int    codec;
266 char * name;
267} _libroar_codec[] = {
268 // PCM:
269 {ROAR_CODEC_PCM_S_LE,    "pcm_s_le"   },
270 {ROAR_CODEC_PCM_S_BE,    "pcm_s_be"   },
271 {ROAR_CODEC_PCM_S_PDP,   "pcm_s_pdp"  },
272 {ROAR_CODEC_PCM_U_LE,    "pcm_u_le"   },
273 {ROAR_CODEC_PCM_U_BE,    "pcm_u_be"   },
274 {ROAR_CODEC_PCM_U_PDP,   "pcm_u_pdp"  },
275 {ROAR_CODEC_DEFAULT,     "default"    }, // alias
276 {ROAR_CODEC_DEFAULT,     "pcm"        }, // alias
277
278 // MIDI:
279 {ROAR_CODEC_MIDI_FILE,   "midi_file"  },
280
281 // XIPH:
282 {ROAR_CODEC_OGG_VORBIS,  "ogg_vorbis" },
283 {ROAR_CODEC_OGG_VORBIS,  "vorbis"     }, // alias
284 {ROAR_CODEC_FLAC,        "flac"       },
285 {ROAR_CODEC_OGG_SPEEX,   "ogg_speex"  },
286 {ROAR_CODEC_OGG_SPEEX,   "speex"      }, // alias
287 {ROAR_CODEC_OGG_FLAC,    "ogg_flac"   },
288 {ROAR_CODEC_OGG_GENERAL, "ogg_general"},
289 {ROAR_CODEC_ROAR_CELT,   "roar_celt"  },
290 {ROAR_CODEC_ROAR_SPEEX,  "roar_speex" },
291 {-1, NULL}
292};
293
294int roar_str2codec(char * codec) {
295 int i;
296 int guess = atoi(codec);
297
298 if ( guess > 0 )
299  return guess;
300
301 if ( codec == NULL || *codec == 0 )
302  return ROAR_CODEC_DEFAULT;
303
304 for (i = 0; _libroar_codec[i].codec != -1; i++)
305  if ( strcasecmp(_libroar_codec[i].name, codec) == 0 )
306   return _libroar_codec[i].codec;
307
308 return -1;
309}
310
311
312char * roar_codec2str (int codec) {
313 int i;
314
315 for (i = 0; _libroar_codec[i].codec != -1; i++)
316  if ( _libroar_codec[i].codec == codec )
317   return _libroar_codec[i].name;
318
319 return "unknown";
320}
321
322//ll
Note: See TracBrowser for help on using the repository browser.