source: roaraudio/libroar/ltm.c @ 4293:b3c0ac64bc7d

Last change on this file since 4293:b3c0ac64bc7d was 4293:b3c0ac64bc7d, checked in by phi, 14 years ago

cleanup

File size: 8.1 KB
Line 
1//ltm.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
5 *
6 *  This file is part of libroar 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 *  libroar 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, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38struct roar_ltm_result {
39 int mt;
40 int window;
41 size_t streams;
42 size_t nummt;
43 size_t structlen;
44 int64_t data[1];
45};
46
47static int roar_ltm_numbits(int f) {
48 int found = 0;
49
50 while (f) {
51  if ( f & 0x1 )
52   found++;
53
54  f >>= 1;
55 }
56
57 return found;
58}
59
60static int roar_ltm_pack_req(int mt, int window,
61                             int * streams, size_t slen,
62                             struct roar_message * mes, char ** buf,
63                             int regtype) {
64 uint16_t * data;
65 size_t i;
66
67 if ( mt == 0 || streams == NULL || slen == 0 || mes == NULL || buf == NULL ) {
68  roar_errno = ROAR_ERROR_INVAL;
69  return -1;
70 }
71
72 memset(mes, 0, sizeof(struct roar_message));
73
74 switch (regtype) {
75  case ROAR_LTM_SST_REGISTER:
76  case ROAR_LTM_SST_UNREGISTER:
77    mes->cmd = ROAR_CMD_SET_STREAM_PARA;
78   break;
79  case ROAR_LTM_SST_GET_RAW:
80    mes->cmd = ROAR_CMD_GET_STREAM_PARA;
81   break;
82  default:
83    roar_errno = ROAR_ERROR_NOTSUP;
84    return -1;
85   break;
86 }
87
88 if ( slen == 1 ) {
89  mes->stream  = *streams;
90  mes->datalen = 6 * 2;
91 } else {
92  mes->stream = -1;
93  mes->datalen = (6 + slen) * 2;
94 }
95
96 if ( mes->datalen > LIBROAR_BUFFER_MSGDATA ) {
97  roar_errno = ROAR_ERROR_NOTSUP;
98  return -1;
99 }
100
101 *buf = NULL;
102
103 data = (uint16_t*)mes->data;
104
105 data[0] = 0;
106 data[1] = ROAR_STREAM_PARA_LTM;
107 data[2] = regtype;
108 data[3] = window;
109 data[4] = 0;
110 data[5] = mt;
111
112 for (i = 0; i < slen; i++) {
113  data[6+i] = streams[i];
114 }
115
116 for (i = 0; i < (mes->datalen/2); i++) {
117  data[i] = ROAR_HOST2NET16(data[i]);
118 }
119
120 return 0;
121}
122
123static int roar_ltm_regunreg(struct roar_connection * con, int mt, int window, int * streams, size_t slen, int type) {
124 struct roar_message mes;
125 char * buf = NULL;
126 int    ret;
127
128 if ( roar_ltm_pack_req(mt, window, streams, slen, &mes, &buf, type) == -1 )
129  return -1;
130
131 ret = roar_req(con, &mes, &buf);
132
133 if ( buf != NULL )
134  free(buf);
135
136 if ( ret != -1 ) {
137  if ( mes.cmd != ROAR_CMD_OK )
138   ret = -1;
139 }
140
141 return ret;
142}
143
144int roar_ltm_register(struct roar_connection * con, int mt, int window, int * streams, size_t slen) {
145 return roar_ltm_regunreg(con, mt, window, streams, slen, ROAR_LTM_SST_REGISTER);
146}
147int roar_ltm_unregister(struct roar_connection * con, int mt, int window, int * streams, size_t slen) {
148 return roar_ltm_regunreg(con, mt, window, streams, slen, ROAR_LTM_SST_UNREGISTER);
149}
150
151
152#ifdef DEBUG
153#define HEXDUMP64(x) roar_ltm_hexdump64((x))
154static void roar_ltm_hexdump64(void * p) {
155 unsigned char * d = p;
156 ROAR_DBG("roar_ltm_hexdump64(p=%p): hex: %.2x%.2x %.2x%.2x %.2x%.2x %.2x%.2x", p, d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]);
157}
158#else
159#define HEXDUMP64(x)
160#endif
161
162struct roar_ltm_result * roar_ltm_get(struct roar_connection * con,
163                                      int mt, int window,
164                                      int * streams, size_t slen,
165                                      struct roar_ltm_result * oldresult) {
166 struct roar_ltm_result * res = NULL;
167 struct roar_message mes;
168 size_t needed_structlen = 0;
169 int64_t  * d64;
170 char * buf = NULL;
171 int    ret;
172 int    i;
173
174 if ( con == NULL )
175  return NULL;
176
177 if ( streams == NULL || slen == 0 )
178  return NULL;
179
180 if ( roar_ltm_pack_req(mt, window, streams, slen, &mes, &buf, ROAR_LTM_SST_GET_RAW) == -1 )
181  return NULL;
182
183 ret = roar_req(con, &mes, &buf);
184
185 if ( ret == -1 || mes.cmd != ROAR_CMD_OK ) {
186  if ( buf != NULL )
187   free(buf);
188  return NULL;
189 }
190
191 if ( buf == NULL ) {
192  d64 = ( int64_t*)&(mes.data);
193 } else {
194  d64 = ( int64_t*)buf;
195 }
196
197
198 for (i = 0; i < mes.datalen/8; i++) {
199  ROAR_DBG("roar_ltm_get(*): d64[i=%i]=%lli", i, (long long int)d64[i]);
200  HEXDUMP64(&(d64[i]));
201  d64[i] = ROAR_NET2HOST64(d64[i]);
202  HEXDUMP64(&(d64[i]));
203  ROAR_DBG("roar_ltm_get(*): d64[i=%i]=%lli", i, (long long int)d64[i]);
204 }
205
206 needed_structlen = sizeof(struct roar_ltm_result) + mes.datalen;
207
208 if ( oldresult != NULL ) {
209  if ( oldresult->structlen >= needed_structlen ) {
210   res = oldresult;
211   needed_structlen = oldresult->structlen;
212  } else {
213   roar_ltm_freeres(oldresult);
214  }
215 } else {
216  res = roar_mm_malloc(needed_structlen);
217 }
218
219 if ( res == NULL ) {
220  if ( buf != NULL )
221   free(buf);
222  return NULL;
223 }
224
225 memset(res, 0, needed_structlen);
226 res->structlen = needed_structlen;
227
228 res->mt      = mt;
229 res->window  = window;
230 res->streams = slen;
231 res->nummt   = roar_ltm_numbits(mt);
232
233 memcpy(res->data, d64, mes.datalen);
234
235 if ( buf != NULL )
236  free(buf);
237 return res;
238}
239
240#define _CKNULL(x) if ( (x) == NULL ) return -1
241#define _RETMEMBERCKED(x,m) _CKNULL(x); return (x)->m
242
243int roar_ltm_get_numstreams(struct roar_ltm_result * res) {
244 _RETMEMBERCKED(res, streams);
245}
246int roar_ltm_get_mt(struct roar_ltm_result * res) {
247 _RETMEMBERCKED(res, mt);
248}
249int roar_ltm_get_window(struct roar_ltm_result * res) {
250 _RETMEMBERCKED(res, window);
251}
252
253static int64_t * roar_ltm_get_streamptr(struct roar_ltm_result * res, int streamidx) {
254 int64_t * ptr;
255 int numchans;
256 int i;
257
258 ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i) = ?", res, streamidx);
259
260 if ( res == NULL || streamidx < 0 || streamidx >= res->streams )
261  return NULL;
262
263 ptr = res->data;
264
265 ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i): res->data=%p", res, streamidx, res->data);
266
267 for (i = 0; i < streamidx; i++) {
268  numchans = *ptr & 0xFFFF;
269
270  ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i): i=%i, numchans=%i", res, streamidx, i, numchans);
271
272  ptr += res->nummt * numchans;
273  ptr++;
274 }
275
276 ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i) = %p", res, streamidx, ptr);
277 return ptr;
278}
279
280int roar_ltm_get_numchans(struct roar_ltm_result * res, int streamidx) {
281 int64_t * ptr = roar_ltm_get_streamptr(res, streamidx);
282
283 if ( ptr == NULL )
284  return -1;
285
286 return *ptr & 0xFFFF;
287}
288
289int64_t roar_ltm_extract(struct roar_ltm_result * res, int mt, int streamidx, int channel) {
290 int64_t * ptr = roar_ltm_get_streamptr(res, streamidx);
291 int numchans;
292 int resmt;
293
294 ROAR_DBG("roar_ltm_extract(res=%p, mt=0x%.4x, streamidx=%i, channel=%i) = ?", res, mt, streamidx, channel);
295
296 if ( roar_ltm_numbits(mt) != 1 )
297  return -1;
298
299 ROAR_DBG("roar_ltm_extract(res=%p, mt=0x%.4x, streamidx=%i, channel=%i) = ?", res, mt, streamidx, channel);
300
301 if ( ptr == NULL )
302  return -1;
303
304 numchans = *ptr & 0xFFFF;
305
306 ROAR_DBG("roar_ltm_extract(res=%p, mt=0x%.4x, streamidx=%i, channel=%i): numchans=%i", res, mt, streamidx, channel, numchans);
307
308 if ( channel >= numchans )
309  return -1;
310
311 ptr++;
312
313 ptr += res->nummt * channel;
314
315 // now ptr points to the first mt for the given channel.
316
317 resmt = res->mt;
318
319 while (!(mt & 0x1)) {
320  if ( resmt & 0x1 )
321   ptr++;
322  mt    >>= 1;
323  resmt >>= 1;
324 }
325
326 ROAR_DBG("roar_ltm_extract(res=%p, mt=?, streamidx=%i, channel=%i): ptr=%p", res, streamidx, channel, ptr);
327 ROAR_DBG("roar_ltm_extract(res=%p, mt=?, streamidx=%i, channel=%i) = %lli", res, streamidx, channel, (long long int)*ptr);
328
329 return *ptr;
330}
331
332//ll
Note: See TracBrowser for help on using the repository browser.