source: roaraudio/libroarrsound/libroarrsound.c @ 3727:9905711fb84a

Last change on this file since 3727:9905711fb84a was 3727:9905711fb84a, checked in by phi, 14 years ago

fixed bug with rsd_set_param() RSD_FORMAT returning -1 in case of sucess

File size: 7.8 KB
Line 
1//libroarrsound.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
5 *  The code (may) include prototypes and comments (and maybe
6 *  other code fragements) from RSound.
7 *  They are copyrighted by Hans-Kristian 'maister' Arntzen.
8 *
9 *  This file is part of libroarrsound a part of RoarAudio,
10 *  a cross-platform sound system for both, home and professional use.
11 *  See README for details.
12 *
13 *  This file is free software; you can redistribute it and/or modify
14 *  it under the terms of the GNU General Public License version 3
15 *  as published by the Free Software Foundation.
16 *
17 *  RoarAudio is distributed in the hope that it will be useful,
18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 *  GNU General Public License for more details.
21 *
22 *  You should have received a copy of the GNU General Public License
23 *  along with this software; see the file COPYING.  If not, write to
24 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *  NOTE for everyone want's to change something and send patches:
27 *  read README and HACKING! There a addition information on
28 *  the license of this document you need to read before you send
29 *  any patches.
30 */
31
32#include "libroarrsound.h"
33
34static size_t libroarrsound_fmt2fs (enum format format) {
35 switch (format) {
36  case RSD_S16_LE:
37  case RSD_S16_BE:
38  case RSD_U16_LE:
39  case RSD_U16_BE:
40    return 16;
41   break;
42  case RSD_U8:
43  case RSD_S8:
44    return 8;
45   break;
46  default:
47    return 0;
48   break;
49 }
50}
51
52int rsd_init (rsound_t **rd) {
53 struct libroarrsound * self;
54
55 if ( rd == NULL )
56  return -1;
57
58 self = roar_mm_malloc(sizeof(struct libroarrsound));
59
60 if ( self == NULL )
61  return -1;
62
63 memset(self, 0, sizeof(struct libroarrsound));
64
65 *rd = (rsound_t*)self;
66
67 self->rsound.conn.socket     = -1;
68 self->rsound.conn.ctl_socket = -1;
69 self->rsound.channels        = ROAR_CHANNELS_DEFAULT;
70 self->rsound.rate            = ROAR_RATE_DEFAULT;
71 self->rsound.format          = RSD_S16_LE;
72
73 return 0;
74}
75
76/* Frees an rsound_t struct. */
77int rsd_free (rsound_t *rd) {
78 struct libroarrsound * self = (struct libroarrsound *)rd;
79 int ret = 0;
80
81 if ( self == NULL )
82  return -1;
83
84 if ( self->flags & LIBROARRSOUND_FLAGS_CONNECTED )
85  if ( roar_disconnect(&(self->con)) == -1 )
86   ret = -1;
87
88 if ( self->flags & LIBROARRSOUND_FLAGS_STREAMING )
89  if ( roar_vio_close(&(self->vio)) == -1 )
90   ret = -1;
91
92 if ( self->rsound.host != NULL )
93  roar_mm_free(self->rsound.host);
94
95 if ( self->rsound.port != NULL )
96  roar_mm_free(self->rsound.port);
97
98 roar_mm_free(self);
99
100 return ret;
101}
102
103int rsd_set_param (rsound_t *rd, int option, void* param) {
104 struct libroarrsound * self = (struct libroarrsound *)rd;
105
106 ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = ?", rd, option, param);
107
108 if ( self == NULL || param == NULL )
109  return -1;
110
111 switch ((enum settings)option) {
112  // connection settings:
113  case RSD_HOST:
114    self->rsound.host = roar_mm_strdup(param);
115   break;
116  case RSD_PORT:
117    self->rsound.port = roar_mm_strdup(param);
118   break;
119  // stream settings:
120  case RSD_SAMPLERATE:
121    self->rsound.rate = *(int*)param;
122   break;
123  case RSD_CHANNELS:
124    self->rsound.channels = *(int*)param;
125   break;
126  case RSD_FORMAT:
127    self->rsound.format = *(int*)param;
128    self->rsound.framesize = libroarrsound_fmt2fs(self->rsound.format);
129   break;
130  default:
131/*
132   RSD_BUFSIZE,
133   RSD_LATENCY,
134*/
135     ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = -1", rd, option, param);
136    return -1;
137   break;
138 }
139
140 ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = 0", rd, option, param);
141 return 0;
142}
143
144static int libroarrsound_connect (struct libroarrsound * self) {
145 char * host;
146
147 if ( self->flags & LIBROARRSOUND_FLAGS_CONNECTED )
148  return 0;
149
150 host = self->rsound.host;
151
152 if ( host == NULL )
153  host = getenv("RSD_SERVER");
154
155 // FIXME: we currently ignore the port. :(
156
157 if ( roar_simple_connect(&(self->con), host, "libroarrsound client") == -1 )
158  return -1;
159
160 self->flags |= LIBROARRSOUND_FLAGS_CONNECTED;
161
162 return 0;
163}
164
165/* Establishes connection to server. Might fail if connection can't be established or that one of
166   the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set
167   with rsd_set_param(), and before rsd_write(). */
168int rsd_start (rsound_t *rd) {
169 struct libroarrsound * self = (struct libroarrsound *)rd;
170 int bits  = 16;
171 int codec;
172
173 if ( self == NULL )
174  return -1;
175
176 if ( self->flags & LIBROARRSOUND_FLAGS_STREAMING )
177  return 0;
178
179 if ( !(self->flags & LIBROARRSOUND_FLAGS_CONNECTED) ) {
180  if ( libroarrsound_connect(self) == -1 )
181   return -1;
182 }
183
184 switch (self->rsound.format) {
185  case RSD_S16_LE:
186    codec = ROAR_CODEC_PCM_S_LE;
187   break;
188  case RSD_S16_BE:
189    codec = ROAR_CODEC_PCM_S_BE;
190   break;
191  case RSD_U16_LE:
192    codec = ROAR_CODEC_PCM_U_LE;
193   break;
194  case RSD_U16_BE:
195    codec = ROAR_CODEC_PCM_U_BE;
196   break;
197  case RSD_S8:
198    codec = ROAR_CODEC_PCM_S;
199    bits  = 8;
200   break;
201  case RSD_U8:
202    codec = ROAR_CODEC_PCM_U;
203    bits  = 8;
204   break;
205  default:
206    return -1;
207   break;
208 }
209
210 if ( roar_vio_simple_new_stream_obj(&(self->vio), &(self->con), &(self->stream),
211                                     self->rsound.rate, self->rsound.channels, bits, codec, ROAR_DIR_PLAY) == -1 )
212  return -1;
213
214 self->flags |= LIBROARRSOUND_FLAGS_STREAMING;
215
216 return 0;
217}
218
219/* Disconnects from server. All audio data still in network buffer and other buffers will be dropped.
220   To continue playing, you will need to rsd_start() again. */
221int rsd_stop (rsound_t *rd) {
222 struct libroarrsound * self = (struct libroarrsound *)rd;
223 int ret;
224
225 if ( self == NULL )
226  return -1;
227
228 if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) )
229  return 0;
230
231 ret = roar_vio_close(&(self->vio));
232
233 self->flags -= LIBROARRSOUND_FLAGS_STREAMING;
234
235 return ret;
236}
237
238/* Writes from buf to the internal buffer. Might fail if no connection is established,
239   or there was an unexpected error. This function will block until all data has
240   been written to the buffer. This function will return the number of bytes written to the buffer,
241   or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */
242size_t rsd_write (rsound_t *rd, const char* buf, size_t size) {
243 struct libroarrsound * self = (struct libroarrsound *)rd;
244 ssize_t ret;
245
246 if ( self == NULL )
247  return -1;
248
249 if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) )
250  return 0;
251
252 ret = roar_vio_write(&(self->vio), (void*)buf, size);
253
254 if ( ret == -1 )
255  return 0;
256
257 return ret;
258}
259
260/* Gets the position of the buffer pointer.
261   Not really interesting for normal applications.
262   Might be useful for implementing rsound on top of other blocking APIs. */
263size_t rsd_pointer (rsound_t *rd);
264
265/* Aquires how much data can be written to the buffer without blocking */
266size_t rsd_get_avail (rsound_t *rd);
267
268/* Aquires the latency at the moment for the audio stream. It is measured in bytes. Useful for syncing video and audio. */
269size_t rsd_delay (rsound_t *rd) {
270 (void)rd;
271 return 0; // TODO: FIXME: write some code to read pos from server.
272}
273
274/* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY
275   Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set
276   with RSD_LATENCY, this function will do nothing. */
277void rsd_delay_wait(rsound_t *rd);
278
279
280/* Pauses or unpauses a stream. pause -> enable = 1
281   This function essentially calls on start() and stop(). This behavior might be changed later. */
282int rsd_pause (rsound_t *rd, int enable) {
283 struct libroarrsound * self = (struct libroarrsound *)rd;
284
285 if ( self == NULL )
286  return -1;
287
288 if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) )
289  return -1;
290
291 return roar_stream_set_flags(&(self->con), &(self->stream), ROAR_FLAG_PAUSE, enable ? ROAR_SET_FLAG : ROAR_RESET_FLAG);
292}
293
294//ll
Note: See TracBrowser for help on using the repository browser.