A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 341 lines 7.5 kB view raw
1/* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken@libsdl.org 21*/ 22#include "SDL_config.h" 23 24/* This is the CD-audio control API for Simple DirectMedia Layer */ 25 26#include "SDL_cdrom.h" 27#include "SDL_syscdrom.h" 28 29#if !defined(__MACOS__) 30#define CLIP_FRAMES 10 /* Some CD-ROMs won't go all the way */ 31#endif 32 33static int SDL_cdinitted = 0; 34static SDL_CD *default_cdrom; 35 36/* The system level CD-ROM control functions */ 37struct CDcaps SDL_CDcaps = { 38 NULL, /* Name */ 39 NULL, /* Open */ 40 NULL, /* GetTOC */ 41 NULL, /* Status */ 42 NULL, /* Play */ 43 NULL, /* Pause */ 44 NULL, /* Resume */ 45 NULL, /* Stop */ 46 NULL, /* Eject */ 47 NULL, /* Close */ 48}; 49int SDL_numcds; 50 51int SDL_CDROMInit(void) 52{ 53 int retval; 54 55 SDL_numcds = 0; 56 retval = SDL_SYS_CDInit(); 57 if ( retval == 0 ) { 58 SDL_cdinitted = 1; 59 } 60 default_cdrom = NULL; 61 return(retval); 62} 63 64/* Check to see if the CD-ROM subsystem has been initialized */ 65static int CheckInit(int check_cdrom, SDL_CD **cdrom) 66{ 67 int okay; 68 69 okay = SDL_cdinitted; 70 if ( check_cdrom && (*cdrom == NULL) ) { 71 *cdrom = default_cdrom; 72 if ( *cdrom == NULL ) { 73 SDL_SetError("CD-ROM not opened"); 74 okay = 0; 75 } 76 } 77 if ( ! SDL_cdinitted ) { 78 SDL_SetError("CD-ROM subsystem not initialized"); 79 } 80 return(okay); 81} 82 83int SDL_CDNumDrives(void) 84{ 85 if ( ! CheckInit(0, NULL) ) { 86 return(-1); 87 } 88 return(SDL_numcds); 89} 90 91const char *SDL_CDName(int drive) 92{ 93 if ( ! CheckInit(0, NULL) ) { 94 return(NULL); 95 } 96 if ( drive >= SDL_numcds ) { 97 SDL_SetError("Invalid CD-ROM drive index"); 98 return(NULL); 99 } 100 if ( SDL_CDcaps.Name ) { 101 return(SDL_CDcaps.Name(drive)); 102 } else { 103 return(""); 104 } 105} 106 107SDL_CD *SDL_CDOpen(int drive) 108{ 109 struct SDL_CD *cdrom; 110 111 if ( ! CheckInit(0, NULL) ) { 112 return(NULL); 113 } 114 if ( drive >= SDL_numcds ) { 115 SDL_SetError("Invalid CD-ROM drive index"); 116 return(NULL); 117 } 118 cdrom = (SDL_CD *)SDL_malloc(sizeof(*cdrom)); 119 if ( cdrom == NULL ) { 120 SDL_OutOfMemory(); 121 return(NULL); 122 } 123 SDL_memset(cdrom, 0, sizeof(*cdrom)); 124 cdrom->id = SDL_CDcaps.Open(drive); 125 if ( cdrom->id < 0 ) { 126 SDL_free(cdrom); 127 return(NULL); 128 } 129 default_cdrom = cdrom; 130 return(cdrom); 131} 132 133CDstatus SDL_CDStatus(SDL_CD *cdrom) 134{ 135 CDstatus status; 136 int i; 137 Uint32 position; 138 139 /* Check if the CD-ROM subsystem has been initialized */ 140 if ( ! CheckInit(1, &cdrom) ) { 141 return(CD_ERROR); 142 } 143 144 /* Get the current status of the drive */ 145 cdrom->numtracks = 0; 146 cdrom->cur_track = 0; 147 cdrom->cur_frame = 0; 148 status = SDL_CDcaps.Status(cdrom, &i); 149 position = (Uint32)i; 150 cdrom->status = status; 151 152 /* Get the table of contents, if there's a CD available */ 153 if ( CD_INDRIVE(status) ) { 154 if ( SDL_CDcaps.GetTOC(cdrom) < 0 ) { 155 status = CD_ERROR; 156 } 157 /* If the drive is playing, get current play position */ 158 if ( (status == CD_PLAYING) || (status == CD_PAUSED) ) { 159 for ( i=1; cdrom->track[i].offset <= position; ++i ) { 160 /* Keep looking */; 161 } 162#ifdef DEBUG_CDROM 163 fprintf(stderr, "Current position: %d, track = %d (offset is %d)\n", 164 position, i-1, cdrom->track[i-1].offset); 165#endif 166 cdrom->cur_track = i-1; 167 position -= cdrom->track[cdrom->cur_track].offset; 168 cdrom->cur_frame = position; 169 } 170 } 171 return(status); 172} 173 174int SDL_CDPlayTracks(SDL_CD *cdrom, 175 int strack, int sframe, int ntracks, int nframes) 176{ 177 int etrack, eframe; 178 int start, length; 179 180 /* Check if the CD-ROM subsystem has been initialized */ 181 if ( ! CheckInit(1, &cdrom) ) { 182 return(CD_ERROR); 183 } 184 185 /* Determine the starting and ending tracks */ 186 if ( (strack < 0) || (strack >= cdrom->numtracks) ) { 187 SDL_SetError("Invalid starting track"); 188 return(CD_ERROR); 189 } 190 if ( ! ntracks && ! nframes ) { 191 etrack = cdrom->numtracks; 192 eframe = 0; 193 } else { 194 etrack = strack+ntracks; 195 if ( etrack == strack ) { 196 eframe = sframe + nframes; 197 } else { 198 eframe = nframes; 199 } 200 } 201 if ( etrack > cdrom->numtracks ) { 202 SDL_SetError("Invalid play length"); 203 return(CD_ERROR); 204 } 205 206 /* Skip data tracks and verify frame offsets */ 207 while ( (strack <= etrack) && 208 (cdrom->track[strack].type == SDL_DATA_TRACK) ) { 209 ++strack; 210 } 211 if ( sframe >= (int)cdrom->track[strack].length ) { 212 SDL_SetError("Invalid starting frame for track %d", strack); 213 return(CD_ERROR); 214 } 215 while ( (etrack > strack) && 216 (cdrom->track[etrack-1].type == SDL_DATA_TRACK) ) { 217 --etrack; 218 } 219 if ( eframe > (int)cdrom->track[etrack].length ) { 220 SDL_SetError("Invalid ending frame for track %d", etrack); 221 return(CD_ERROR); 222 } 223 224 /* Determine start frame and play length */ 225 start = (cdrom->track[strack].offset+sframe); 226 length = (cdrom->track[etrack].offset+eframe)-start; 227#ifdef CLIP_FRAMES 228 /* I've never seen this necessary, but xmcd does it.. */ 229 length -= CLIP_FRAMES; /* CLIP_FRAMES == 10 */ 230#endif 231 if ( length < 0 ) { 232 return(0); 233 } 234 235 /* Play! */ 236#ifdef DEBUG_CDROM 237 fprintf(stderr, "Playing %d frames at offset %d\n", length, start); 238#endif 239 return(SDL_CDcaps.Play(cdrom, start, length)); 240} 241 242int SDL_CDPlay(SDL_CD *cdrom, int sframe, int length) 243{ 244 /* Check if the CD-ROM subsystem has been initialized */ 245 if ( ! CheckInit(1, &cdrom) ) { 246 return(CD_ERROR); 247 } 248 249 return(SDL_CDcaps.Play(cdrom, sframe, length)); 250} 251 252int SDL_CDPause(SDL_CD *cdrom) 253{ 254 CDstatus status; 255 int retval; 256 257 /* Check if the CD-ROM subsystem has been initialized */ 258 if ( ! CheckInit(1, &cdrom) ) { 259 return(CD_ERROR); 260 } 261 262 status = SDL_CDcaps.Status(cdrom, NULL); 263 switch (status) { 264 case CD_PLAYING: 265 retval = SDL_CDcaps.Pause(cdrom); 266 break; 267 default: 268 retval = 0; 269 break; 270 } 271 return(retval); 272} 273 274int SDL_CDResume(SDL_CD *cdrom) 275{ 276 CDstatus status; 277 int retval; 278 279 /* Check if the CD-ROM subsystem has been initialized */ 280 if ( ! CheckInit(1, &cdrom) ) { 281 return(CD_ERROR); 282 } 283 284 status = SDL_CDcaps.Status(cdrom, NULL); 285 switch (status) { 286 case CD_PAUSED: 287 retval = SDL_CDcaps.Resume(cdrom); 288 default: 289 retval = 0; 290 break; 291 } 292 return(retval); 293} 294 295int SDL_CDStop(SDL_CD *cdrom) 296{ 297 CDstatus status; 298 int retval; 299 300 /* Check if the CD-ROM subsystem has been initialized */ 301 if ( ! CheckInit(1, &cdrom) ) { 302 return(CD_ERROR); 303 } 304 305 status = SDL_CDcaps.Status(cdrom, NULL); 306 switch (status) { 307 case CD_PLAYING: 308 case CD_PAUSED: 309 retval = SDL_CDcaps.Stop(cdrom); 310 default: 311 retval = 0; 312 break; 313 } 314 return(retval); 315} 316 317int SDL_CDEject(SDL_CD *cdrom) 318{ 319 /* Check if the CD-ROM subsystem has been initialized */ 320 if ( ! CheckInit(1, &cdrom) ) { 321 return(CD_ERROR); 322 } 323 return(SDL_CDcaps.Eject(cdrom)); 324} 325 326void SDL_CDClose(SDL_CD *cdrom) 327{ 328 /* Check if the CD-ROM subsystem has been initialized */ 329 if ( ! CheckInit(1, &cdrom) ) { 330 return; 331 } 332 SDL_CDcaps.Close(cdrom); 333 SDL_free(cdrom); 334 default_cdrom = NULL; 335} 336 337void SDL_CDROMQuit(void) 338{ 339 SDL_SYS_CDQuit(); 340 SDL_cdinitted = 0; 341}