source: roaraudio/libroarrsound/libroarrsound.c @ 3707:b1abe562c05c

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

wrote most basic functions

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