source: roaraudio/libroarrsound/libroarrsound.c @ 3711:1a09dfb497d6

Last change on this file since 3711:1a09dfb497d6 was 3711:1a09dfb497d6, checked in by phi, 14 years ago

honor $RSD_SERVER

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