source: roaraudio/roard/driver_shout.c @ 5961:06e7fd9e4c25

Last change on this file since 5961:06e7fd9e4c25 was 5961:06e7fd9e4c25, checked in by phi, 10 years ago

Updates of copyright and license headers

File size: 6.2 KB
Line 
1//driver_shout.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014
5 *
6 *  This file is part of roard 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 *  RoarAudio 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 */
25
26#include "roard.h"
27#ifdef ROAR_HAVE_LIBSHOUT
28
29struct driver_shout {
30 shout_t * shout;
31 int blocking;
32};
33
34static int _driver_shout_usage_counter = 0;
35
36int     driver_shout_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) {
37 struct driver_shout * self = NULL;
38 const char * s_server = NULL;
39 const char * s_mount  = NULL;
40 const char * s_user   = NULL;
41 const char * s_pw     = NULL;
42 int    s_port   = -1;
43 const char * s_desc   = NULL;
44 const char * s_genre  = NULL;
45 const char * s_name   = NULL;
46 const char * s_url    = NULL;
47 int    s_public = 0;
48 char * a;
49 shout_t * shout;
50
51 switch (info->codec) {
52  case ROAR_CODEC_DEFAULT:
53    info->codec = ROAR_CODEC_OGG_VORBIS;
54   break;
55  case ROAR_CODEC_OGG_VORBIS:
56  case ROAR_CODEC_OGG_SPEEX:
57  case ROAR_CODEC_OGG_FLAC:
58  case ROAR_CODEC_OGG_GENERAL:
59    // ok, no errors here
60   break;
61  default:
62    ROAR_ERR("This driver only supports Ogg/* (most common is Ogg/Vorbis), current codec is %s", roar_codec2str(info->codec));
63    return -1;
64   break;
65 }
66
67 if ( device != NULL ) {
68  // device sould be an URL in this form:
69  // [http[s]://][user[:pw]@]host[:port][/mp.ogg]
70
71  if ( (a = strstr(device, "://")) != NULL ) {
72   *a = 0;
73   if ( strcmp(device, "http") ) {
74    return -1;
75   }
76   device = a + 3;
77  }
78
79  // [user[:pw]@]host[:port][/mp.ogg]
80
81  if ( (a = strstr(device, "@")) != NULL ) {
82   *a = 0;
83   s_user = device;
84   device = a + 1;
85  }
86
87  if ( s_user != NULL ) {
88   if ( (a = strstr(s_user, ":")) != NULL ) {
89    *a = 0;
90    s_pw = a+1;
91   }
92  }
93
94  if ( s_user != NULL && ! *s_user )
95   s_user = NULL;
96
97  if ( s_pw != NULL && ! *s_pw )
98   s_pw = NULL;
99
100  // host[:port][/mp.ogg]
101
102  if ( (a = strstr(device, "/")) != NULL ) {
103   *a = 0;
104   s_server = device;
105   device = a + 1;
106  } else {
107   s_server  = device;
108   device   += strlen(device);
109  }
110
111  if ( (a = strstr(s_server, ":")) != NULL ) {
112   *a = 0;
113   s_port = atoi(a+1);
114  }
115
116  if ( ! *s_server )
117   s_server = NULL;
118
119  // [/mp.ogg]
120
121  if ( *device ) {
122   s_mount = device;
123  }
124 }
125
126 ROAR_DBG("driver_shout_open_vio(*): user='%s', pw='%s', server='%s', port=%i, mount='%s'",
127                   s_user, s_pw, s_server, s_port, s_mount);
128
129 if ( s_server == NULL )
130  s_server = "localhost";
131
132 if ( s_mount == NULL )
133  s_mount  = "/roar.ogg";
134
135 if ( s_pw == NULL )
136  s_pw     = "hackme";
137
138 if ( s_user == NULL )
139  s_user     = "source";
140
141 if ( s_port == -1 )
142  s_port   = 8000;
143
144 if ( _driver_shout_usage_counter++ == 0 )
145  shout_init();
146
147 if (!(shout = shout_new())) {
148  ROAR_ERR("Can not clreate shout object");
149  return 1;
150 }
151
152 if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) {
153  ROAR_ERR("Error setting hostname: %s", shout_get_error(shout));
154  return 1;
155 }
156
157 if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
158  ROAR_ERR("Error setting protocol: %s", shout_get_error(shout));
159  return 1;
160 }
161
162 if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) {
163  ROAR_ERR("Error setting port: %s", shout_get_error(shout));
164  return 1;
165 }
166
167 if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) {
168  ROAR_ERR("Error setting password: %s", shout_get_error(shout));
169  return 1;
170 }
171
172 if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) {
173  ROAR_ERR("Error setting mount: %s", shout_get_error(shout));
174  return 1;
175 }
176
177 if (shout_set_user(shout, s_user) != SHOUTERR_SUCCESS) {
178  ROAR_ERR("Error setting user: %s", shout_get_error(shout));
179  return 1;
180 }
181
182 if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) {
183  ROAR_ERR("Error setting format: %s", shout_get_error(shout));
184  return 1;
185 }
186
187 shout_set_public(shout, s_public);
188
189 if (s_desc  != NULL)
190  shout_set_description(shout, s_desc);
191
192 if (s_genre != NULL)
193  shout_set_genre(shout, s_genre);
194
195 if (s_name  != NULL)
196  shout_set_name(shout, s_name);
197
198 if (s_url   != NULL)
199  shout_set_url(shout, s_url);
200
201 if (shout_open(shout) != SHOUTERR_SUCCESS) {
202  ROAR_ERR("Can not open connection via libshout!");
203  return -1;
204 }
205
206 self = roar_mm_malloc(sizeof(struct driver_shout));
207 if ( self == NULL ) {
208  shout_close(shout);
209  return -1;
210 }
211
212 memset(self, 0, sizeof(struct driver_shout));
213 self->shout = shout;
214 self->blocking = ROAR_SOCKET_BLOCK;
215
216 memset(inst, 0, sizeof(struct roar_vio_calls));
217 inst->flags    = ROAR_VIO_FLAGS_NONE;
218 inst->refc     = 1;
219 inst->inst     = (void*)self;
220 inst->write    = driver_shout_write;
221 inst->close    = driver_shout_close;
222 inst->ctl      = driver_dummy_ctl;
223
224 return 0;
225}
226
227int     driver_shout_close(struct roar_vio_calls * vio) {
228 struct driver_shout * self = vio->inst;
229
230 shout_close(self->shout);
231 roar_mm_free(self);
232
233 if ( _driver_shout_usage_counter-- == 1 )
234  shout_shutdown();
235
236 return 0;
237}
238
239ssize_t driver_shout_write(struct roar_vio_calls * vio, void *buf, size_t count) {
240 struct driver_shout * self = vio->inst;
241
242 if (shout_send(self->shout, (unsigned char*)buf, count) != SHOUTERR_SUCCESS)
243  return -1;
244
245 if ( self->blocking == ROAR_SOCKET_BLOCK )
246  shout_sync(self->shout);
247
248 return count;
249}
250
251int     driver_shout_ctl     (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) {
252 struct driver_shout * self = vio->inst;
253
254 switch (cmd) {
255  case ROAR_VIO_CTL_NONBLOCK:
256    self->blocking = *(const int*)data;
257    return 0;
258   break;
259  default:
260    roar_err_set(ROAR_ERROR_BADRQC);
261    return -1;
262   break;
263 }
264}
265
266#endif
267//ll
Note: See TracBrowser for help on using the repository browser.