source: roaraudio/libroarrsound/libroarrsound.c @ 3744:d95dada255ec

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

updated prototypes, again...

File size: 8.0 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 rsd_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, enum rsd_settings 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 (option) {
112  // connection settings:
113  case RSD_HOST:
114    if ( self->rsound.host != NULL )
115     roar_mm_free(self->rsound.host);
116
117    self->rsound.host = roar_mm_strdup(param);
118   break;
119  case RSD_PORT:
120    if ( self->rsound.port != NULL )
121     roar_mm_free(self->rsound.port);
122
123    self->rsound.port = roar_mm_strdup(param);
124   break;
125  // stream settings:
126  case RSD_SAMPLERATE:
127    self->rsound.rate = *(int*)param;
128   break;
129  case RSD_CHANNELS:
130    self->rsound.channels = *(int*)param;
131   break;
132  case RSD_FORMAT:
133    self->rsound.format = *(int*)param;
134    self->rsound.framesize = libroarrsound_fmt2fs(self->rsound.format);
135   break;
136  default:
137/*
138   RSD_BUFSIZE,
139   RSD_LATENCY,
140*/
141     ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = -1", rd, option, param);
142    return -1;
143   break;
144 }
145
146 ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = 0", rd, option, param);
147 return 0;
148}
149
150static int libroarrsound_connect (struct libroarrsound * self) {
151 char * host;
152
153 if ( self->flags & LIBROARRSOUND_FLAGS_CONNECTED )
154  return 0;
155
156 host = self->rsound.host;
157
158 if ( host == NULL )
159  host = getenv("RSD_SERVER");
160
161 // FIXME: we currently ignore the port. :(
162
163 if ( roar_simple_connect(&(self->con), host, "libroarrsound client") == -1 )
164  return -1;
165
166 self->flags |= LIBROARRSOUND_FLAGS_CONNECTED;
167
168 return 0;
169}
170
171/* Establishes connection to server. Might fail if connection can't be established or that one of
172   the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set
173   with rsd_set_param(), and before rsd_write(). */
174int rsd_start (rsound_t *rd) {
175 struct libroarrsound * self = (struct libroarrsound *)rd;
176 int bits  = 16;
177 int codec;
178
179 if ( self == NULL )
180  return -1;
181
182 if ( self->flags & LIBROARRSOUND_FLAGS_STREAMING )
183  return 0;
184
185 if ( !(self->flags & LIBROARRSOUND_FLAGS_CONNECTED) ) {
186  if ( libroarrsound_connect(self) == -1 )
187   return -1;
188 }
189
190 switch (self->rsound.format) {
191  case RSD_S16_LE:
192    codec = ROAR_CODEC_PCM_S_LE;
193   break;
194  case RSD_S16_BE:
195    codec = ROAR_CODEC_PCM_S_BE;
196   break;
197  case RSD_U16_LE:
198    codec = ROAR_CODEC_PCM_U_LE;
199   break;
200  case RSD_U16_BE:
201    codec = ROAR_CODEC_PCM_U_BE;
202   break;
203  case RSD_S8:
204    codec = ROAR_CODEC_PCM_S;
205    bits  = 8;
206   break;
207  case RSD_U8:
208    codec = ROAR_CODEC_PCM_U;
209    bits  = 8;
210   break;
211  default:
212    return -1;
213   break;
214 }
215
216 if ( roar_vio_simple_new_stream_obj(&(self->vio), &(self->con), &(self->stream),
217                                     self->rsound.rate, self->rsound.channels, bits, codec, ROAR_DIR_PLAY) == -1 )
218  return -1;
219
220 self->flags |= LIBROARRSOUND_FLAGS_STREAMING;
221
222 return 0;
223}
224
225/* Disconnects from server. All audio data still in network buffer and other buffers will be dropped.
226   To continue playing, you will need to rsd_start() again. */
227int rsd_stop (rsound_t *rd) {
228 struct libroarrsound * self = (struct libroarrsound *)rd;
229 int ret;
230
231 if ( self == NULL )
232  return -1;
233
234 if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) )
235  return 0;
236
237 ret = roar_vio_close(&(self->vio));
238
239 self->flags -= LIBROARRSOUND_FLAGS_STREAMING;
240
241 return ret;
242}
243
244/* Writes from buf to the internal buffer. Might fail if no connection is established,
245   or there was an unexpected error. This function will block until all data has
246   been written to the buffer. This function will return the number of bytes written to the buffer,
247   or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */
248size_t rsd_write (rsound_t *rd, const char* buf, size_t size) {
249 struct libroarrsound * self = (struct libroarrsound *)rd;
250 ssize_t ret;
251
252 if ( self == NULL )
253  return -1;
254
255 if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) )
256  return 0;
257
258 ret = roar_vio_write(&(self->vio), (void*)buf, size);
259
260 if ( ret == -1 )
261  return 0;
262
263 return ret;
264}
265
266/* Gets the position of the buffer pointer.
267   Not really interesting for normal applications.
268   Might be useful for implementing rsound on top of other blocking APIs. */
269size_t rsd_pointer (rsound_t *rd);
270
271/* Aquires how much data can be written to the buffer without blocking */
272size_t rsd_get_avail (rsound_t *rd);
273
274/* Aquires the latency at the moment for the audio stream. It is measured in bytes. Useful for syncing video and audio. */
275size_t rsd_delay (rsound_t *rd) {
276 (void)rd;
277 return 0; // TODO: FIXME: write some code to read pos from server.
278}
279
280/* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY
281   Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set
282   with RSD_LATENCY, this function will do nothing. */
283void rsd_delay_wait(rsound_t *rd);
284
285
286/* Pauses or unpauses a stream. pause -> enable = 1
287   This function essentially calls on start() and stop(). This behavior might be changed later. */
288int rsd_pause (rsound_t *rd, int enable) {
289 struct libroarrsound * self = (struct libroarrsound *)rd;
290
291 if ( self == NULL )
292  return -1;
293
294 if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) )
295  return -1;
296
297 return roar_stream_set_flags(&(self->con), &(self->stream), ROAR_FLAG_PAUSE, enable ? ROAR_SET_FLAG : ROAR_RESET_FLAG);
298}
299
300//ll
Note: See TracBrowser for help on using the repository browser.