source: roaraudio/libroar/cdrom.c @ 5275:811818eb5b81

Last change on this file since 5275:811818eb5b81 was 5241:766eead707a5, checked in by phi, 12 years ago

some small updates for the CDRom API

File size: 6.2 KB
Line 
1//cdrom.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
5 *
6 *  This file is part of libroar 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 *  libroar 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 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#define ROAR_CDROM_ERROR_NORETURN(format, args...) ROAR_ERR(format, ## args); _exit(3)
39
40#if BYTE_ORDER == BIG_ENDIAN
41#define ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT "--output-raw-big-endian"
42#elif BYTE_ORDER == LITTLE_ENDIAN
43#define ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT "--output-raw-little-endian"
44#endif
45
46#ifdef ROAR_TARGET_WIN32
47#undef ROAR_HAVE_BIN_CDPARANOIA
48#endif
49
50pid_t roar_cdrom_run_cdparanoia (int cdrom, int data, int track, char * pos) {
51#if defined(ROAR_HAVE_BIN_CDPARANOIA) && defined(ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT) && defined(ROAR_HAVE_CDROM)
52 char my_pos[32] = {0};
53 pid_t pid;
54 int fh[2];
55
56 ROAR_DBG("roar_cdrom_run_cdparanoia(cdrom=%i, data=%i, track=%i, pos='%s') = ?", cdrom, data, track, pos);
57
58 if ( cdrom == -1 || data == -1 || (track == -1 && pos == NULL) || (track != -1 && pos != NULL) )
59  return -1;
60
61 if ( track != -1 ) {
62  pos = my_pos;
63  snprintf(pos, 32, "%i", track);
64 }
65
66 if ( (pid = fork()) == -1 ) {
67  return -1;
68 }
69
70 if ( pid )
71  return pid;
72
73 fh[0] = dup(cdrom);
74 fh[1] = dup(data);
75
76 if ( fh[0] == -1 || fh[1] == -1 ) {
77  ROAR_CDROM_ERROR_NORETURN("Can not dup(): %s", strerror(errno));
78 }
79
80 close(ROAR_STDIN);
81 close(ROAR_STDOUT);
82
83 // TODO: should I close some other handles?
84
85 if ( dup2(fh[0], ROAR_STDIN) == -1 || dup2(fh[1], ROAR_STDOUT) == -1 ) {
86  ROAR_CDROM_ERROR_NORETURN("Can not dup2(): %s", strerror(errno));
87 }
88
89 // now close our backups:
90 close(fh[0]);
91 close(fh[1]);
92
93 execl(ROAR_HAVE_BIN_CDPARANOIA, "cdparanoia", "--force-cdrom-device", "/dev/stdin", "-q",
94                ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT, pos, "-", NULL);
95
96 ROAR_CDROM_ERROR_NORETURN("We are still alive after exec()!, very bad!, error was: %s", strerror(errno));
97 return -1;
98#else
99#ifndef ROAR_HAVE_BIN_CDPARANOIA
100 ROAR_ERR("roar_cdrom_run_cdparanoia(*): ROAR_HAVE_BIN_CDPARANOIA not defined!");
101#endif
102#ifndef ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT
103 ROAR_ERR("roar_cdrom_run_cdparanoia(*): ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT not defined!");
104#endif
105 ROAR_ERR("roar_cdrom_run_cdparanoia(cdrom=%i, data=%i, track=%i, pos='%s') = -1 // no cdparanoia support compiled in",
106             cdrom, data, track, pos);
107 return -1;
108#endif
109}
110
111int roar_cdrom_open (struct roar_connection * con, struct roar_cdrom * cdrom, const char * device) {
112#ifdef ROAR_HAVE_CDROM
113 int flags;
114
115 if ( cdrom == NULL )
116  return -1;
117
118 memset((void*)cdrom, 0, sizeof(struct roar_cdrom));
119
120 if ( device == NULL )
121  device = roar_cdromdevice();
122
123 if ( device == NULL )
124  return -1;
125
126 strncpy(cdrom->device, device, ROAR_CDROM_MAX_DEVLEN);
127
128 cdrom->con        = con; // we do not care here if it is set or not as we can operate in local only mode
129
130 cdrom->stream     = -1;
131 cdrom->play_local =  1;
132 cdrom->player     = -1;
133
134 if ( (cdrom->fh = open(cdrom->device, O_RDONLY, 0644)) == -1 )
135  return -1;
136
137#ifndef ROAR_TARGET_WIN32
138 if ( (flags = fcntl(cdrom->fh, F_GETFL, 0)) == -1 ) {
139  close(cdrom->fh);
140  cdrom->fh  = -1;
141  return -1;
142 }
143
144 flags |= FD_CLOEXEC;
145
146 if ( fcntl(cdrom->fh, F_SETFL, flags) == -1 ) {
147  close(cdrom->fh);
148  cdrom->fh = -1;
149  return -1;
150 }
151#endif
152
153 return 0;
154#else
155 return -1;
156#endif
157}
158
159int roar_cdrom_close(struct roar_cdrom * cdrom) {
160#ifdef ROAR_HAVE_CDROM
161 if ( cdrom == NULL )
162  return -1;
163
164 roar_cdrom_stop(cdrom); // stop on close
165
166 if ( cdrom->fh != -1 )
167  close(cdrom->fh);
168
169 memset((void*)cdrom, 0, sizeof(struct roar_cdrom));
170
171 return 0;
172#else
173 return -1;
174#endif
175}
176
177int roar_cdrom_stop (struct roar_cdrom * cdrom) {
178#ifdef ROAR_HAVE_CDROM
179 int ret;
180
181 if ( cdrom == NULL )
182  return -1;
183
184 if ( cdrom->con == NULL )
185  return -1;
186
187 if ( cdrom->stream == -1 )
188  return -1;
189
190 if ( (ret = roar_kick(cdrom->con, ROAR_OT_STREAM, cdrom->stream)) == -1 ) {
191  return -1;
192 }
193
194#ifndef ROAR_TARGET_WIN32
195 if ( cdrom->player != -1 )
196  kill(cdrom->player, SIGINT);
197#else
198 if ( cdrom->player != -1 ) {
199  ROAR_ERR("roar_cdrom_stop(*): Can not kill player with pid %i, not supported on win32", cdrom->player);
200 }
201#endif
202
203 cdrom->player = -1;
204 cdrom->stream = -1;
205
206 return ret;
207#else
208 return -1;
209#endif
210}
211
212int roar_cdrom_play (struct roar_cdrom * cdrom, int track) {
213#ifdef ROAR_HAVE_CDROM
214 struct roar_vio_calls vio;
215 struct roar_stream stream[1];
216 int stream_fh;
217
218 if ( cdrom == NULL )
219  return -1;
220
221 if ( cdrom->con == NULL )
222  return -1;
223
224 if ( cdrom->stream != -1 ) {
225  if ( roar_cdrom_stop(cdrom) == -1 )
226   return -1;
227 }
228
229 if ( cdrom->play_local ) {
230
231  if ( roar_vio_simple_new_stream_obj(&vio, cdrom->con, stream, ROAR_CDROM_STREAMINFO, ROAR_DIR_PLAY) == -1 ) {
232   return -1;
233  }
234
235  if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_WRITE_FH, &stream_fh) == -1 ) {
236   roar_vio_close(&vio);
237   return -1;
238  }
239
240  if ( (cdrom->player = roar_cdrom_run_cdparanoia(cdrom->fh, stream_fh, track, NULL)) != -1 ) {
241   cdrom->stream = stream->id;
242   return 0;
243  }
244
245  roar_vio_close(&vio);
246
247  return -1;
248 } else {
249  // no support for remote playback yet
250  return -1;
251 }
252#else
253 return -1;
254#endif
255}
256
257//ll
Note: See TracBrowser for help on using the repository browser.