├── COPYING ├── libs ├── libcommon │ ├── charset.c │ ├── charset.h │ ├── fileutils.c │ ├── fileutils.h │ ├── list.h │ ├── log.c │ ├── log.h │ ├── logging.c │ ├── logging.h │ ├── pb.h │ ├── pb_decode.c │ ├── pb_decode.h │ ├── pb_encode.c │ ├── pb_encode.h │ ├── socket.c │ ├── socket.h │ ├── sys │ │ ├── atomic.h │ │ ├── io_buffer.h │ │ ├── isoself.h │ │ └── storage.h │ ├── timeout.c │ ├── timeout.h │ ├── usocket.c │ ├── usocket.h │ ├── utils.c │ ├── utils.h │ ├── wsocket.c │ └── wsocket.h ├── libdstdec │ ├── buffer_pool.c │ ├── buffer_pool.h │ ├── ccp_calc.c │ ├── ccp_calc.h │ ├── conststr.h │ ├── dst_ac.c │ ├── dst_ac.h │ ├── dst_data.c │ ├── dst_data.h │ ├── dst_decoder.c │ ├── dst_decoder.h │ ├── dst_fram.c │ ├── dst_fram.h │ ├── dst_init.c │ ├── dst_init.h │ ├── types.h │ ├── unpack_dst.c │ ├── unpack_dst.h │ ├── yarn.c │ └── yarn.h ├── libid3 │ ├── genre.dat │ ├── id3.c │ ├── id3.h │ ├── id3_frame.c │ ├── id3_frame_content.c │ ├── id3_frame_text.c │ ├── id3_frame_url.c │ ├── id3_header.h │ ├── id3_tag.c │ └── unicode.c └── libsacd │ ├── cuesheet.c │ ├── cuesheet.h │ ├── dsdiff.c │ ├── dsdiff.h │ ├── dsf.c │ ├── dsf.h │ ├── dst_decoder_ps3.c │ ├── dst_decoder_ps3.h │ ├── endianess.h │ ├── ioctl.c │ ├── ioctl.h │ ├── iso_writer.c │ ├── sac_accessor.c │ ├── sac_accessor.h │ ├── sacd_input.c │ ├── sacd_input.h │ ├── sacd_pb_stream.c │ ├── sacd_pb_stream.h │ ├── sacd_read_internal.h │ ├── sacd_reader.c │ ├── sacd_reader.h │ ├── sacd_ripper.pb.c │ ├── sacd_ripper.pb.h │ ├── sacd_ripper.proto │ ├── scarletbook.c │ ├── scarletbook.h │ ├── scarletbook_helpers.c │ ├── scarletbook_helpers.h │ ├── scarletbook_id3.c │ ├── scarletbook_id3.h │ ├── scarletbook_output.c │ ├── scarletbook_output.h │ ├── scarletbook_print.c │ ├── scarletbook_print.h │ ├── scarletbook_read.c │ ├── scarletbook_read.h │ └── version.h ├── readme.rst ├── todo └── tools └── sacd_extract ├── CMakeLists.txt ├── changelog ├── getopt.c ├── getopt.h ├── getopt1.c └── main.c /libs/libcommon/charset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1999-2001 Haavard Kvaalen 3 | * 4 | * Licensed under GNU LGPL version 2. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifdef HAVE_CODESET 15 | #include 16 | #endif 17 | 18 | #include "charset.h" 19 | #include "logging.h" 20 | 21 | char* charset_get_current(void) 22 | { 23 | char *charset = getenv("CHARSET"); 24 | 25 | #ifdef HAVE_CODESET 26 | if (!charset) 27 | charset = nl_langinfo(CODESET); 28 | #endif 29 | if (!charset) 30 | charset = "ISO-8859-1"; 31 | 32 | return charset; 33 | } 34 | 35 | char* charset_convert(const char *string, size_t insize, const char *from, const char *to) 36 | { 37 | size_t outleft, outsize; 38 | iconv_t cd; 39 | char *out, *outptr; 40 | const char *input = string; 41 | 42 | if (!string) 43 | return NULL; 44 | 45 | if (!from) 46 | from = charset_get_current(); 47 | if (!to) 48 | to = charset_get_current(); 49 | 50 | if ((cd = iconv_open(to, from)) == (iconv_t)-1) 51 | { 52 | LOG(lm_main, LOG_ERROR, ("convert_string(): Conversion not supported. " 53 | "Charsets: %s -> %s", from, to)); 54 | return strdup(string); 55 | } 56 | 57 | /* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */ 58 | /* + 4 for nul in case len == 1 */ 59 | outsize = ((insize + 3) & ~3) + 4; 60 | out = malloc(outsize); 61 | outleft = outsize - 4; 62 | outptr = out; 63 | 64 | retry: 65 | #ifdef __lv2ppu__ 66 | if (iconv(cd, (const char **) &input, &insize, &outptr, &outleft) == (size_t) -1) 67 | #else 68 | if (iconv(cd, &input, &insize, &outptr, &outleft) == (size_t) -1) 69 | #endif 70 | { 71 | int used; 72 | switch (errno) 73 | { 74 | case E2BIG: 75 | used = outptr - out; 76 | outsize = ((outsize - 4) * 2) + 4; 77 | out = realloc(out, outsize); 78 | outptr = out + used; 79 | outleft = outsize - 4 - used; 80 | goto retry; 81 | case EINVAL: 82 | break; 83 | case EILSEQ: 84 | /* Invalid sequence, try to get the 85 | rest of the string */ 86 | input++; 87 | insize--; 88 | goto retry; 89 | default: 90 | LOG(lm_main, LOG_ERROR, ("convert_string(): Conversion failed. " 91 | "Inputstring: %s; Error: %s", 92 | string, strerror(errno))); 93 | break; 94 | } 95 | } 96 | memset(outptr, 0, 4); 97 | 98 | iconv_close(cd); 99 | return out; 100 | } 101 | 102 | char* charset_from_utf8(const char *string) 103 | { 104 | if (!string) 105 | return NULL; 106 | return charset_convert(string, strlen(string), "UTF-8", NULL); 107 | } 108 | 109 | char* charset_to_utf8(const char *string) 110 | { 111 | if (!string) 112 | return NULL; 113 | return charset_convert(string, strlen(string), NULL, "UTF-8"); 114 | } 115 | -------------------------------------------------------------------------------- /libs/libcommon/charset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1999-2001 Haavard Kvaalen 3 | * 4 | * Licensed under GNU LGPL version 2. 5 | * 6 | */ 7 | 8 | #ifndef CHARSET_H_INCLUDED 9 | #define CHARSET_H_INCLUDED 10 | 11 | char* charset_get_current(void); 12 | char* charset_convert(const char *string, size_t insize, const char *from, const char *to); 13 | char* charset_to_utf8(const char *string); 14 | char* charset_from_utf8(const char *string); 15 | 16 | #endif /* CHARSET_H_INCLUDED */ 17 | -------------------------------------------------------------------------------- /libs/libcommon/fileutils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __FILEUTILS_H__ 23 | #define __FILEUTILS_H__ 24 | 25 | #include 26 | 27 | #if defined(_WIN32) && !defined(__MINGW32__) 28 | typedef int mode_t; 29 | #else 30 | #include 31 | #endif 32 | 33 | // substitute various items into a formatted string (similar to printf) 34 | // 35 | // format - the format of the filename 36 | // tracknum - gets substituted for %N in format 37 | // year - gets substituted for %Y in format 38 | // artist - gets substituted for %A in format 39 | // album - gets substituted for %L in format 40 | // title - gets substituted for %T in format 41 | // 42 | // NOTE: caller must free the returned string! 43 | char * parse_format(const char * format, int tracknum, const char * year, const char * artist, const char * album, const char * title); 44 | 45 | // construct a filename from various parts 46 | // 47 | // path - the path the file is placed in (don't include a trailing '/') 48 | // dir - the parent directory of the file (don't include a trailing '/') 49 | // file - the filename 50 | // extension - the suffix of a file (don't include a leading '.') 51 | // 52 | // NOTE: caller must free the returned string! 53 | // NOTE: any of the parameters may be NULL to be omitted 54 | char * make_filename(const char * path, const char * dir, const char * file, const char * extension); 55 | 56 | int recursive_mkdir(char* pathAndName, mode_t mode); 57 | 58 | int recursive_parent_mkdir(char* pathAndName, mode_t mode); 59 | 60 | void sanitize_filename(char *f); 61 | 62 | void sanitize_filepath(char *f); 63 | 64 | void get_unique_filename(char **file, const char *ext); 65 | 66 | char * get_unique_path(char *dir, char *file, const char *ext); 67 | 68 | void get_unique_dir(char *device, char **dir); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /libs/libcommon/log.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is the Netscape Portable Runtime (NSPR). 15 | * 16 | * The Initial Developer of the Original Code is 17 | * Netscape Communications Corporation. 18 | * Portions created by the Initial Developer are Copyright (C) 1998-2000 19 | * the Initial Developer. All Rights Reserved. 20 | * 21 | * Contributor(s): 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | #ifndef __LOG_H__ 38 | #define __LOG_H__ 39 | 40 | #include 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* 47 | ** log.h -- Declare interfaces to the Logging service 48 | ** 49 | ** To use the service from a client program, you should create a 50 | ** PRLogModuleInfo structure by calling PR_NewLogModule(). After 51 | ** creating the LogModule, you can write to the log using the LOG() 52 | ** macro. 53 | ** 54 | ** Initialization of the log service is handled by log_init(). 55 | ** 56 | ** At execution time, you must enable the log service. To enable the 57 | ** log service, set the environment variable: LOG_MODULES 58 | ** variable. 59 | ** 60 | ** LOG_MODULES variable has the form: 61 | ** 62 | ** :[, :]* 63 | ** 64 | ** Where: 65 | ** is the name passed to PR_NewLogModule(). 66 | ** is a numeric constant, e.g. 5. This value is the maximum 67 | ** value of a log event, enumerated by PRLogModuleLevel, that you want 68 | ** written to the log. 69 | ** 70 | ** For example: to record all events of greater value than or equal to 71 | ** LOG_ERROR for a LogModule names "gizmo", say: 72 | ** 73 | ** set LOG_MODULES=gizmo:2 74 | ** 75 | ** Note that you must specify the numeric value of LOG_ERROR. 76 | ** 77 | ** Special LogModule names are provided for controlling the log 78 | ** service at execution time. These controls should be set in the 79 | ** LOG_MODULES environment variable at execution time to affect 80 | ** the log service for your application. 81 | ** 82 | ** The special LogModule "all" enables all LogModules. To enable all 83 | ** LogModule calls to LOG(), say: 84 | ** 85 | ** set LOG_MODULES=all:5 86 | ** 87 | ** The special LogModule name "sync" tells the log service to do 88 | ** unbuffered logging. 89 | ** 90 | ** The special LogModule name "bufsize:" tells the log service 91 | ** to set the log buffer to . 92 | ** 93 | ** The environment variable LOG_FILE specifies the log file to use 94 | ** unless the default of "stderr" is acceptable. For MS Windows 95 | ** systems, LOG_FILE can be set to a special value: "WinDebug" 96 | ** (case sensitive). This value causes LOG() output to be written 97 | ** using the Windows API OutputDebugString(). OutputDebugString() 98 | ** writes to the debugger window; some people find this helpful. 99 | ** 100 | ** 101 | ** To put log messages in your programs, use the LOG macro: 102 | ** 103 | ** LOG(, , (, *)); 104 | ** 105 | ** Where is the address of a PRLogModuleInfo structure, and 106 | ** is one of the levels defined by the enumeration: 107 | ** PRLogModuleLevel. is a printf() style of argument list. That 108 | ** is: (fmtstring, ...). 109 | ** 110 | ** Example: 111 | ** 112 | ** main() { 113 | ** int one = 1; 114 | ** PRLogModuleInfo * myLm = PR_NewLogModule("gizmo"); 115 | ** LOG( myLm, LOG_ALWAYS, ("Log this! %d\n", one)); 116 | ** return; 117 | ** } 118 | ** 119 | ** Note the use of printf() style arguments as the third agrument(s) to 120 | ** LOG(). 121 | ** 122 | ** After compiling and linking you application, set the environment: 123 | ** 124 | ** set LOG_MODULES=gizmo:5 125 | ** set LOG_FILE=logfile.txt 126 | ** 127 | ** When you execute your application, the string "Log this! 1" will be 128 | ** written to the file "logfile.txt". 129 | ** 130 | */ 131 | 132 | typedef enum log_module_level_t 133 | { 134 | LOG_NONE = 0, /* nothing */ 135 | LOG_ALWAYS = 1, /* always printed */ 136 | LOG_ERROR = 2, /* error messages */ 137 | LOG_WARNING = 3, /* warning messages */ 138 | LOG_DEBUG = 4, /* debug messages */ 139 | 140 | LOG_NOTICE = LOG_DEBUG, /* notice messages */ 141 | LOG_WARN = LOG_WARNING, /* warning messages */ 142 | LOG_MIN = LOG_DEBUG, /* minimal debugging messages */ 143 | LOG_MAX = LOG_DEBUG /* maximal debugging messages */ 144 | } log_module_level_t; 145 | 146 | /* 147 | ** One of these structures is created for each module that uses logging. 148 | ** "name" is the name of the module 149 | ** "level" is the debugging level selected for that module 150 | */ 151 | typedef struct log_module_info_t 152 | { 153 | const char *name; 154 | log_module_level_t level; 155 | struct log_module_info_t *next; 156 | } log_module_info_t; 157 | 158 | /* 159 | ** initialize logging 160 | */ 161 | void log_init(void); 162 | 163 | /* 164 | ** destroy logging 165 | */ 166 | void log_destroy(void); 167 | 168 | /* 169 | ** Create a new log module. 170 | */ 171 | log_module_info_t* create_log_module(const char *name); 172 | 173 | /* 174 | ** Set the file to use for logging. Returns PR_FALSE if the file cannot 175 | ** be created 176 | */ 177 | int set_log_file(const char *name); 178 | 179 | /* 180 | ** Set the size of the logging buffer. If "buffer_size" is zero then the 181 | ** logging becomes "synchronous" (or unbuffered). 182 | */ 183 | void set_log_buffering(int buffer_size); 184 | 185 | /* 186 | ** Print a string to the log. "fmt" is a PR_snprintf format type. All 187 | ** messages printed to the log are preceeded by the name of the thread 188 | ** and a time stamp. Also, the routine provides a missing newline if one 189 | ** is not provided. 190 | */ 191 | void log_print(const char *fmt, ...); 192 | 193 | /* 194 | ** Flush the log to its file. 195 | */ 196 | void log_flush(void); 197 | 198 | void log_assert(const char *s, const char *file, int ln); 199 | 200 | #define DEBUG 1 201 | 202 | #if defined(DEBUG) || defined(FORCE_LOG) 203 | #define LOGGING 1 204 | 205 | #define LOG_TEST(_module, _level) \ 206 | ((_module)->level >= (_level)) 207 | 208 | /* 209 | ** Log something. 210 | ** "module" is the address of a PRLogModuleInfo structure 211 | ** "level" is the desired logging level 212 | ** "args" is a variable length list of arguments to print, in the following 213 | ** format: ("printf style format string", ...) 214 | */ 215 | #define LOG(_module, _level, _args) \ 216 | { \ 217 | if (LOG_TEST(_module, _level)) { \ 218 | log_print _args; \ 219 | } \ 220 | } 221 | 222 | #else /* defined(DEBUG) || defined(FORCE_LOG) */ 223 | 224 | #undef LOGGING 225 | #define LOG_TEST(module, level) 0 226 | #define LOG(module, level, args) 227 | 228 | #endif /* defined(DEBUG) || defined(FORCE_LOG) */ 229 | 230 | #if defined(DEBUG) || defined(FORCE_ASSERT) 231 | 232 | #define ASSERT(_expr) \ 233 | ((_expr) ? ((void) 0) : log_assert(# _expr, __FILE__, __LINE__)) 234 | 235 | #define NOT_REACHED(_reasonStr) \ 236 | log_assert(_reasonStr, __FILE__, __LINE__) 237 | 238 | #else 239 | 240 | #define ASSERT(expr) ((void) 0) 241 | #define NOT_REACHED(reasonStr) 242 | 243 | #endif /* defined(DEBUG) || defined(FORCE_ASSERT) */ 244 | 245 | #ifdef __cplusplus 246 | }; 247 | #endif 248 | 249 | #endif /* __LOG_H__ */ 250 | -------------------------------------------------------------------------------- /libs/libcommon/logging.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include "logging.h" 24 | 25 | log_module_info_t * lm_main = 0; 26 | 27 | void init_logging() 28 | { 29 | #ifdef __lv2ppu__ 30 | setenv("LOG_MODULES", "all:5", 0); //,bufsize:16384 31 | #elif !defined(_WIN32) 32 | setenv("LOG_MODULES", "all:3", 0); //,bufsize:16384 33 | #endif 34 | lm_main = create_log_module("main"); 35 | log_init(); 36 | } 37 | 38 | void destroy_logging() 39 | { 40 | log_destroy(); 41 | } 42 | -------------------------------------------------------------------------------- /libs/libcommon/logging.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __LOGGING_H__ 23 | #define __LOGGING_H__ 24 | 25 | #include "log.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | void init_logging(); 32 | void destroy_logging(); 33 | 34 | extern log_module_info_t * lm_main; 35 | 36 | #ifdef __cplusplus 37 | }; 38 | #endif 39 | 40 | #endif /* __LOGGING_H__ */ 41 | -------------------------------------------------------------------------------- /libs/libcommon/pb.h: -------------------------------------------------------------------------------- 1 | #ifndef _PB_H_ 2 | #define _PB_H_ 3 | 4 | /* pb.h: Common parts for nanopb library. 5 | * Most of these are quite low-level stuff. For the high-level interface, 6 | * see pb_encode.h or pb_decode.h 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef __GNUC__ 14 | /* This just reduces memory requirements, but is not required. */ 15 | #define pb_packed __attribute__((packed)) 16 | #else 17 | #define pb_packed 18 | #endif 19 | 20 | /* List of possible field types. These are used in the autogenerated code. 21 | * Least-significant 4 bits tell the scalar type 22 | * Most-significant 4 bits specify repeated/required/packed etc. 23 | * 24 | * INT32 and UINT32 are treated the same, as are (U)INT64 and (S)FIXED* 25 | * These types are simply casted to correct field type when they are 26 | * assigned to the memory pointer. 27 | * SINT* is different, though, because it is zig-zag coded. 28 | */ 29 | 30 | typedef enum { 31 | /************************ 32 | * Field contents types * 33 | ************************/ 34 | 35 | /* Numeric types */ 36 | PB_LTYPE_VARINT = 0x00, /* int32, uint32, int64, uint64, bool, enum */ 37 | PB_LTYPE_SVARINT = 0x01, /* sint32, sint64 */ 38 | PB_LTYPE_FIXED32 = 0x02, /* fixed32, sfixed32, float */ 39 | PB_LTYPE_FIXED64 = 0x03, /* fixed64, sfixed64, double */ 40 | 41 | /* Marker for last packable field type. */ 42 | PB_LTYPE_LAST_PACKABLE = 0x03, 43 | 44 | /* Byte array with pre-allocated buffer. 45 | * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ 46 | PB_LTYPE_BYTES = 0x04, 47 | 48 | /* String with pre-allocated buffer. 49 | * data_size is the maximum length. */ 50 | PB_LTYPE_STRING = 0x05, 51 | 52 | /* Submessage 53 | * submsg_fields is pointer to field descriptions */ 54 | PB_LTYPE_SUBMESSAGE = 0x06, 55 | 56 | /* Number of declared LTYPES */ 57 | PB_LTYPES_COUNT = 7, 58 | 59 | /****************** 60 | * Modifier flags * 61 | ******************/ 62 | 63 | /* Just the basic, write data at data_offset */ 64 | PB_HTYPE_REQUIRED = 0x00, 65 | 66 | /* Write true at size_offset */ 67 | PB_HTYPE_OPTIONAL = 0x10, 68 | 69 | /* Read to pre-allocated array 70 | * Maximum number of entries is array_size, 71 | * actual number is stored at size_offset */ 72 | PB_HTYPE_ARRAY = 0x20, 73 | 74 | /* Works for all required/optional/repeated fields. 75 | * data_offset points to pb_callback_t structure. 76 | * LTYPE should be 0 (it is ignored, but sometimes 77 | * used to speculatively index an array). */ 78 | PB_HTYPE_CALLBACK = 0x30 79 | } pb_packed pb_type_t; 80 | 81 | #define PB_HTYPE(x) ((x) & 0xF0) 82 | #define PB_LTYPE(x) ((x) & 0x0F) 83 | 84 | /* This structure is used in auto-generated constants 85 | * to specify struct fields. 86 | * You can change field sizes here if you need structures 87 | * larger than 256 bytes or field tags larger than 256. 88 | * The compiler should complain if your .proto has such 89 | * structures ("initializer too large for type"). 90 | */ 91 | typedef struct _pb_field_t pb_field_t; 92 | struct _pb_field_t { 93 | uint8_t tag; 94 | pb_type_t type; 95 | uint8_t data_offset; /* Offset of field data, relative to previous field. */ 96 | int8_t size_offset; /* Offset of array size or has-boolean, relative to data */ 97 | uint32_t data_size; /* Data size in bytes for a single item */ 98 | uint8_t array_size; /* Maximum number of entries in array */ 99 | 100 | /* Field definitions for submessage 101 | * OR default value for all other non-array, non-callback types 102 | * If null, then field will zeroed. */ 103 | const void *ptr; 104 | } pb_packed; 105 | 106 | /* This structure is used for 'bytes' arrays. 107 | * It has the number of bytes in the beginning, and after that an array. 108 | * Note that actual structs used will have a different length of bytes array. 109 | */ 110 | typedef struct { 111 | size_t size; 112 | uint8_t *bytes; 113 | } pb_bytes_array_t; 114 | 115 | /* This structure is used for giving the callback function. 116 | * It is stored in the message structure and filled in by the method that 117 | * calls pb_decode. 118 | * 119 | * The decoding callback will be given a limited-length stream 120 | * If the wire type was string, the length is the length of the string. 121 | * If the wire type was a varint/fixed32/fixed64, the length is the length 122 | * of the actual value. 123 | * The function may be called multiple times (especially for repeated types, 124 | * but also otherwise if the message happens to contain the field multiple 125 | * times.) 126 | * 127 | * The encoding callback will receive the actual output stream. 128 | * It should write all the data in one call, including the field tag and 129 | * wire type. It can write multiple fields. 130 | * 131 | * The callback can be null if you want to skip a field. 132 | */ 133 | typedef struct _pb_istream_t pb_istream_t; 134 | typedef struct _pb_ostream_t pb_ostream_t; 135 | typedef struct _pb_callback_t pb_callback_t; 136 | struct _pb_callback_t { 137 | union { 138 | bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg); 139 | bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg); 140 | } funcs; 141 | 142 | /* Free arg for use by callback */ 143 | void *arg; 144 | }; 145 | 146 | /* Wire types. Library user needs these only in encoder callbacks. */ 147 | typedef enum { 148 | PB_WT_VARINT = 0, 149 | PB_WT_64BIT = 1, 150 | PB_WT_STRING = 2, 151 | PB_WT_32BIT = 5 152 | } pb_wire_type_t; 153 | 154 | /* These macros are used to declare pb_field_t's in the constant array. */ 155 | #define pb_membersize(st, m) (sizeof ((st*)0)->m) 156 | #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) 157 | #define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) 158 | #define pb_delta_end(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) 159 | #define PB_LAST_FIELD {0,0,0,0,0,0,0} 160 | 161 | 162 | #endif -------------------------------------------------------------------------------- /libs/libcommon/pb_decode.h: -------------------------------------------------------------------------------- 1 | #ifndef _PB_DECODE_H_ 2 | #define _PB_DECODE_H_ 3 | 4 | /* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. 5 | * The main function is pb_decode. You will also need to create an input 6 | * stream, which is easiest to do with pb_istream_t. 7 | * 8 | * You also need structures and their corresponding pb_field_t descriptions. 9 | * These are usually generated from .proto-files with a script. 10 | */ 11 | 12 | #include 13 | #include "pb.h" 14 | 15 | /* Lightweight input stream. 16 | * You can provide a callback function for reading or use 17 | * pb_istream_from_buffer. 18 | * 19 | * Rules for callback: 20 | * 1) Return false on IO errors. This will cause decoding to abort. 21 | * 22 | * 2) If buf is NULL, read but don't store bytes ("skip input"). 23 | * 24 | * 3) You can use state to store your own data (e.g. buffer pointer), 25 | * and rely on pb_read to verify that no-body reads past bytes_left. 26 | * 27 | * 4) Your callback may be used with substreams, in which case bytes_left 28 | * is different than from the main stream. Don't use bytes_left to compute 29 | * any pointers. 30 | */ 31 | struct _pb_istream_t 32 | { 33 | bool (*callback)(pb_istream_t *stream, uint8_t *buf, size_t count); 34 | void *state; /* Free field for use by callback implementation */ 35 | size_t bytes_left; 36 | }; 37 | 38 | pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize); 39 | bool pb_read(pb_istream_t *stream, uint8_t *buf, size_t count); 40 | 41 | /* Decode from stream to destination struct. 42 | * Returns true on success, false on any failure. 43 | * The actual struct pointed to by dest must match the description in fields. 44 | */ 45 | bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); 46 | 47 | /* --- Helper functions --- 48 | * You may want to use these from your caller or callbacks. 49 | */ 50 | 51 | bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); 52 | 53 | bool pb_skip_varint(pb_istream_t *stream); 54 | bool pb_skip_string(pb_istream_t *stream); 55 | 56 | /* --- Field decoders --- 57 | * Each decoder takes stream and field description, and a pointer to the field 58 | * in the destination struct (dest = struct_addr + field->data_offset). 59 | * For arrays, these functions are called repeatedly. 60 | */ 61 | 62 | bool pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); 63 | bool pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest); 64 | bool pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest); 65 | bool pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest); 66 | 67 | bool pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); 68 | bool pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); 69 | bool pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /libs/libcommon/pb_encode.h: -------------------------------------------------------------------------------- 1 | #ifndef _PB_ENCODE_H_ 2 | #define _PB_ENCODE_H_ 3 | 4 | /* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. 5 | * The main function is pb_encode. You also need an output stream, structures 6 | * and their field descriptions (just like with pb_decode). 7 | */ 8 | 9 | #include 10 | #include "pb.h" 11 | 12 | /* Lightweight output stream. 13 | * You can provide callback for writing or use pb_ostream_from_buffer. 14 | * 15 | * Alternatively, callback can be NULL in which case the stream will just 16 | * count the number of bytes that would have been written. In this case 17 | * max_size is not checked. 18 | * 19 | * Rules for callback: 20 | * 1) Return false on IO errors. This will cause encoding to abort. 21 | * 22 | * 2) You can use state to store your own data (e.g. buffer pointer). 23 | * 24 | * 3) pb_write will update bytes_written after your callback runs. 25 | * 26 | * 4) Substreams will modify max_size and bytes_written. Don't use them to 27 | * calculate any pointers. 28 | */ 29 | struct _pb_ostream_t 30 | { 31 | bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count); 32 | void *state; /* Free field for use by callback implementation */ 33 | size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ 34 | size_t bytes_written; 35 | }; 36 | 37 | pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize); 38 | bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count); 39 | 40 | /* Encode struct to given output stream. 41 | * Returns true on success, false on any failure. 42 | * The actual struct pointed to by src_struct must match the description in fields. 43 | * All required fields in the struct are assumed to have been filled in. 44 | */ 45 | bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); 46 | 47 | /* --- Helper functions --- 48 | * You may want to use these from your caller or callbacks. 49 | */ 50 | 51 | bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); 52 | bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, int field_number); 53 | /* Encode tag based on LTYPE and field number defined in the field structure. */ 54 | bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); 55 | /* Write length as varint and then the contents of buffer. */ 56 | bool pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size); 57 | 58 | /* --- Field encoders --- 59 | * Each encoder writes the content for the field. 60 | * The tag/wire type has been written already. 61 | */ 62 | 63 | bool pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src); 64 | bool pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); 65 | bool pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src); 66 | bool pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src); 67 | 68 | bool pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); 69 | bool pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src); 70 | bool pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src); 71 | 72 | #endif -------------------------------------------------------------------------------- /libs/libcommon/socket.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/socket.c -------------------------------------------------------------------------------- /libs/libcommon/socket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/socket.h -------------------------------------------------------------------------------- /libs/libcommon/sys/io_buffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __SYS_IO_BUFFER_H__ 23 | #define __SYS_IO_BUFFER_H__ 24 | 25 | #ifndef __lv2ppu__ 26 | #error you need the psl1ght/lv2 ppu compatible compiler! 27 | #endif 28 | 29 | #include 30 | #include 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | typedef int sys_io_buffer_t; 37 | typedef int sys_io_block_t; 38 | 39 | static inline int sys_io_buffer_create(int io_block_count, int block_size, int blocks, int unknown_3, sys_io_buffer_t *io_buffer) 40 | { 41 | // unknown_3, alignment? (spotted: 512, 1024, any other value == crash) 42 | 43 | lv2syscall5(624, io_block_count, block_size, blocks, unknown_3 & 0x600, (uint64_t) io_buffer); 44 | 45 | return_to_user_prog(int); 46 | } 47 | 48 | static inline int sys_io_buffer_destroy(sys_io_buffer_t io_buffer) 49 | { 50 | lv2syscall1(625, io_buffer); 51 | return_to_user_prog(int); 52 | } 53 | 54 | static inline int sys_io_buffer_allocate(sys_io_buffer_t io_buffer, sys_io_block_t *block) 55 | { 56 | lv2syscall2(626, io_buffer, (uint64_t) block); 57 | return_to_user_prog(int); 58 | } 59 | 60 | static inline int sys_io_buffer_free(sys_io_buffer_t io_buffer, sys_io_block_t block) 61 | { 62 | lv2syscall2(627, io_buffer, block); 63 | return_to_user_prog(int); 64 | } 65 | 66 | #ifdef __cplusplus 67 | }; 68 | #endif 69 | #endif /* _SYS_IO_BUFFER_H__ */ 70 | -------------------------------------------------------------------------------- /libs/libcommon/sys/isoself.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __ISOSELF_H__ 23 | #define __ISOSELF_H__ 24 | 25 | #ifndef __lv2ppu__ 26 | #error you need the psl1ght/lv2 ppu compatible compiler! 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | static inline int sys_isoself_spu_create(sys_raw_spu_t *id, uint8_t *source_spe) 39 | { 40 | lv2syscall6(230, (uint64_t) id, (uint64_t) source_spe, 0, 0, 0, 0); 41 | return_to_user_prog(int); 42 | } 43 | 44 | static inline int sys_isoself_spu_destroy(sys_raw_spu_t id) 45 | { 46 | lv2syscall1(231, id); 47 | return_to_user_prog(int); 48 | } 49 | 50 | static inline int sys_isoself_spu_start(sys_raw_spu_t id) 51 | { 52 | lv2syscall1(232, id); 53 | return_to_user_prog(int); 54 | } 55 | 56 | static inline int sys_isoself_spu_create_interrupt_tag(sys_raw_spu_t id, 57 | uint32_t class_id, 58 | uint32_t hwthread, 59 | sys_interrupt_tag_t *intrtag) 60 | { 61 | lv2syscall4(233, id, class_id, hwthread, (uint64_t) intrtag); 62 | return_to_user_prog(int); 63 | } 64 | 65 | static inline int sys_isoself_spu_set_int_mask(sys_raw_spu_t id, 66 | uint32_t class_id, 67 | uint64_t mask) 68 | { 69 | lv2syscall3(234, id, class_id, mask); 70 | return_to_user_prog(int); 71 | } 72 | 73 | static inline int sys_isoself_spu_set_int_stat(sys_raw_spu_t id, 74 | uint32_t class_id, 75 | uint64_t stat) 76 | { 77 | lv2syscall3(236, id, class_id, stat); 78 | return_to_user_prog(int); 79 | } 80 | 81 | static inline int sys_isoself_spu_get_int_stat(sys_raw_spu_t id, 82 | uint32_t class_id, 83 | uint64_t * stat) 84 | { 85 | lv2syscall3(237, id, class_id, (uint64_t) stat); 86 | return_to_user_prog(int); 87 | } 88 | 89 | static inline int sys_isoself_spu_read_puint_mb(sys_raw_spu_t id, 90 | uint32_t * value) 91 | { 92 | lv2syscall2(240, id, (uint64_t) value); 93 | return_to_user_prog(int); 94 | } 95 | 96 | #ifdef __cplusplus 97 | }; 98 | #endif 99 | 100 | #endif /* __ISOSELF_H__ */ 101 | -------------------------------------------------------------------------------- /libs/libcommon/sys/storage.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __SYS_STORAGE_H__ 23 | #define __SYS_STORAGE_H__ 24 | 25 | #ifndef __lv2ppu__ 26 | #error you need the psl1ght/lv2 ppu compatible compiler! 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | #define BD_DEVICE 0x0101000000000006ULL 40 | 41 | /* The generic packet command opcodes for CD/DVD Logical Units, 42 | * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */ 43 | #define GPCMD_GET_CONFIGURATION 0x46 44 | #define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a 45 | #define GPCMD_MODE_SELECT_10 0x55 46 | #define GPCMD_MODE_SENSE_10 0x5a 47 | #define GPCMD_READ_CD 0xbe 48 | #define GPCMD_READ_DVD_STRUCTURE 0xad 49 | #define GPCMD_READ_TRACK_RZONE_INFO 0x52 50 | #define GPCMD_READ_TOC_PMA_ATIP 0x43 51 | #define GPCMD_REPORT_KEY 0xa4 52 | #define GPCMD_SEND_KEY 0xa3 53 | #define GPCMD_START_STOP_UNIT 0x1b 54 | 55 | #define LV2_STORAGE_SEND_ATAPI_COMMAND (1) 56 | 57 | struct lv2_atapi_cmnd_block 58 | { 59 | uint8_t pkt[32]; /* packet command block */ 60 | uint32_t pktlen; /* should be 12 for ATAPI 8020 */ 61 | uint32_t blocks; 62 | uint32_t block_size; 63 | uint32_t proto; /* transfer mode */ 64 | uint32_t in_out; /* transfer direction */ 65 | uint32_t unknown; 66 | } __attribute__((packed)); 67 | 68 | typedef struct 69 | { 70 | uint8_t name[7]; 71 | uint8_t unknown01; 72 | uint32_t unknown02; // random nr? 73 | uint32_t zero01; 74 | uint32_t unknown03; // 0x28? 75 | uint32_t unknown04; // 0xd000e990? 76 | uint8_t zero02[16]; 77 | uint64_t total_sectors; 78 | uint32_t sector_size; 79 | uint32_t unknown05; 80 | uint8_t writable; 81 | uint8_t unknown06[3]; 82 | uint32_t unknown07; 83 | } __attribute__((packed)) device_info_t; 84 | 85 | enum lv2_atapi_proto 86 | { 87 | ATAPI_NON_DATA_PROTO = 0, 88 | ATAPI_PIO_DATA_IN_PROTO = 1, 89 | ATAPI_PIO_DATA_OUT_PROTO = 2, 90 | ATAPI_DMA_PROTO = 3 91 | }; 92 | 93 | enum lv2_atapi_in_out 94 | { 95 | ATAPI_DIR_WRITE = 0, /* memory -> device */ 96 | ATAPI_DIR_READ = 1 /* device -> memory */ 97 | }; 98 | 99 | static inline void sys_storage_init_atapi_cmnd( 100 | struct lv2_atapi_cmnd_block *atapi_cmnd 101 | , uint32_t block_size 102 | , uint32_t proto 103 | , uint32_t type) 104 | { 105 | memset(atapi_cmnd, 0, sizeof(struct lv2_atapi_cmnd_block)); 106 | atapi_cmnd->pktlen = 12; 107 | atapi_cmnd->blocks = 1; 108 | atapi_cmnd->block_size = block_size; /* transfer size is block_size * blocks */ 109 | atapi_cmnd->proto = proto; 110 | atapi_cmnd->in_out = type; 111 | } 112 | 113 | static inline int sys_storage_send_atapi_command(uint32_t fd, struct lv2_atapi_cmnd_block *atapi_cmnd, uint8_t *buffer) 114 | { 115 | uint64_t tag; 116 | lv2syscall7(616 117 | , fd 118 | , LV2_STORAGE_SEND_ATAPI_COMMAND 119 | , (uint64_t) atapi_cmnd 120 | , sizeof(struct lv2_atapi_cmnd_block) 121 | , (uint64_t) buffer 122 | , atapi_cmnd->block_size 123 | , (uint64_t) &tag); 124 | 125 | return_to_user_prog(int); 126 | } 127 | 128 | static inline int sys_storage_async_configure(uint32_t fd, sys_io_buffer_t io_buffer, sys_event_queue_t equeue_id, int *unknown) 129 | { 130 | lv2syscall4(605 131 | , fd 132 | , io_buffer 133 | , equeue_id 134 | , (uint64_t) unknown); 135 | 136 | return_to_user_prog(int); 137 | } 138 | 139 | static inline int sys_storage_get_device_info(uint64_t device, device_info_t *device_info) 140 | { 141 | lv2syscall2(609, device, (uint64_t) device_info); 142 | return_to_user_prog(int); 143 | } 144 | 145 | static inline int sys_storage_open(uint64_t id, int *fd) 146 | { 147 | lv2syscall4(600, id, 0, (uint64_t) fd, 0); 148 | return_to_user_prog(int); 149 | } 150 | 151 | static inline int sys_storage_close(int fd) 152 | { 153 | lv2syscall1(601, fd); 154 | return_to_user_prog(int); 155 | } 156 | 157 | static inline int sys_storage_read(int fd, uint32_t start_sector, uint32_t sectors, uint8_t *bounce_buf, uint32_t *sectors_read) 158 | { 159 | lv2syscall7(602, fd, 0, start_sector, sectors, (uint64_t) bounce_buf, (uint64_t) sectors_read, 0); 160 | return_to_user_prog(int); 161 | } 162 | 163 | static inline int sys_storage_async_read(int fd, uint32_t start_sector, uint32_t sectors, sys_io_block_t bounce_buf, uint64_t user_data) 164 | { 165 | lv2syscall7(606, fd, 0, start_sector, sectors, bounce_buf, user_data, 0); 166 | return_to_user_prog(int); 167 | } 168 | 169 | /** 170 | * In order to execute syscall 864 the access rights of LV2 need to be patched 171 | */ 172 | static inline int sys_storage_reset_bd(void) 173 | { 174 | lv2syscall2(864, 0x5004, 0x29); 175 | return_to_user_prog(int); 176 | } 177 | 178 | /** 179 | * In order to execute syscall 864 the access rights of LV2 need to be patched 180 | */ 181 | static inline int sys_storage_authenticate_bd(void) 182 | { 183 | int func = 0x43; 184 | lv2syscall2(864, 0x5007, (uint64_t) &func); 185 | return_to_user_prog(int); 186 | } 187 | 188 | #ifdef __cplusplus 189 | }; 190 | #endif 191 | #endif /* _SYS_STORAGE_H__ */ 192 | -------------------------------------------------------------------------------- /libs/libcommon/timeout.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/timeout.c -------------------------------------------------------------------------------- /libs/libcommon/timeout.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/timeout.h -------------------------------------------------------------------------------- /libs/libcommon/usocket.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/usocket.c -------------------------------------------------------------------------------- /libs/libcommon/usocket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/usocket.h -------------------------------------------------------------------------------- /libs/libcommon/utils.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "utils.h" 31 | #include "charset.h" 32 | #include "logging.h" 33 | 34 | char *substr(const char *pstr, int start, int numchars) 35 | { 36 | static char pnew[512]; 37 | wchar_t *wc; 38 | char *wchar_type; 39 | char *c; 40 | memset(pnew, 0, sizeof(pnew)); 41 | if (numchars < (int) sizeof(pnew)) 42 | { 43 | #ifdef _WIN32 44 | wchar_type = (sizeof(wchar_t) == 2) ? 45 | "UCS-2-INTERNAL" : "UCS-4-INTERNAL"; 46 | #else 47 | wchar_type = "WCHAR_T"; 48 | #endif 49 | wc = (wchar_t *) charset_convert((char *) pstr + start, 50 | numchars, "UTF-8", wchar_type); 51 | c = charset_convert((char *) wc, 52 | wcslen(wc) * sizeof(wchar_t), wchar_type, "UTF-8"); 53 | strcpy(pnew, c); 54 | free(wc); 55 | free(c); 56 | return pnew; 57 | } 58 | return pnew; 59 | } 60 | 61 | char *str_replace(const char *src, const char *from, const char *to) 62 | { 63 | size_t size = strlen(src) + 1; 64 | size_t fromlen = strlen(from); 65 | size_t tolen = strlen(to); 66 | char *value = malloc(size); 67 | char *dst = value; 68 | if (value != NULL) 69 | { 70 | for ( ;; ) 71 | { 72 | const char *match = strstr(src, from); 73 | if ( match != NULL ) 74 | { 75 | size_t count = match - src; 76 | char *temp; 77 | size += tolen - fromlen; 78 | temp = realloc(value, size); 79 | if ( temp == NULL ) 80 | { 81 | free(value); 82 | return NULL; 83 | } 84 | dst = temp + (dst - value); 85 | value = temp; 86 | memmove(dst, src, count); 87 | src += count; 88 | dst += count; 89 | memmove(dst, to, tolen); 90 | src += fromlen; 91 | dst += tolen; 92 | } 93 | else /* No match found. */ 94 | { 95 | strcpy(dst, src); 96 | break; 97 | } 98 | } 99 | } 100 | return value; 101 | } 102 | 103 | void replace_double_space_with_single(char *str) 104 | { 105 | const char *match; 106 | char *ret; 107 | do 108 | { 109 | ret = str_replace(str, " ", " "); 110 | if (ret) 111 | { 112 | strcpy(str, ret); 113 | free(ret); 114 | } 115 | match = strstr(str, " "); 116 | } 117 | while (match != 0); 118 | } 119 | 120 | // removes all instances of bad characters from the string 121 | // 122 | // str - the string to trim 123 | // bad - the sting containing all the characters to remove 124 | void trim_chars(char * str, const char * bad) 125 | { 126 | int i; 127 | int pos; 128 | int len = strlen(str); 129 | unsigned b; 130 | 131 | for (b = 0; b < strlen(bad); b++) 132 | { 133 | pos = 0; 134 | for (i = 0; i < len + 1; i++) 135 | { 136 | if (str[i] != bad[b]) 137 | { 138 | str[pos] = str[i]; 139 | pos++; 140 | } 141 | } 142 | } 143 | } 144 | 145 | // removes leading and trailing whitespace as defined by isspace() 146 | // 147 | // str - the string to trim 148 | void trim_whitespace(char * s) 149 | { 150 | uint8_t * p = (uint8_t *) s; 151 | int l = strlen((char *) p); 152 | 153 | while(isspace((int) p[l - 1])) p[--l] = 0; 154 | while(* p && isspace((int) *p)) ++p, --l; 155 | 156 | memmove(s, p, l + 1); 157 | } 158 | 159 | const char hex_asc[] = "0123456789abcdef"; 160 | 161 | #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] 162 | #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] 163 | 164 | /** 165 | * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory 166 | * @buf: data blob to dump 167 | * @len: number of bytes in the @buf 168 | * @rowsize: number of bytes to print per line; must be 16 or 32 169 | * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) 170 | * @linebuf: where to put the converted data 171 | * @linebuflen: total size of @linebuf, including space for terminating NUL 172 | * @ascii: include ASCII after the hex output 173 | * 174 | * hex_dump_to_buffer() works on one "line" of output at a time, i.e., 175 | * 16 or 32 bytes of input data converted to hex + ASCII output. 176 | * 177 | * Given a buffer of uint8_t data, hex_dump_to_buffer() converts the input data 178 | * to a hex + ASCII dump at the supplied memory location. 179 | * The converted output is always NUL-terminated. 180 | * 181 | * E.g.: 182 | * hex_dump_to_buffer(frame->data, frame->len, 16, 1, 183 | * linebuf, sizeof(linebuf), true); 184 | * 185 | * example output buffer: 186 | * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO 187 | */ 188 | void hex_dump_to_buffer(const void *buf, int len, int rowsize, 189 | int groupsize, char *linebuf, int linebuflen, 190 | int ascii) 191 | { 192 | const uint8_t *ptr = buf; 193 | uint8_t ch; 194 | int j, lx = 0; 195 | int ascii_column; 196 | 197 | if (rowsize != 16 && rowsize != 32) 198 | rowsize = 16; 199 | 200 | if (!len) 201 | goto nil; 202 | if (len > rowsize) /* limit to one line at a time */ 203 | len = rowsize; 204 | if ((len % groupsize) != 0) /* no mixed size output */ 205 | groupsize = 1; 206 | 207 | switch (groupsize) { 208 | case 8: { 209 | const uint64_t *ptr8 = buf; 210 | int ngroups = len / groupsize; 211 | 212 | for (j = 0; j < ngroups; j++) 213 | lx += snprintf(linebuf + lx, linebuflen - lx, 214 | "%s%16.16llx", j ? " " : "", 215 | (unsigned long long)*(ptr8 + j)); 216 | ascii_column = 17 * ngroups + 2; 217 | break; 218 | } 219 | 220 | case 4: { 221 | const uint32_t *ptr4 = buf; 222 | int ngroups = len / groupsize; 223 | 224 | for (j = 0; j < ngroups; j++) 225 | lx += snprintf(linebuf + lx, linebuflen - lx, 226 | "%s%8.8x", j ? " " : "", *(ptr4 + j)); 227 | ascii_column = 9 * ngroups + 2; 228 | break; 229 | } 230 | 231 | case 2: { 232 | const uint16_t *ptr2 = buf; 233 | int ngroups = len / groupsize; 234 | 235 | for (j = 0; j < ngroups; j++) 236 | lx += snprintf(linebuf + lx, linebuflen - lx, 237 | "%s%4.4x", j ? " " : "", *(ptr2 + j)); 238 | ascii_column = 5 * ngroups + 2; 239 | break; 240 | } 241 | 242 | default: 243 | for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) { 244 | ch = ptr[j]; 245 | linebuf[lx++] = hex_asc_hi(ch); 246 | linebuf[lx++] = hex_asc_lo(ch); 247 | linebuf[lx++] = ' '; 248 | } 249 | if (j) 250 | lx--; 251 | 252 | ascii_column = 3 * rowsize + 2; 253 | break; 254 | } 255 | if (!ascii) 256 | goto nil; 257 | 258 | while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) 259 | linebuf[lx++] = ' '; 260 | for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) { 261 | ch = ptr[j]; 262 | linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.'; 263 | } 264 | nil: 265 | linebuf[lx++] = '\0'; 266 | } 267 | 268 | /** 269 | * print_hex_dump - print a text hex dump to syslog for a binary blob of data 270 | * @level: kernel log level (e.g. KERN_DEBUG) 271 | * @prefix_str: string to prefix each line with; 272 | * caller supplies trailing spaces for alignment if desired 273 | * @rowsize: number of bytes to print per line; must be 16 or 32 274 | * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) 275 | * @buf: data blob to dump 276 | * @len: number of bytes in the @buf 277 | * @ascii: include ASCII after the hex output 278 | * 279 | * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump 280 | * to the kernel log at the specified kernel log level, with an optional 281 | * leading prefix. 282 | * 283 | * print_hex_dump() works on one "line" of output at a time, i.e., 284 | * 16 or 32 bytes of input data converted to hex + ASCII output. 285 | * print_hex_dump() iterates over the entire input @buf, breaking it into 286 | * "line size" chunks to format and print. 287 | * 288 | * E.g.: 289 | * print_hex_dump(LOG_NOTICE, "data: ", 16, 1, frame->data, frame->len, 0); 290 | */ 291 | void print_hex_dump(log_module_level_t level, const char *prefix_str, 292 | int rowsize, int groupsize, 293 | const void *buf, int len, int ascii) 294 | { 295 | const uint8_t *ptr = buf; 296 | int i, linelen, remaining = len; 297 | char linebuf[32 * 3 + 2 + 32 + 1]; 298 | 299 | if (rowsize != 16 && rowsize != 32) 300 | rowsize = 16; 301 | 302 | for (i = 0; i < len; i += rowsize) 303 | { 304 | linelen = min(remaining, rowsize); 305 | remaining -= rowsize; 306 | 307 | hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, 308 | linebuf, sizeof(linebuf), ascii); 309 | 310 | LOG(lm_main, level, ("%s%s\n", prefix_str, linebuf)); 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /libs/libcommon/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __UTILS_H__ 23 | #define __UTILS_H__ 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #include "log.h" 30 | 31 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 32 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 33 | 34 | #define is_between_exclusive(num,lowerbound,upperbound) \ 35 | ( ((num) > (lowerbound)) && ((num) < (upperbound)) ) 36 | 37 | #define is_between_inclusive(num,lowerbound,upperbound) \ 38 | ( ((num) >= (lowerbound)) && ((num) <= (upperbound)) ) 39 | 40 | char *substr(const char *, int, int); 41 | 42 | char *str_replace(const char *src, const char *from, const char *to); 43 | 44 | // replaces doubles spaces with a single space 45 | // 46 | // str - the string to process 47 | void replace_double_space_with_single(char *str); 48 | 49 | // removes leading and trailing whitespace as defined by isspace() 50 | // 51 | // str - the string to trim 52 | void trim_whitespace(char * str); 53 | 54 | // removes all instances of bad characters from the string 55 | // 56 | // str - the string to trim 57 | // bad - the sting containing all the characters to remove 58 | void trim_chars(char * str, const char * bad); 59 | 60 | void print_hex_dump(log_module_level_t level, const char *prefix_str, 61 | int rowsize, int groupsize, 62 | const void *buf, int len, int ascii); 63 | 64 | 65 | #ifdef __cplusplus 66 | }; 67 | #endif 68 | 69 | #endif /* __UTILS_H__ */ 70 | -------------------------------------------------------------------------------- /libs/libcommon/wsocket.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/wsocket.c -------------------------------------------------------------------------------- /libs/libcommon/wsocket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libcommon/wsocket.h -------------------------------------------------------------------------------- /libs/libdstdec/buffer_pool.c: -------------------------------------------------------------------------------- 1 | /* 2 | This software is provided 'as-is', without any express or implied 3 | warranty. In no event will the author be held liable for any damages 4 | arising from the use of this software. 5 | 6 | Permission is granted to anyone to use this software for any purpose, 7 | including commercial applications, and to alter it and redistribute it 8 | freely, subject to the following restrictions: 9 | 10 | 1. The origin of this software must not be misrepresented; you must not 11 | claim that you wrote the original software. If you use this software 12 | in a product, an acknowledgment in the product documentation would be 13 | appreciated but is not required. 14 | 2. Altered source versions must be plainly marked as such, and must not be 15 | misrepresented as being the original software. 16 | 3. This notice may not be removed or altered from any source distribution. 17 | 18 | Mark Adler 19 | madler@alumni.caltech.edu 20 | */ 21 | 22 | #include 23 | #include 24 | #ifndef __APPLE__ 25 | #include 26 | #endif 27 | 28 | #include "buffer_pool.h" 29 | 30 | /* initialize a pool (pool structure itself provided, not allocated) -- the 31 | limit is the maximum number of spaces in the pool, or -1 to indicate no 32 | limit, i.e., to never wait for a buffer to return to the pool */ 33 | void buffer_pool_create(buffer_pool_t *pool, size_t size, int limit) 34 | { 35 | pool->have = new_lock(0); 36 | pool->head = NULL; 37 | pool->size = size; 38 | pool->limit = limit; 39 | pool->made = 0; 40 | } 41 | 42 | /* get a space from a pool -- the use count is initially set to one, so there 43 | is no need to call use_space() for the first use */ 44 | buffer_pool_space_t *buffer_pool_get_space(buffer_pool_t *pool) 45 | { 46 | buffer_pool_space_t *space; 47 | 48 | /* if can't create any more, wait for a space to show up */ 49 | possess(pool->have); 50 | if (pool->limit == 0) 51 | wait_for(pool->have, NOT_TO_BE, 0); 52 | 53 | /* if a space is available, pull it from the list and return it */ 54 | if (pool->head != NULL) 55 | { 56 | space = pool->head; 57 | possess(space->use); 58 | pool->head = space->next; 59 | twist(pool->have, BY, -1); /* one less in pool */ 60 | twist(space->use, TO, 1); /* initially one user */ 61 | return space; 62 | } 63 | 64 | /* nothing available, don't want to wait, make a new space */ 65 | assert(pool->limit != 0); 66 | if (pool->limit > 0) 67 | pool->limit--; 68 | pool->made++; 69 | release(pool->have); 70 | space = malloc(sizeof(buffer_pool_space_t)); 71 | if (space == NULL) 72 | return 0; 73 | space->use = new_lock(1); /* initially one user */ 74 | #ifdef _WIN32 75 | space->buf = _aligned_malloc(pool->size, 64); 76 | #elif __APPLE__ 77 | posix_memalign(&space->buf, 64, pool->size); 78 | #else 79 | space->buf = memalign(64, pool->size); 80 | #endif 81 | if (space->buf == NULL) 82 | return 0; 83 | space->pool = pool; /* remember the pool this belongs to */ 84 | return space; 85 | } 86 | 87 | /* increment the use count to require one more drop before returning this space 88 | to the pool */ 89 | void buffer_pool_use_space(buffer_pool_space_t *space) 90 | { 91 | possess(space->use); 92 | twist(space->use, BY, +1); 93 | } 94 | 95 | /* drop a space, returning it to the pool if the use count is zero */ 96 | void buffer_pool_drop_space(buffer_pool_space_t *space) 97 | { 98 | int use; 99 | buffer_pool_t *pool; 100 | 101 | possess(space->use); 102 | use = peek_lock(space->use); 103 | assert(use != 0); 104 | if (use == 1) 105 | { 106 | pool = space->pool; 107 | possess(pool->have); 108 | space->next = pool->head; 109 | pool->head = space; 110 | twist(pool->have, BY, +1); 111 | } 112 | twist(space->use, BY, -1); 113 | } 114 | 115 | /* free the memory and lock resources of a pool -- return number of spaces for 116 | debugging and resource usage measurement */ 117 | int buffer_pool_free(buffer_pool_t *pool) 118 | { 119 | int count; 120 | buffer_pool_space_t *space; 121 | 122 | possess(pool->have); 123 | count = 0; 124 | while ((space = pool->head) != NULL) 125 | { 126 | pool->head = space->next; 127 | #ifdef _WIN32 128 | _aligned_free(space->buf); 129 | #else 130 | free(space->buf); 131 | #endif 132 | free_lock(space->use); 133 | free(space); 134 | count++; 135 | } 136 | release(pool->have); 137 | free_lock(pool->have); 138 | assert(count == pool->made); 139 | return count; 140 | } 141 | -------------------------------------------------------------------------------- /libs/libdstdec/buffer_pool.h: -------------------------------------------------------------------------------- 1 | /* 2 | This software is provided 'as-is', without any express or implied 3 | warranty. In no event will the author be held liable for any damages 4 | arising from the use of this software. 5 | 6 | Permission is granted to anyone to use this software for any purpose, 7 | including commercial applications, and to alter it and redistribute it 8 | freely, subject to the following restrictions: 9 | 10 | 1. The origin of this software must not be misrepresented; you must not 11 | claim that you wrote the original software. If you use this software 12 | in a product, an acknowledgment in the product documentation would be 13 | appreciated but is not required. 14 | 2. Altered source versions must be plainly marked as such, and must not be 15 | misrepresented as being the original software. 16 | 3. This notice may not be removed or altered from any source distribution. 17 | 18 | Mark Adler 19 | madler@alumni.caltech.edu 20 | */ 21 | 22 | #ifndef BUFFER_POOL_H_INCLUDED 23 | #define BUFFER_POOL_H_INCLUDED 24 | 25 | /* -- pool of spaces for buffer management -- */ 26 | 27 | /* These routines manage a pool of spaces. Each pool specifies a fixed size 28 | buffer to be contained in each space. Each space has a use count, which 29 | when decremented to zero returns the space to the pool. If a space is 30 | requested from the pool and the pool is empty, a space is immediately 31 | created unless a specified limit on the number of spaces has been reached. 32 | Only if the limit is reached will it wait for a space to be returned to the 33 | pool. Each space knows what pool it belongs to, so that it can be returned. 34 | */ 35 | 36 | #include "yarn.h" 37 | 38 | /* a space (one buffer for each space) */ 39 | typedef struct buffer_pool_space_t 40 | { 41 | lock *use; /* use count -- return to pool when zero */ 42 | void *buf; /* buffer of size pool->size */ 43 | size_t len; /* for application usage */ 44 | struct buffer_pool_t *pool; /* pool to return to */ 45 | struct buffer_pool_space_t *next; /* for pool linked list */ 46 | } buffer_pool_space_t; 47 | 48 | /* pool of spaces (one pool for each size needed) */ 49 | typedef struct buffer_pool_t 50 | { 51 | lock *have; /* unused spaces available, lock for list */ 52 | buffer_pool_space_t *head; /* linked list of available buffers */ 53 | size_t size; /* size of all buffers in this pool */ 54 | int limit; /* number of new spaces allowed, or -1 */ 55 | int made; /* number of buffers made */ 56 | } buffer_pool_t; 57 | 58 | /* initialize a pool (pool structure itself provided, not allocated) -- the 59 | limit is the maximum number of spaces in the pool, or -1 to indicate no 60 | limit, i.e., to never wait for a buffer to return to the pool */ 61 | void buffer_pool_create(buffer_pool_t *pool, size_t size, int limit); 62 | 63 | /* get a space from a pool -- the use count is initially set to one, so there 64 | is no need to call use_space() for the first use */ 65 | buffer_pool_space_t *buffer_pool_get_space(buffer_pool_t *pool); 66 | 67 | /* increment the use count to require one more drop before returning this space 68 | to the pool */ 69 | void buffer_pool_use_space(buffer_pool_space_t *space); 70 | 71 | /* drop a space, returning it to the pool if the use count is zero */ 72 | void buffer_pool_drop_space(buffer_pool_space_t *space); 73 | 74 | /* free the memory and lock resources of a pool -- return number of spaces for 75 | debugging and resource usage measurement */ 76 | int buffer_pool_free(buffer_pool_t *pool); 77 | 78 | #endif /* BUFFER_POOL_H_INCLUDED */ 79 | -------------------------------------------------------------------------------- /libs/libdstdec/ccp_calc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/ccp_calc.c -------------------------------------------------------------------------------- /libs/libdstdec/ccp_calc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/ccp_calc.h -------------------------------------------------------------------------------- /libs/libdstdec/conststr.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | MPEG-4 Audio RM Module 3 | Lossless coding of 1-bit oversampled audio - DST (Direct Stream Transfer) 4 | 5 | This software was originally developed by: 6 | 7 | * Aad Rijnberg 8 | Philips Digital Systems Laboratories Eindhoven 9 | 10 | 11 | * Fons Bruekers 12 | Philips Research Laboratories Eindhoven 13 | 14 | 15 | * Eric Knapen 16 | Philips Digital Systems Laboratories Eindhoven 17 | 18 | 19 | And edited by: 20 | 21 | * Richard Theelen 22 | Philips Digital Systems Laboratories Eindhoven 23 | 24 | 25 | in the course of development of the MPEG-4 Audio standard ISO-14496-1, 2 and 3. 26 | This software module is an implementation of a part of one or more MPEG-4 Audio 27 | tools as specified by the MPEG-4 Audio standard. ISO/IEC gives users of the 28 | MPEG-4 Audio standards free licence to this software module or modifications 29 | thereof for use in hardware or software products claiming conformance to the 30 | MPEG-4 Audio standards. Those intending to use this software module in hardware 31 | or software products are advised that this use may infringe existing patents. 32 | The original developers of this software of this module and their company, 33 | the subsequent editors and their companies, and ISO/EIC have no liability for 34 | use of this software module or modifications thereof in an implementation. 35 | Copyright is not released for non MPEG-4 Audio conforming products. The 36 | original developer retains full right to use this code for his/her own purpose, 37 | assign or donate the code to a third party and to inhibit third party from 38 | using the code for non MPEG-4 Audio conforming products. This copyright notice 39 | must be included in all copies of derivative works. 40 | 41 | Copyright 2004. 42 | 43 | Source file: conststr.h (Constants) 44 | 45 | Required libraries: 46 | 47 | Authors: 48 | RT: Richard Theelen, PDSL-labs Eindhoven 49 | 50 | Changes: 51 | 08-Mar-2004 RT Initial version 52 | 53 | ************************************************************************/ 54 | 55 | 56 | /****************************************************************************** 57 | * 58 | * Module : conststr.h 59 | * 60 | * Description : Constants 61 | * 62 | * Tools : MicroSoft Visual C++ 6.0 63 | * 64 | * Target Platform : WinNT, Win2000, WinXP 65 | * 66 | * Naming Conventions : 67 | * 68 | * 69 | * Copyright (C) Philips Electronics N.V. 2004 70 | * PDSL Eindhoven - the Netherlands 71 | * 72 | * All rights are reserved. Reproduction in whole or in part is 73 | * prohibited without the written consent of the copyright owner. 74 | * (template nr. CTV520-98-0003) 75 | ******************************************************************************/ 76 | 77 | 78 | #ifndef __CONSTSTR_H_INCLUDED 79 | #define __CONSTSTR_H_INCLUDED 80 | 81 | 82 | /*============================================================================*/ 83 | /* MACROS */ 84 | /*============================================================================*/ 85 | 86 | #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 87 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 88 | 89 | 90 | /*============================================================================*/ 91 | /* CONSTANTS */ 92 | /*============================================================================*/ 93 | 94 | #define RESOL 8 95 | #define SIZE_MAXFRAMELEN 4 /* Number of bits for representing framelength 96 | in the frame header */ 97 | #define SIZE_NROFCHANNELS 4 /* Number of bits for representing NrOfChannels 98 | in the frame header */ 99 | #define SIZE_DSTFRAMELEN 16 /* Number of bits for representing the DST 100 | framelength in bytes in the frameheader */ 101 | 102 | 103 | /* PREDICTION */ 104 | #define SIZE_CODEDPREDORDER 7 /* Number of bits in the stream for representing 105 | the "CodedPredOrder" in each frame */ 106 | #define SIZE_PREDCOEF 9 /* Number of bits in the stream for representing 107 | each filter coefficient in each frame */ 108 | 109 | /* ARITHMETIC CODING */ 110 | #define AC_BITS 8 /* Number of bits and maximum level for coding 111 | the probability */ 112 | #define AC_PROBS (1 << AC_BITS) 113 | #define AC_HISBITS 6 /* Number of entries in the histogram */ 114 | #define AC_HISMAX (1 << AC_HISBITS) 115 | #define AC_QSTEP (SIZE_PREDCOEF - AC_HISBITS) /* Quantization step 116 | for histogram */ 117 | 118 | /* RICE CODING OF PREDICTION COEFFICIENTS AND PTABLES */ 119 | #define NROFFRICEMETHODS 3 /* Number of different Pred. Methods for filters 120 | used in combination with Rice coding */ 121 | #define NROFPRICEMETHODS 3 /* Number of different Pred. Methods for Ptables 122 | used in combination with Rice coding */ 123 | #define MAXCPREDORDER 3 /* max pred.order for prediction of 124 | filter coefs / Ptables entries */ 125 | #define SIZE_RICEMETHOD 2 /* nr of bits in stream for indicating method */ 126 | #define SIZE_RICEM 3 /* nr of bits in stream for indicating m */ 127 | #define MAX_RICE_M_F 6 /* Max. value of m for filters */ 128 | #define MAX_RICE_M_P 4 /* Max. value of m for Ptables */ 129 | 130 | 131 | /* SEGMENTATION */ 132 | #define MAXNROF_FSEGS 4 /* max nr of segments per channel for filters */ 133 | #define MAXNROF_PSEGS 8 /* max nr of segments per channel for Ptables */ 134 | #define MIN_FSEG_LEN 1024 /* min segment length in bits of filters */ 135 | #define MIN_PSEG_LEN 32 /* min segment length in bits of Ptables */ 136 | 137 | /* DSTXBITS */ 138 | #define MAX_DSTXBITS_SIZE 256 139 | 140 | /* 64FS44 => 4704 */ 141 | /* 128FS44 => 9408 */ 142 | /* 256FS44 => 18816 */ 143 | #define MAX_DSDBYTES_INFRAME 18816 144 | 145 | #define MAX_CHANNELS 6 146 | #define MAX_DSDBITS_INFRAME (588 * 64) 147 | #define MAXNROF_SEGS 8 /* max nr of segments per channel for filters or Ptables */ 148 | 149 | enum DST_ErrorCodes 150 | { 151 | DSTErr_NoError = 0, 152 | DSTErr_NegativeBitAllocation, 153 | DSTErr_TooManySegments, 154 | DSTErr_InvalidSegmentResolution, 155 | DSTErr_InvalidSegmentLength, 156 | DSTErr_TooManyTables, 157 | DSTErr_InvalidTableNumber, 158 | DSTErr_InvalidChannelMapping, 159 | DSTErr_SegmentNumberMismatch, 160 | DSTErr_InvalidCoefficientCoding, 161 | DSTErr_InvalidCoefficientRange, 162 | DSTErr_InvalidPtableCoding, 163 | DSTErr_InvalidPtableRange, 164 | DSTErr_InvalidStuffingPattern, 165 | DSTErr_InvalidArithmeticCode, 166 | DSTErr_ArithmeticDecoder, 167 | DSTErr_MaxError, 168 | }; 169 | 170 | #endif /* __CONSTSTR_H_INCLUDED */ 171 | -------------------------------------------------------------------------------- /libs/libdstdec/dst_ac.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/dst_ac.c -------------------------------------------------------------------------------- /libs/libdstdec/dst_ac.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/dst_ac.h -------------------------------------------------------------------------------- /libs/libdstdec/dst_data.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | MPEG-4 Audio RM Module 3 | Lossless coding of 1-bit oversampled audio - DST (Direct Stream Transfer) 4 | 5 | This software was originally developed by: 6 | 7 | * Aad Rijnberg 8 | Philips Digital Systems Laboratories Eindhoven 9 | 10 | 11 | * Fons Bruekers 12 | Philips Research Laboratories Eindhoven 13 | 14 | 15 | * Eric Knapen 16 | Philips Digital Systems Laboratories Eindhoven 17 | 18 | 19 | And edited by: 20 | 21 | * Richard Theelen 22 | Philips Digital Systems Laboratories Eindhoven 23 | 24 | 25 | * Maxim Anisiutkin 26 | ICT Group 27 | 28 | 29 | in the course of development of the MPEG-4 Audio standard ISO-14496-1, 2 and 3. 30 | This software module is an implementation of a part of one or more MPEG-4 Audio 31 | tools as specified by the MPEG-4 Audio standard. ISO/IEC gives users of the 32 | MPEG-4 Audio standards free licence to this software module or modifications 33 | thereof for use in hardware or software products claiming conformance to the 34 | MPEG-4 Audio standards. Those intending to use this software module in hardware 35 | or software products are advised that this use may infringe existing patents. 36 | The original developers of this software of this module and their company, 37 | the subsequent editors and their companies, and ISO/EIC have no liability for 38 | use of this software module or modifications thereof in an implementation. 39 | Copyright is not released for non MPEG-4 Audio conforming products. The 40 | original developer retains full right to use this code for his/her own purpose, 41 | assign or donate the code to a third party and to inhibit third party from 42 | using the code for non MPEG-4 Audio conforming products. This copyright notice 43 | must be included in all copies of derivative works. 44 | 45 | Copyright 2004. 46 | 47 | Source file: DSTData.h (DSTData object) 48 | 49 | Required libraries: 50 | 51 | Authors: 52 | RT: Richard Theelen, PDSL-labs Eindhoven 53 | MA: Maxim Anisiutkin, ICT Group 54 | 55 | Changes: 56 | 08-Mar-2004 RT Initial version 57 | 29-Jun-2011 MA Modified to run in multithreaded environment 58 | 59 | ************************************************************************/ 60 | 61 | 62 | #if !defined(__DSTDATA_H_INCLUDED) 63 | #define __DSTDATA_H_INCLUDED 64 | 65 | /*============================================================================*/ 66 | /* INCLUDES */ 67 | /*============================================================================*/ 68 | 69 | #include "types.h" 70 | 71 | /*============================================================================*/ 72 | /* FUNCTION PROTOTYPES */ 73 | /*============================================================================*/ 74 | 75 | int GetDSTDataPointer (StrData* SD, uint8_t** pBuffer); 76 | int ResetReadingIndex (StrData* SD); 77 | int ReadNextBitFromBuffer (StrData* SD, uint8_t* pBit); 78 | int ReadNextNBitsFromBuffer(StrData* SD, int32_t* pBits, int32_t NrBits); 79 | int ReadNextByteFromBuffer (StrData* SD, uint8_t* pByte); 80 | 81 | int FillBuffer(StrData* SD, uint8_t* pBuf, int32_t Size); 82 | 83 | int FIO_BitGetChrUnsigned(StrData* SD, int Len, unsigned char *x); 84 | int FIO_BitGetIntUnsigned(StrData* SD, int Len, int *x); 85 | int FIO_BitGetIntSigned(StrData* SD, int Len, int *x); 86 | int FIO_BitGetShortSigned(StrData* SD, int Len, short *x); 87 | int get_in_bitcount(StrData* SD); 88 | 89 | int CreateBuffer(StrData* SD, int32_t Size); 90 | int DeleteBuffer(StrData* SD); 91 | 92 | 93 | #endif /* !defined(__DSTDATA_H_INCLUDED) */ 94 | 95 | -------------------------------------------------------------------------------- /libs/libdstdec/dst_decoder.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef DST_DECODER_H 23 | #define DST_DECODER_H 24 | 25 | #include 26 | 27 | typedef struct dst_decoder_s dst_decoder_t; 28 | typedef void (*frame_decoded_callback_t)(uint8_t* frame_data, size_t frame_size, void *userdata); 29 | typedef void (*frame_error_callback_t)(int frame_count, int frame_error_code, const char *frame_error_message, void *userdata); 30 | 31 | dst_decoder_t* dst_decoder_create(int channel_count, frame_decoded_callback_t frame_decoded_callback, frame_error_callback_t frame_error_callback, void *userdata); 32 | void dst_decoder_destroy(dst_decoder_t *dst_decoder); 33 | void dst_decoder_decode(dst_decoder_t *dst_decoder, uint8_t* frame_data, size_t frame_size); 34 | 35 | 36 | #endif /* DST_DECODER_H */ 37 | -------------------------------------------------------------------------------- /libs/libdstdec/dst_fram.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/dst_fram.c -------------------------------------------------------------------------------- /libs/libdstdec/dst_fram.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/dst_fram.h -------------------------------------------------------------------------------- /libs/libdstdec/dst_init.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/dst_init.c -------------------------------------------------------------------------------- /libs/libdstdec/dst_init.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/dst_init.h -------------------------------------------------------------------------------- /libs/libdstdec/types.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libdstdec/types.h -------------------------------------------------------------------------------- /libs/libdstdec/unpack_dst.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | MPEG-4 Audio RM Module 3 | Lossless coding of 1-bit oversampled audio - DST (Direct Stream Transfer) 4 | 5 | This software was originally developed by: 6 | 7 | * Aad Rijnberg 8 | Philips Digital Systems Laboratories Eindhoven 9 | 10 | 11 | * Fons Bruekers 12 | Philips Research Laboratories Eindhoven 13 | 14 | 15 | * Eric Knapen 16 | Philips Digital Systems Laboratories Eindhoven 17 | 18 | 19 | And edited by: 20 | 21 | * Richard Theelen 22 | Philips Digital Systems Laboratories Eindhoven 23 | 24 | 25 | in the course of development of the MPEG-4 Audio standard ISO-14496-1, 2 and 3. 26 | This software module is an implementation of a part of one or more MPEG-4 Audio 27 | tools as specified by the MPEG-4 Audio standard. ISO/IEC gives users of the 28 | MPEG-4 Audio standards free licence to this software module or modifications 29 | thereof for use in hardware or software products claiming conformance to the 30 | MPEG-4 Audio standards. Those intending to use this software module in hardware 31 | or software products are advised that this use may infringe existing patents. 32 | The original developers of this software of this module and their company, 33 | the subsequent editors and their companies, and ISO/EIC have no liability for 34 | use of this software module or modifications thereof in an implementation. 35 | Copyright is not released for non MPEG-4 Audio conforming products. The 36 | original developer retains full right to use this code for his/her own purpose, 37 | assign or donate the code to a third party and to inhibit third party from 38 | using the code for non MPEG-4 Audio conforming products. This copyright notice 39 | must be included in all copies of derivative works. 40 | 41 | Copyright 2004. 42 | 43 | Source file: UnpackDST.h (Unpacking DST Frame Data) 44 | 45 | Required libraries: 46 | 47 | Authors: 48 | RT: Richard Theelen, PDSL-labs Eindhoven 49 | 50 | Changes: 51 | 08-Mar-2004 RT Initial version 52 | 53 | ************************************************************************/ 54 | 55 | 56 | #if !defined(__UNPACKDST_H) 57 | #define __UNPACKDST_H 58 | 59 | 60 | /*============================================================================*/ 61 | /* INCLUDES */ 62 | /*============================================================================*/ 63 | 64 | #include "types.h" 65 | #include "dst_data.h" 66 | 67 | 68 | /*============================================================================*/ 69 | /* FUNCTION PROTOTYPES */ 70 | /*============================================================================*/ 71 | 72 | int UnpackDSTframe(ebunch* D, 73 | uint8_t* DSTdataframe, 74 | uint8_t* DSDdataframe); 75 | 76 | 77 | #endif /* __UNPACKDST_H */ 78 | -------------------------------------------------------------------------------- /libs/libdstdec/yarn.h: -------------------------------------------------------------------------------- 1 | /* yarn.h -- generic interface for thread operations 2 | * Copyright (C) 2008 Mark Adler 3 | * Version 1.1 26 Oct 2008 Mark Adler 4 | */ 5 | 6 | /* 7 | This software is provided 'as-is', without any express or implied 8 | warranty. In no event will the author be held liable for any damages 9 | arising from the use of this software. 10 | 11 | Permission is granted to anyone to use this software for any purpose, 12 | including commercial applications, and to alter it and redistribute it 13 | freely, subject to the following restrictions: 14 | 15 | 1. The origin of this software must not be misrepresented; you must not 16 | claim that you wrote the original software. If you use this software 17 | in a product, an acknowledgment in the product documentation would be 18 | appreciated but is not required. 19 | 2. Altered source versions must be plainly marked as such, and must not be 20 | misrepresented as being the original software. 21 | 3. This notice may not be removed or altered from any source distribution. 22 | 23 | Mark Adler 24 | madler@alumni.caltech.edu 25 | */ 26 | 27 | /* Basic thread operations 28 | 29 | This interface isolates the local operating system implementation of threads 30 | from the application in order to facilitate platform independent use of 31 | threads. All of the implementation details are deliberately hidden. 32 | 33 | Assuming adequate system resources and proper use, none of these functions 34 | can fail. As a result, any errors encountered will cause an exit() to be 35 | executed. 36 | 37 | These functions allow the simple launching and joining of threads, and the 38 | locking of objects and synchronization of changes of objects. The latter is 39 | implemented with a single lock type that contains an integer value. The 40 | value can be ignored for simple exclusive access to an object, or the value 41 | can be used to signal and wait for changes to an object. 42 | 43 | -- Arguments -- 44 | 45 | thread *thread; identifier for launched thread, used by join 46 | void probe(void *); pointer to function "probe", run when thread starts 47 | void *payload; single argument passed to the probe function 48 | lock *lock; a lock with a value -- used for exclusive access to 49 | an object and to synchronize threads waiting for 50 | changes to an object 51 | long val; value to set lock, increment lock, or wait for 52 | int n; number of threads joined 53 | 54 | -- Thread functions -- 55 | 56 | thread = launch(probe, payload) - launch a thread -- exit via probe() return 57 | join(thread) - join a thread and by joining end it, waiting for the thread 58 | to exit if it hasn't already -- will free the resources allocated by 59 | launch() (don't try to join the same thread more than once) 60 | n = join_all() - join all threads launched by launch() that are not joined 61 | yet and free the resources allocated by the launches, usually to clean 62 | up when the thread processing is done -- join_all() returns an int with 63 | the count of the number of threads joined (join_all() should only be 64 | called from the main thread, and should only be called after any calls 65 | of join() have completed) 66 | destruct(thread) - terminate the thread in mid-execution and join it 67 | (depending on the implementation, the termination may not be immediate, 68 | but may wait for the thread to execute certain thread or file i/o 69 | operations) 70 | 71 | -- Lock functions -- 72 | 73 | lock = new_lock(val) - create a new lock with initial value val (lock is 74 | created in the released state) 75 | possess(lock) - acquire exclusive possession of a lock, waiting if necessary 76 | twist(lock, [TO | BY], val) - set lock to or increment lock by val, signal 77 | all threads waiting on this lock and then release the lock -- must 78 | possess the lock before calling (twist releases, so don't do a 79 | release() after a twist() on the same lock) 80 | wait_for(lock, [TO_BE | NOT_TO_BE | TO_BE_MORE_THAN | TO_BE_LESS_THAN], val) 81 | - wait on lock value to be, not to be, be greater than, or be less than 82 | val -- must possess the lock before calling, will possess the lock on 83 | return but the lock is released while waiting to permit other threads 84 | to use twist() to change the value and signal the change (so make sure 85 | that the object is in a usable state when waiting) 86 | release(lock) - release a possessed lock (do not try to release a lock that 87 | the current thread does not possess) 88 | val = peek_lock(lock) - return the value of the lock (assumes that lock is 89 | already possessed, no possess or release is done by peek_lock()) 90 | free_lock(lock) - free the resources allocated by new_lock() (application 91 | must assure that the lock is released before calling free_lock()) 92 | 93 | -- Memory allocation --- 94 | 95 | yarn_mem(better_malloc, better_free) - set the memory allocation and free 96 | routines for use by the yarn routines where the supplied routines have 97 | the same interface and operation as malloc() and free(), and may be 98 | provided in order to supply thread-safe memory allocation routines or 99 | for any other reason -- by default malloc() and free() will be used 100 | 101 | -- Error control -- 102 | 103 | yarn_name - a char pointer to a string that will be the prefix for any error 104 | messages that these routines generate before exiting -- if not changed 105 | by the application, "yarn" will be used 106 | yarn_abort - an external function that will be executed when there is an 107 | internal yarn error, due to out of memory or misuse -- this function 108 | may exit to abort the application, or if it returns, the yarn error 109 | handler will exit (set to NULL by default for no action) 110 | */ 111 | 112 | #ifndef YARN_H_INCLUDED 113 | #define YARN_H_INCLUDED 114 | 115 | #include 116 | 117 | extern char *yarn_prefix; 118 | extern void (*yarn_abort)(int); 119 | 120 | void yarn_mem(void *(*)(size_t), void (*)(void *)); 121 | 122 | typedef struct thread_s thread; 123 | thread *launch(void (*)(void *), void *); 124 | void join(thread *); 125 | int join_all(void); 126 | void destruct(thread *); 127 | 128 | typedef struct lock_s lock; 129 | lock *new_lock(long); 130 | void possess(lock *); 131 | void release(lock *); 132 | enum twist_op { TO, BY }; 133 | void twist(lock *, enum twist_op, long); 134 | enum wait_op { 135 | TO_BE, /* or */ NOT_TO_BE, /* that is the question */ 136 | TO_BE_MORE_THAN, TO_BE_LESS_THAN }; 137 | void wait_for(lock *, enum wait_op, long); 138 | long peek_lock(lock *); 139 | void free_lock(lock *); 140 | 141 | #endif /* YARN_H_INCLUDED */ 142 | -------------------------------------------------------------------------------- /libs/libid3/id3_frame_content.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1999, 2002, Espen Skoglund 3 | * Copyright (C) 2000 - 2004 Haavard Kvaalen 4 | * 5 | * $Id: id3_frame_content.c,v 1.15 2007/07/05 13:59:48 shd Exp $ 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | */ 21 | #include 22 | #include 23 | #include 24 | 25 | #include "id3.h" 26 | 27 | #if 0 28 | 29 | enum { 30 | CTYPE_NUM, 31 | CTYPE_STR, 32 | }; 33 | 34 | struct element { 35 | int type; 36 | union { 37 | int num; 38 | char *str; 39 | } c; 40 | }; 41 | 42 | static GSList* push_element(GSList *l, int num, char *str) 43 | { 44 | struct element *elem = malloc(sizeof (struct element)); 45 | 46 | if (num != -1) 47 | { 48 | elem->type = CTYPE_NUM; 49 | elem->c.num = num; 50 | } 51 | else 52 | { 53 | elem->type = CTYPE_STR; 54 | elem->c.str = strdup(str); 55 | } 56 | return g_slist_prepend(l, elem); 57 | } 58 | 59 | static char *pop_element(GSList **l) 60 | { 61 | struct element *elem = (*l)->data; 62 | GSList *tmp; 63 | char *ret; 64 | 65 | if (elem->type == CTYPE_NUM) 66 | ret = strdup(mpg123_get_id3_genre(elem->c.num)); 67 | else 68 | ret = elem->c.str; 69 | 70 | /* Remove link */ 71 | tmp = *l; 72 | *l = g_slist_remove_link(*l, *l); 73 | g_slist_free_1(tmp); 74 | return ret; 75 | } 76 | 77 | static GSList* id3_get_content_v23(struct id3_frame *frame) 78 | { 79 | char *input, *ptr; 80 | GSList *list = NULL; 81 | 82 | input = id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), 83 | ID3_TEXT_FRAME_PTR(frame)); 84 | 85 | if (!input) 86 | return NULL; 87 | 88 | ptr = input; 89 | while (ptr[0] == '(' && ptr[1] != '(') 90 | { 91 | if (!strchr(ptr, ')')) 92 | break; 93 | 94 | if (strncmp(ptr, "(RX)", 4) == 0) 95 | { 96 | list = push_element(list, -1, _("Remix")); 97 | ptr += 4; 98 | } 99 | else if (strncmp(ptr, "(CR)", 4) == 0) 100 | { 101 | list = push_element(list, -1, _("Cover")); 102 | ptr += 4; 103 | } 104 | else 105 | { 106 | /* Get ID3v1 genre number */ 107 | int num; 108 | char *endptr; 109 | num = strtol(ptr + 1, &endptr, 10); 110 | if (*endptr == ')' && num >= 0 && num <= 255) 111 | { 112 | list = push_element(list, num, NULL); 113 | ptr = endptr + 1; 114 | } 115 | else if (*endptr == ')') 116 | ptr = endptr + 1; 117 | else 118 | break; 119 | } 120 | } 121 | 122 | if (*ptr == 0) { 123 | /* Unexpected end of ID */ 124 | g_slist_free(list); 125 | free(input); 126 | return NULL; 127 | } 128 | 129 | /* 130 | * Add plaintext refinement. 131 | */ 132 | if (strncmp(ptr, "((", 2)) 133 | ptr++; 134 | list = push_element(list, -1, ptr); 135 | free(input); 136 | 137 | return list; 138 | } 139 | 140 | static GSList* id3_get_content_v24(struct id3_frame *frame) 141 | { 142 | GSList *list = NULL; 143 | int offset = 0; 144 | 145 | while (offset < frame->fr_size - 1) 146 | { 147 | int num; 148 | char *input, *endptr; 149 | 150 | input = id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), 151 | ID3_TEXT_FRAME_PTR(frame) + offset); 152 | 153 | if (!input) 154 | break; 155 | 156 | /* Get ID3v1 genre number */ 157 | num = strtol(input, &endptr, 10); 158 | if (endptr && endptr != input && *endptr == '\0' && 159 | num >= 0 && num < 256) 160 | list = push_element(list, num, NULL); 161 | else if (!strcmp(input, "RX")) 162 | list = push_element(list, -1, _("Remix")); 163 | else if (!strcmp(input, "CR")) 164 | list = push_element(list, -1, _("Cover")); 165 | else 166 | list = push_element(list, -1, input); 167 | 168 | offset += id3_string_size(ID3_TEXT_FRAME_ENCODING(frame), 169 | ID3_TEXT_FRAME_PTR(frame) + offset); 170 | } 171 | 172 | return list; 173 | } 174 | 175 | /* 176 | * Function id3_get_content (frame) 177 | * 178 | * Expand content type string of frame and return it. Return NULL 179 | * upon error. 180 | * 181 | */ 182 | char *id3_get_content(struct id3_frame *frame) 183 | { 184 | GSList *list; 185 | char **str_array, *ret; 186 | int len; 187 | 188 | if (frame->fr_desc->fd_id == ID3_TCON 189 | return NULL; 190 | 191 | /* Check if frame is compressed */ 192 | if (id3_decompress_frame(frame) == -1) 193 | return NULL; 194 | 195 | if (frame->fr_owner->id3_version == 3) 196 | list = id3_get_content_v23(frame); 197 | else 198 | list = id3_get_content_v24(frame); 199 | 200 | len = g_slist_length(list); 201 | 202 | if (len == 0) 203 | return strdup(""); 204 | 205 | str_array = calloc(sizeof (char *) * (len + 1), 1); 206 | 207 | while (len-- && list) 208 | str_array[len] = pop_element(&list); 209 | 210 | if (len != -1 || list) 211 | fprintf(stderr, "len: %d; list: %p", len, list); 212 | 213 | ret = g_strjoinv(", ", str_array); 214 | g_strfreev(str_array); 215 | 216 | return ret; 217 | } 218 | 219 | #endif -------------------------------------------------------------------------------- /libs/libid3/id3_frame_url.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1999, 2001, 2002 Espen Skoglund 3 | * Copyright (C) 2000 - 2004 Haavard Kvaalen 4 | * 5 | * $Id: id3_frame_url.c,v 1.9 2004/04/04 16:14:31 havard Exp $ 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | */ 21 | #include 22 | 23 | #include "id3.h" 24 | #include "id3_header.h" 25 | 26 | /* 27 | * Function id3_get_url (frame) 28 | * 29 | * Return URL of frame. 30 | * 31 | */ 32 | char *id3_get_url(struct id3_frame *frame) 33 | { 34 | int offset = 0; 35 | /* Type check */ 36 | if (frame->fr_desc->fd_idstr[0] != 'W') 37 | return NULL; 38 | 39 | /* Check if frame is compressed */ 40 | if (id3_decompress_frame(frame) == -1) 41 | return NULL; 42 | 43 | if (frame->fr_desc->fd_id == ID3_WXXX) 44 | { 45 | /* 46 | * This is a user defined link frame. Skip the description. 47 | */ 48 | offset = id3_string_size(ID3_TEXT_FRAME_ENCODING(frame), 49 | ID3_TEXT_FRAME_PTR(frame)); 50 | if (offset >= frame->fr_size) 51 | return NULL; 52 | } 53 | 54 | return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), 55 | ID3_TEXT_FRAME_PTR(frame) + offset); 56 | } 57 | 58 | /* 59 | * Function id3_get_url_desc (frame) 60 | * 61 | * Get description of a URL. 62 | * 63 | */ 64 | char *id3_get_url_desc(struct id3_frame *frame) 65 | { 66 | /* Type check */ 67 | if (frame->fr_desc->fd_idstr[0] != 'W') 68 | return NULL; 69 | 70 | /* If predefined link frame, return description. */ 71 | if (frame->fr_desc->fd_id != ID3_WXXX) 72 | return frame->fr_desc->fd_description; 73 | 74 | /* Check if frame is compressed */ 75 | if (id3_decompress_frame(frame) == -1) 76 | return NULL; 77 | 78 | return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), 79 | ID3_TEXT_FRAME_PTR(frame)); 80 | } 81 | -------------------------------------------------------------------------------- /libs/libid3/id3_header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1998, 1999, Espen Skoglund 3 | * Copyright (C) 2000-2004 Haavard Kvaalen 4 | * 5 | * $Id: id3_header.h,v 1.7 2004/04/04 16:14:31 havard Exp $ 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | */ 21 | #ifndef ID3_HEADER_H 22 | #define ID3_HEADER_H 23 | 24 | /* 25 | * Layout for the ID3 tag header. 26 | */ 27 | #if 0 28 | struct id3_taghdr { 29 | uint8_t th_version; 30 | uint8_t th_revision; 31 | uint8_t th_flags; 32 | uint32_t th_size; 33 | }; 34 | #endif 35 | 36 | /* Header size excluding "ID3" */ 37 | #define ID3_TAGHDR_SIZE 7 /* Size on disk */ 38 | 39 | #define ID3_THFLAG_USYNC 0x80 40 | #define ID3_THFLAG_EXT 0x40 41 | #define ID3_THFLAG_EXP 0x20 42 | 43 | #define ID3_SET_SIZE28(size, a, b, c, d) \ 44 | do { \ 45 | a = ((size & 0x800000) >> 23) | (((size & 0x7f000000) >> 24) << 1); \ 46 | b = ((size & 0x8000) >> 15) | (((size & 0x7f0000) >> 16) << 1); \ 47 | c = ((size & 0x80) >> 7) | (((size & 0x7f00) >> 8) << 1); \ 48 | d = (size & 0x7f); \ 49 | } while (0) 50 | 51 | #define ID3_GET_SIZE28(a, b, c, d) \ 52 | (((a & 0x7f) << (24 - 3)) | \ 53 | ((b & 0x7f) << (16 - 2)) | \ 54 | ((c & 0x7f) << ( 8 - 1)) | \ 55 | ((d & 0x7f))) 56 | 57 | 58 | 59 | /* 60 | * Layout for the extended header. 61 | */ 62 | #if 0 63 | struct id3_exthdr { 64 | uint32_t eh_size; 65 | uint16_t eh_flags; 66 | uint32_t eh_padsize; 67 | }; 68 | #endif 69 | 70 | #define ID3_EXTHDR_SIZE 10 71 | 72 | #define ID3_EHFLAG_V23_CRC 0x80 73 | #define ID3_EHFLAG_V24_CRC 0x20 74 | 75 | 76 | 77 | /* 78 | * Layout for the frame header. 79 | */ 80 | #if 0 81 | struct id3_framehdr { 82 | uint32_t fh_id; 83 | uint32_t fh_size; 84 | uint16_t fh_flags; 85 | }; 86 | #endif 87 | 88 | #define ID3_FRAMEHDR_SIZE 10 89 | 90 | 91 | #define ID3_FHFLAG_TAGALT 0x8000 92 | #define ID3_FHFLAG_FILEALT 0x4000 93 | #define ID3_FHFLAG_RO 0x2000 94 | #define ID3_FHFLAG_COMPRESS 0x0080 95 | #define ID3_FHFLAG_ENCRYPT 0x0040 96 | #define ID3_FHFLAG_GROUP 0x0020 97 | 98 | 99 | #define DEBUG_ID3 100 | #ifdef DEBUG_ID3 101 | #define id3_error(id3, error) \ 102 | (void) ( id3->id3_error_msg = error, \ 103 | printf( "Error %s, line %d: %s\n", __FILE__, __LINE__, error ) ) 104 | 105 | 106 | #else 107 | #define id3_error(id3, error) \ 108 | (void) ( id3->id3_error_msg = error ) 109 | 110 | #endif 111 | 112 | /* 113 | * Version 2.2.0 114 | */ 115 | 116 | /* 117 | * Layout for the frame header. 118 | */ 119 | #if 0 120 | struct id3_framehdr { 121 | char fh_id[3]; 122 | uint8_t fh_size[3]; 123 | }; 124 | #endif 125 | 126 | #define ID3_FRAMEHDR_SIZE_22 6 127 | 128 | #endif /* ID3_HEADER_H */ 129 | -------------------------------------------------------------------------------- /libs/libid3/id3_tag.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1999-2000, Espen Skoglund 3 | * Copyright (C) 2001 - 2004 Haavard Kvaalen 4 | * 5 | * $Id: id3_tag.c,v 1.9 2004/04/04 23:49:37 havard Exp $ 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | */ 21 | #include 22 | 23 | #include "id3.h" 24 | #include "id3_header.h" 25 | 26 | 27 | /* 28 | * Function id3_init_tag (id3) 29 | * 30 | * Initialize an empty ID3 tag. 31 | * 32 | */ 33 | void id3_init_tag(struct id3_tag *id3) 34 | { 35 | /* 36 | * Initialize header. 37 | */ 38 | id3->id3_version = 3; 39 | id3->id3_revision = 0; 40 | id3->id3_flags = 0; 41 | id3->id3_tagsize = 0; 42 | 43 | id3->id3_altered = 1; 44 | id3->id3_newtag = 1; 45 | id3->id3_pos = 0; 46 | 47 | /* 48 | * Initialize frames. 49 | */ 50 | INIT_LIST_HEAD(&id3->id3_frame); 51 | } 52 | 53 | 54 | /* 55 | * Function id3_read_tag (id3) 56 | * 57 | * Read the ID3 tag from the input stream. The start of the tag 58 | * must be positioned in the next tag in the stream. Return 0 upon 59 | * success, or -1 if an error occured. 60 | * 61 | */ 62 | int id3_read_tag(struct id3_tag *id3) 63 | { 64 | char *buf; 65 | 66 | /* 67 | * We know that the tag will be at least this big. 68 | * 69 | * tag header + "ID3" 70 | */ 71 | id3->id3_tagsize = ID3_TAGHDR_SIZE + 3; 72 | 73 | if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) 74 | { 75 | /* 76 | * Check if we have a valid ID3 tag. 77 | */ 78 | char *id = id3->id3_read(id3, NULL, 3); 79 | if (id == NULL) 80 | return -1; 81 | 82 | if (id[0] != 'I' || id[1] != 'D' || id[2] != '3') 83 | { 84 | /* 85 | * ID3 tag was not detected. 86 | */ 87 | id3->id3_seek(id3, -3); 88 | return -1; 89 | } 90 | } 91 | 92 | /* 93 | * Read ID3 tag-header. 94 | */ 95 | buf = id3->id3_read(id3, NULL, ID3_TAGHDR_SIZE); 96 | if (buf == NULL) 97 | return -1; 98 | 99 | id3->id3_version = buf[0]; 100 | id3->id3_revision = buf[1]; 101 | id3->id3_flags = buf[2]; 102 | id3->id3_tagsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); 103 | id3->id3_newtag = 0; 104 | id3->id3_pos = 0; 105 | 106 | if (id3->id3_version < 2 || id3->id3_version > 4) 107 | return -1; 108 | 109 | /* 110 | * Parse extended header. 111 | */ 112 | if (id3->id3_flags & ID3_THFLAG_EXT) 113 | { 114 | buf = id3->id3_read(id3, NULL, ID3_EXTHDR_SIZE); 115 | if (buf == NULL) 116 | return -1; 117 | } 118 | 119 | /* 120 | * Parse frames. 121 | */ 122 | while (id3->id3_pos < id3->id3_tagsize) 123 | { 124 | if (id3_read_frame(id3) == -1) 125 | return -1; 126 | } 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /libs/libid3/unicode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004 Haavard Kvaalen 3 | * 4 | * Licensed under GNU GPL version 2. 5 | * 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | #include "charset.h" 12 | 13 | static size_t utf16_strlen(const unsigned char *string) 14 | { 15 | size_t len = 0; 16 | 17 | while (*(string + len) != 0 || *(string + len + 1) != 0) 18 | len += 2; 19 | 20 | return len; 21 | } 22 | 23 | #ifdef HAVE_ICONV 24 | 25 | char *convert_from_utf16(const unsigned char *utf16) 26 | { 27 | return charset_convert(utf16, utf16_strlen(utf16), "UTF-16", NULL); 28 | } 29 | 30 | char *convert_from_utf16be(const unsigned char *utf16) 31 | { 32 | return charset_convert(utf16, utf16_strlen(utf16), "UTF-16BE", NULL); 33 | } 34 | 35 | 36 | #else 37 | 38 | 39 | static char* to_ascii(const unsigned char *utf16, int le) 40 | { 41 | char *ascii; 42 | unsigned int i, len, c; 43 | 44 | len = utf16_strlen(utf16) / 2 + 1; 45 | 46 | ascii = malloc(len + 1); 47 | 48 | for (i = 0, c = 0; i < len; i++) 49 | { 50 | uint16_t uc; 51 | int o = i << 1; 52 | 53 | if (le) 54 | uc = *(utf16 + o) | *(utf16 + o + 1) << 8; 55 | else 56 | uc = *(utf16 + o) << 8 | *(utf16 + o + 1); 57 | 58 | /* Skip BOM and surrogate pairs */ 59 | if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) 60 | continue; 61 | 62 | if (uc < 0x80) 63 | ascii[c] = (uint8_t) uc; 64 | else 65 | ascii[c] = '?'; 66 | c++; 67 | } 68 | 69 | ascii[c] = 0; 70 | return ascii; 71 | } 72 | 73 | char *convert_from_utf16(const unsigned char *utf16) 74 | { 75 | int le = 0; 76 | uint16_t bom = *utf16 << 8 | *(utf16 + 1); 77 | 78 | if (bom == 0xfffe) 79 | le = 1; 80 | else if (bom != 0xfeff) 81 | return strdup(""); 82 | 83 | return to_ascii(utf16, le); 84 | } 85 | 86 | char *convert_from_utf16be(const unsigned char *utf16) 87 | { 88 | return to_ascii(utf16, 0); 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /libs/libsacd/cuesheet.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "cuesheet.h" 35 | 36 | static char *cue_escape(const char *src) 37 | { 38 | static char ret[512]; 39 | char *s = str_replace(src, "\"", "\\\""); 40 | strcpy(ret, s); 41 | free(s); 42 | trim_whitespace(ret); 43 | return ret; 44 | } 45 | 46 | int write_cue_sheet(scarletbook_handle_t *handle, const char *filename, int area, char *cue_filename) 47 | { 48 | FILE *fd; 49 | 50 | #ifdef _WIN32 51 | { 52 | wchar_t *wide_filename = (wchar_t *) charset_convert(cue_filename, strlen(cue_filename), "UTF-8", "UCS-2-INTERNAL"); 53 | fd = _wfopen(wide_filename, L"wb"); 54 | free(wide_filename); 55 | } 56 | #else 57 | fd = fopen(cue_filename, "wb"); 58 | #endif 59 | if (fd == 0) 60 | { 61 | return -1; 62 | } 63 | 64 | // Write UTF-8 BOM 65 | fputc(0xef, fd); 66 | fputc(0xbb, fd); 67 | fputc(0xbf, fd); 68 | fprintf(fd, "\nREM File created by SACD Extract, version: " SACD_RIPPER_VERSION_STRING "\n"); 69 | 70 | if (handle->master_toc->disc_genre[0].genre > 0) 71 | { 72 | fprintf(fd, "REM GENRE %s\n", album_genre[handle->master_toc->disc_genre[0].genre]); 73 | } 74 | 75 | if (handle->master_toc->disc_date_year) 76 | { 77 | fprintf(fd, "REM DATE %04d-%02d-%02d\n", handle->master_toc->disc_date_year 78 | , handle->master_toc->disc_date_month 79 | , handle->master_toc->disc_date_day); 80 | } 81 | 82 | if (handle->master_text.disc_artist) 83 | { 84 | fprintf(fd, "PERFORMER \"%s\"\n", cue_escape(handle->master_text.disc_artist)); 85 | } 86 | 87 | if (handle->master_text.disc_title) 88 | { 89 | fprintf(fd, "TITLE \"%s\"\n", cue_escape(handle->master_text.disc_title)); 90 | } 91 | 92 | if (strlen(handle->master_toc->disc_catalog_number) > 0) 93 | { 94 | fprintf(fd, "CATALOG %s\n", cue_escape(substr(handle->master_toc->disc_catalog_number, 0, 16))); 95 | } 96 | 97 | fprintf(fd, "FILE \"%s\" WAVE\n", cue_escape(filename)); 98 | { 99 | int track, track_count = handle->area[area].area_toc->track_count; 100 | uint64_t prev_abs_end = 0; 101 | 102 | for (track = 0; track < track_count; track++) 103 | { 104 | area_tracklist_time_t *time = &handle->area[area].area_tracklist_time->start[track]; 105 | 106 | fprintf(fd, " TRACK %02d AUDIO\n", track + 1); 107 | 108 | if (handle->area[area].area_track_text[track].track_type_title) 109 | { 110 | fprintf(fd, " TITLE \"%s\"\n", cue_escape(handle->area[area].area_track_text[track].track_type_title)); 111 | } 112 | 113 | if (handle->area[area].area_track_text[track].track_type_performer) 114 | { 115 | fprintf(fd, " PERFORMER \"%s\"\n", cue_escape(handle->area[area].area_track_text[track].track_type_performer)); 116 | } 117 | 118 | if (*handle->area[area].area_isrc_genre->isrc[track].country_code) 119 | { 120 | fprintf(fd, " ISRC %s\n", cue_escape(substr(handle->area[area].area_isrc_genre->isrc[track].country_code, 0, 12))); 121 | } 122 | 123 | if ((uint64_t) TIME_FRAMECOUNT(&handle->area[area].area_tracklist_time->start[track]) > prev_abs_end) 124 | { 125 | int prev_sec = (int) (prev_abs_end / SACD_FRAME_RATE); 126 | 127 | fprintf(fd, " INDEX 00 %02d:%02d:%02d\n", prev_sec / 60, (int) prev_sec % 60, (int) prev_abs_end % SACD_FRAME_RATE); 128 | fprintf(fd, " INDEX 01 %02d:%02d:%02d\n", time->minutes, time->seconds, time->frames); 129 | } 130 | else 131 | { 132 | fprintf(fd, " INDEX 01 %02d:%02d:%02d\n", time->minutes, time->seconds, time->frames); 133 | } 134 | 135 | prev_abs_end = TIME_FRAMECOUNT(&handle->area[area].area_tracklist_time->start[track]) + 136 | TIME_FRAMECOUNT(&handle->area[area].area_tracklist_time->duration[track]); 137 | } 138 | } 139 | 140 | fclose(fd); 141 | 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /libs/libsacd/cuesheet.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __CUESHEET_H__ 23 | #define __CUESHEET_H__ 24 | 25 | #include "scarletbook.h" 26 | 27 | int write_cue_sheet(scarletbook_handle_t *, const char *, int, char *); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /libs/libsacd/dsdiff.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/setmind/sacd-ripper/58db5f16fcf410ae4d6aeca226a067b37ade136a/libs/libsacd/dsdiff.h -------------------------------------------------------------------------------- /libs/libsacd/dsf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef DSF_H_INCLUDED 23 | #define DSF_H_INCLUDED 24 | 25 | #include 26 | #include "endianess.h" 27 | 28 | #undef ATTRIBUTE_PACKED 29 | #undef PRAGMA_PACK_BEGIN 30 | #undef PRAGMA_PACK_END 31 | 32 | #if defined(__GNUC__) && !defined(__MINGW32__) 33 | #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) 34 | #define ATTRIBUTE_PACKED __attribute__ ((packed)) 35 | #define PRAGMA_PACK 0 36 | #endif 37 | #endif 38 | 39 | /** 40 | * A first year Sony intern must have come up with this format! it's so badly put together 41 | * that I should actually not have written this code in the first place.. 42 | */ 43 | 44 | #if !defined(ATTRIBUTE_PACKED) 45 | #define ATTRIBUTE_PACKED 46 | #define PRAGMA_PACK 1 47 | #endif 48 | 49 | #define DSD_MARKER (MAKE_MARKER('D', 'S', 'D', ' ')) // DSD Chunk Header 50 | #define FMT_MARKER (MAKE_MARKER('f', 'm', 't', ' ')) // fmt chunkheader 51 | #define DATA_MARKER (MAKE_MARKER('d', 'a', 't', 'a')) // data chunkheader 52 | 53 | #define DSF_VERSION 1 54 | 55 | #define FORMAT_ID_DSD 0 56 | 57 | // Audiogate cannot deal with "regular" DSD stored as MSB and 1 byte per channel so we do the 58 | // LSB conversion and set the blocksize to 4096, argh.. 59 | 60 | #define SACD_BLOCK_SIZE_PER_CHANNEL 4096 // 4096 bytes per channel 61 | #define SACD_BITS_PER_SAMPLE 1 // LSB 62 | 63 | enum 64 | { 65 | CHANNEL_TYPE_MONO = 1, 66 | CHANNEL_TYPE_STEREO = 2, 67 | CHANNEL_TYPE_3_CHANNELS = 3, 68 | CHANNEL_TYPE_QUAD = 4, 69 | CHANNEL_TYPE_4_CHANNELS = 5, 70 | CHANNEL_TYPE_5_CHANNELS = 6, 71 | CHANNEL_TYPE_5_1_CHANNELS = 7 72 | }; 73 | 74 | #if PRAGMA_PACK 75 | #pragma pack(1) 76 | #endif 77 | 78 | struct dsd_chunk_header_t 79 | { 80 | uint32_t chunk_id; 81 | 82 | uint64_t chunk_data_size; 83 | 84 | uint64_t total_file_size; 85 | 86 | uint64_t metadata_offset; 87 | 88 | } ATTRIBUTE_PACKED; 89 | typedef struct dsd_chunk_header_t dsd_chunk_header_t; 90 | #define DSD_CHUNK_HEADER_SIZE 28U 91 | 92 | struct fmt_chunk_t 93 | { 94 | uint32_t chunk_id; 95 | 96 | uint64_t chunk_data_size; 97 | 98 | uint32_t version; 99 | 100 | uint32_t format_id; 101 | 102 | uint32_t channel_type; 103 | 104 | uint32_t channel_count; 105 | 106 | uint32_t sample_frequency; 107 | 108 | uint32_t bits_per_sample; 109 | 110 | uint64_t sample_count; 111 | 112 | uint32_t block_size_per_channel; 113 | 114 | uint32_t reserved; 115 | 116 | } ATTRIBUTE_PACKED; 117 | typedef struct fmt_chunk_t fmt_chunk_t; 118 | #define FMT_CHUNK_SIZE 52U 119 | 120 | struct data_chunk_t 121 | { 122 | uint32_t chunk_id; 123 | 124 | uint64_t chunk_data_size; 125 | 126 | uint8_t data[]; 127 | } ATTRIBUTE_PACKED; 128 | typedef struct data_chunk_t data_chunk_t; 129 | #define DATA_CHUNK_SIZE 12U 130 | 131 | #if PRAGMA_PACK 132 | #pragma pack() 133 | #endif 134 | 135 | #endif /* DSF_H_INCLUDED */ 136 | -------------------------------------------------------------------------------- /libs/libsacd/dst_decoder_ps3.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __DST_DECODER_PS3_H__ 23 | #define __DST_DECODER_PS3_H__ 24 | 25 | #ifdef __lv2ppu__ 26 | 27 | #include 28 | 29 | typedef void (*frame_decoded_callback_t)(uint8_t* frame_data, size_t frame_size, void *userdata); 30 | typedef void (*frame_error_callback_t)(int frame_count, int frame_error_code, const char *frame_error_message, void *userdata); 31 | typedef struct dst_decoder_thread_s *dst_decoder_thread_t; 32 | 33 | #define NUM_DST_DECODERS 5 /* The number of DST decoders (SPUs) */ 34 | 35 | typedef struct dst_decoder_t 36 | { 37 | sys_event_queue_t recv_queue; 38 | 39 | int event_count; 40 | 41 | int channel_count; 42 | 43 | dst_decoder_thread_t decoder[NUM_DST_DECODERS]; 44 | 45 | uint8_t *dsd_data; 46 | 47 | frame_decoded_callback_t frame_decoded_callback; 48 | frame_error_callback_t frame_error_callback; 49 | void *userdata; 50 | } 51 | dst_decoder_t; 52 | 53 | dst_decoder_t* dst_decoder_create(int channel_count, frame_decoded_callback_t frame_decoded_callback, frame_error_callback_t frame_error_callback, void *userdata); 54 | int dst_decoder_destroy(dst_decoder_t *dst_decoder); 55 | int dst_decoder_decode(dst_decoder_t *dst_decoder, uint8_t* frame_data, size_t frame_size); 56 | 57 | #endif 58 | 59 | #endif /* __DST_DECODER_H__ */ 60 | -------------------------------------------------------------------------------- /libs/libsacd/endianess.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef ENDIANESS_H_INCLUDED 23 | #define ENDIANESS_H_INCLUDED 24 | 25 | #if defined(__BIG_ENDIAN__) 26 | 27 | /* All bigendian systems are fine, just ignore the swaps. */ 28 | #define SWAP16(x) (void) (x) 29 | #define SWAP32(x) (void) (x) 30 | #define SWAP64(x) (void) (x) 31 | 32 | #define hton16(x) (uint16_t) (x) 33 | #define hton32(x) (uint32_t) (x) 34 | #define hton64(x) (uint64_t) (x) 35 | 36 | #define htole16(x) \ 37 | ((((x) & 0xff00) >> 8) | \ 38 | (((x) & 0x00ff) << 8)) 39 | #define htole32(x) \ 40 | ((((x) & 0xff000000) >> 24) | \ 41 | (((x) & 0x00ff0000) >> 8) | \ 42 | (((x) & 0x0000ff00) << 8) | \ 43 | (((x) & 0x000000ff) << 24)) 44 | #define htole64(x) \ 45 | ((((x) & 0xff00000000000000ULL) >> 56) | \ 46 | (((x) & 0x00ff000000000000ULL) >> 40) | \ 47 | (((x) & 0x0000ff0000000000ULL) >> 24) | \ 48 | (((x) & 0x000000ff00000000ULL) >> 8) | \ 49 | (((x) & 0x00000000ff000000ULL) << 8) | \ 50 | (((x) & 0x0000000000ff0000ULL) << 24) | \ 51 | (((x) & 0x000000000000ff00ULL) << 40) | \ 52 | (((x) & 0x00000000000000ffULL) << 56)) 53 | 54 | #define MAKE_MARKER(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 55 | 56 | #else 57 | 58 | #define MAKE_MARKER(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) 59 | 60 | /* For __FreeBSD_version */ 61 | #if defined(HAVE_SYS_PARAM_H) 62 | #include 63 | #endif 64 | 65 | #if defined(__linux__) || defined(__GLIBC__) 66 | #include 67 | #define SWAP16(x) x = bswap_16(x) 68 | #define SWAP32(x) x = bswap_32(x) 69 | #define SWAP64(x) x = bswap_64(x) 70 | #define hton16(x) bswap_16(x) 71 | #define hton32(x) bswap_32(x) 72 | #define hton64(x) bswap_64(x) 73 | 74 | #elif defined(__APPLE__) 75 | #include 76 | #define SWAP16(x) x = OSSwapBigToHostInt16(x) 77 | #define SWAP32(x) x = OSSwapBigToHostInt32(x) 78 | #define SWAP64(x) x = OSSwapBigToHostInt64(x) 79 | #define hton16(x) OSSwapBigToHostInt16(x) 80 | #define hton32(x) OSSwapBigToHostInt32(x) 81 | #define hton64(x) OSSwapBigToHostInt64(x) 82 | 83 | #elif defined(__NetBSD__) 84 | #include 85 | #define SWAP16(x) BE16TOH(x) 86 | #define SWAP32(x) BE32TOH(x) 87 | #define SWAP64(x) BE64TOH(x) 88 | #define hton16(x) BE16TOH(x) 89 | #define hton32(x) BE32TOH(x) 90 | #define hton64(x) BE64TOH(x) 91 | 92 | #elif defined(__OpenBSD__) 93 | #include 94 | #define SWAP16(x) x = swap16(x) 95 | #define SWAP32(x) x = swap32(x) 96 | #define SWAP64(x) x = swap64(x) 97 | #define hton16(x) swap16(x) 98 | #define hton32(x) swap32(x) 99 | #define hton64(x) swap64(x) 100 | 101 | #elif defined(__FreeBSD__) && __FreeBSD_version >= 470000 102 | #include 103 | #define SWAP16(x) x = be16toh(x) 104 | #define SWAP32(x) x = be32toh(x) 105 | #define SWAP64(x) x = be64toh(x) 106 | #define hton16(x) be16toh(x) 107 | #define hton32(x) be32toh(x) 108 | #define hton64(x) be64toh(x) 109 | 110 | /* This is a slow but portable implementation, it has multiple evaluation 111 | * problems so beware. 112 | * Old FreeBSD's and Solaris don't have or any other such 113 | * functionality! 114 | */ 115 | 116 | #elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defined(WIN32) || defined(__CYGWIN__) || defined(__BEOS__) 117 | #define hton16(x) \ 118 | ((((x) & 0xff00) >> 8) | \ 119 | (((x) & 0x00ff) << 8)) 120 | #define hton32(x) \ 121 | ((((x) & 0xff000000) >> 24) | \ 122 | (((x) & 0x00ff0000) >> 8) | \ 123 | (((x) & 0x0000ff00) << 8) | \ 124 | (((x) & 0x000000ff) << 24)) 125 | #define hton64(x) \ 126 | ((((x) & 0xff00000000000000ULL) >> 56) | \ 127 | (((x) & 0x00ff000000000000ULL) >> 40) | \ 128 | (((x) & 0x0000ff0000000000ULL) >> 24) | \ 129 | (((x) & 0x000000ff00000000ULL) >> 8) | \ 130 | (((x) & 0x00000000ff000000ULL) << 8) | \ 131 | (((x) & 0x0000000000ff0000ULL) << 24) | \ 132 | (((x) & 0x000000000000ff00ULL) << 40) | \ 133 | (((x) & 0x00000000000000ffULL) << 56)) 134 | 135 | #define SWAP16(x) x = (hton16(x)) 136 | #define SWAP32(x) x = (hton32(x)) 137 | #define SWAP64(x) x = (hton64(x)) 138 | 139 | #else 140 | 141 | /* If there isn't a header provided with your system with this functionality 142 | * add the relevant || define( ) to the portable implementation above. 143 | */ 144 | #error "You need to add endian swap macros for you're system" 145 | 146 | #endif 147 | 148 | #endif /* __BIG_ENDIAN__ */ 149 | 150 | #ifndef __BIG_ENDIAN__ 151 | 152 | #ifndef htole16 153 | #define htole16(x) (uint16_t) (x) 154 | #endif 155 | #ifndef htole32 156 | #define htole32(x) (uint32_t) (x) 157 | #endif 158 | #ifndef htole64 159 | #define htole64(x) (uint64_t) (x) 160 | #endif 161 | 162 | #endif 163 | 164 | #endif /* ENDIANESS_H_INCLUDED */ 165 | -------------------------------------------------------------------------------- /libs/libsacd/ioctl.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifdef __lv2ppu__ 23 | 24 | #include 25 | #include "ioctl.h" 26 | 27 | int ioctl_eject(int fd) 28 | { 29 | int res; 30 | struct lv2_atapi_cmnd_block atapi_cmnd; 31 | 32 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0, ATAPI_NON_DATA_PROTO, ATAPI_DIR_WRITE); 33 | 34 | atapi_cmnd.pkt[0] = GPCMD_START_STOP_UNIT; 35 | atapi_cmnd.pkt[1] = 1; 36 | atapi_cmnd.pkt[4] = 0x02; /* eject */ 37 | 38 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, 0); 39 | 40 | return res; 41 | } 42 | 43 | int ioctl_get_configuration(int fd, uint8_t *buffer) 44 | { 45 | int res; 46 | struct lv2_atapi_cmnd_block atapi_cmnd; 47 | 48 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0x10, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 49 | atapi_cmnd.pkt[0] = GPCMD_GET_CONFIGURATION; 50 | atapi_cmnd.pkt[1] = 0; 51 | atapi_cmnd.pkt[2] = 0xff; 52 | atapi_cmnd.pkt[3] = 0x41; 53 | atapi_cmnd.pkt[8] = 0x10; 54 | 55 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 56 | // if (buffer[10] & 1 == 0) return 0xF000FFFF 57 | // if (buffer[0] & 1 != 0) exec_mode_sense 58 | return res; 59 | } 60 | 61 | int ioctl_mode_sense(int fd, uint8_t *buffer) 62 | { 63 | int res; 64 | struct lv2_atapi_cmnd_block atapi_cmnd; 65 | 66 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0x10, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 67 | 68 | atapi_cmnd.pkt[0] = GPCMD_MODE_SENSE_10; 69 | atapi_cmnd.pkt[1] = 0x08; 70 | atapi_cmnd.pkt[2] = 0x03; 71 | atapi_cmnd.pkt[8] = 0x10; 72 | 73 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 74 | // if (buffer[11] == 2) exec_mode_select 75 | return res; 76 | } 77 | 78 | int ioctl_mode_select(int fd) 79 | { 80 | int res; 81 | struct lv2_atapi_cmnd_block atapi_cmnd; 82 | static uint8_t buffer[256]; 83 | memset(buffer, 0, sizeof(buffer)); 84 | 85 | buffer[1] = 0x0e; 86 | buffer[7] = 8; 87 | buffer[8] = 3; 88 | buffer[9] = 6; 89 | buffer[11] = 3; // ? 3 == SACD 90 | buffer[255] = 0x10; 91 | 92 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0x10, ATAPI_PIO_DATA_OUT_PROTO, ATAPI_DIR_WRITE); 93 | 94 | atapi_cmnd.pkt[0] = GPCMD_MODE_SELECT_10; 95 | atapi_cmnd.pkt[1] = 0x10; /* PF */ 96 | atapi_cmnd.pkt[8] = 0x10; 97 | 98 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 99 | 100 | return res; 101 | } 102 | 103 | int ioctl_enable_encryption(int fd, uint8_t *buffer, uint32_t lba) 104 | { 105 | int res; 106 | struct lv2_atapi_cmnd_block atapi_cmnd; 107 | 108 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0x0a, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 109 | 110 | atapi_cmnd.pkt[0] = GPCMD_READ_DVD_STRUCTURE; 111 | atapi_cmnd.pkt[1] = 2; 112 | 113 | atapi_cmnd.pkt[2] = lba >> 24; 114 | atapi_cmnd.pkt[3] = lba >> 16; 115 | atapi_cmnd.pkt[4] = lba >> 8; 116 | atapi_cmnd.pkt[5] = lba & 0xff; 117 | 118 | atapi_cmnd.pkt[9] = 0x0a; 119 | 120 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 121 | 122 | return res; 123 | } 124 | 125 | int ioctl_get_event_status_notification(int fd, uint8_t *buffer) 126 | { 127 | int res; 128 | struct lv2_atapi_cmnd_block atapi_cmnd; 129 | 130 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0x08, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 131 | 132 | atapi_cmnd.pkt[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; 133 | atapi_cmnd.pkt[1] = 1; /* IMMED */ 134 | atapi_cmnd.pkt[4] = 4; /* media event */ 135 | atapi_cmnd.pkt[8] = 0x08; 136 | 137 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 138 | 139 | return res; 140 | } 141 | 142 | int ioctl_report_key_start(int fd, uint8_t *buffer) 143 | { 144 | int res; 145 | struct lv2_atapi_cmnd_block atapi_cmnd; 146 | 147 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0x08, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 148 | 149 | atapi_cmnd.pkt[0] = GPCMD_REPORT_KEY; 150 | 151 | atapi_cmnd.pkt[2] = 0; 152 | atapi_cmnd.pkt[3] = 0; 153 | atapi_cmnd.pkt[4] = 0; 154 | atapi_cmnd.pkt[5] = 0x08; 155 | 156 | atapi_cmnd.pkt[6] = 0; 157 | atapi_cmnd.pkt[7] = 0x10; 158 | 159 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 160 | 161 | return res; 162 | } 163 | 164 | int ioctl_send_key(int fd, uint8_t agid, uint32_t key_size, uint8_t *key, uint8_t sequence) 165 | { 166 | int res; 167 | struct lv2_atapi_cmnd_block atapi_cmnd; 168 | uint32_t buffer_size; 169 | uint8_t buffer[256]; 170 | uint8_t buffer_align = 0; 171 | 172 | if ((key_size & 3) != 0) 173 | { 174 | buffer_align = ~(key_size & 3) + 4 + 1; 175 | } 176 | buffer_size = key_size + 4 + buffer_align; 177 | 178 | sys_storage_init_atapi_cmnd(&atapi_cmnd, buffer_size, ATAPI_PIO_DATA_OUT_PROTO, ATAPI_DIR_WRITE); 179 | 180 | atapi_cmnd.pkt[0] = GPCMD_SEND_KEY; 181 | 182 | atapi_cmnd.pkt[2] = buffer_size >> 24; 183 | atapi_cmnd.pkt[3] = buffer_size >> 16; 184 | atapi_cmnd.pkt[4] = buffer_size >> 8; 185 | atapi_cmnd.pkt[5] = buffer_size & 0xff; 186 | 187 | atapi_cmnd.pkt[6] = sequence; 188 | atapi_cmnd.pkt[7] = 0x10; 189 | atapi_cmnd.pkt[10] = agid; 190 | 191 | memset(buffer, 0, sizeof(buffer)); 192 | 193 | buffer[0] = key_size >> 24; 194 | buffer[1] = key_size >> 16; 195 | buffer[2] = key_size >> 8; 196 | buffer[3] = key_size & 0xff; 197 | memcpy(buffer + 4, key, key_size); 198 | 199 | //if (buffer_align != 0) { 200 | // memset(buffer + key_size + 4, 0, buffer_align); 201 | //} 202 | 203 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 204 | 205 | return res; 206 | } 207 | 208 | int ioctl_report_key(int fd, uint8_t agid, uint32_t *key_size, uint8_t *key, uint8_t sequence) 209 | { 210 | int res; 211 | struct lv2_atapi_cmnd_block atapi_cmnd; 212 | uint32_t buffer_size; 213 | uint8_t buffer[256]; 214 | uint8_t buffer_align = 0; 215 | uint32_t new_key_size, old_key_size = *key_size; 216 | 217 | memset(buffer, 0, sizeof(buffer)); 218 | 219 | if ((old_key_size & 3) != 0) 220 | { 221 | buffer_align = ~(old_key_size & 3) + 4 + 1; 222 | } 223 | buffer_size = old_key_size + 4 + buffer_align; 224 | 225 | sys_storage_init_atapi_cmnd(&atapi_cmnd, buffer_size, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 226 | 227 | atapi_cmnd.pkt[0] = GPCMD_REPORT_KEY; 228 | 229 | atapi_cmnd.pkt[2] = buffer_size >> 24; 230 | atapi_cmnd.pkt[3] = buffer_size >> 16; 231 | atapi_cmnd.pkt[4] = buffer_size >> 8; 232 | atapi_cmnd.pkt[5] = buffer_size & 0xff; 233 | 234 | atapi_cmnd.pkt[6] = sequence; 235 | atapi_cmnd.pkt[7] = 0x10; 236 | atapi_cmnd.pkt[10] = agid; 237 | 238 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 239 | 240 | new_key_size = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; 241 | *key_size = new_key_size; 242 | 243 | memcpy(key, buffer + 4, (old_key_size > new_key_size ? new_key_size : old_key_size)); 244 | 245 | return res; 246 | } 247 | 248 | int ioctl_report_key_finish(int fd, uint8_t agid) 249 | { 250 | int res; 251 | struct lv2_atapi_cmnd_block atapi_cmnd; 252 | 253 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 0, ATAPI_NON_DATA_PROTO, ATAPI_DIR_READ); 254 | 255 | atapi_cmnd.pkt[0] = GPCMD_REPORT_KEY; 256 | 257 | atapi_cmnd.pkt[6] = 0xff; 258 | atapi_cmnd.pkt[7] = 0x10; 259 | atapi_cmnd.pkt[10] = agid; 260 | 261 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, 0); 262 | 263 | return res; 264 | } 265 | 266 | 267 | int ioctl_read_toc_header(int fd, uint8_t *buffer) 268 | { 269 | int res; 270 | struct lv2_atapi_cmnd_block atapi_cmnd; 271 | 272 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 12, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 273 | 274 | atapi_cmnd.pkt[0] = GPCMD_READ_TOC_PMA_ATIP; 275 | atapi_cmnd.pkt[6] = 0; 276 | atapi_cmnd.pkt[8] = 12; /* LSB of length */ 277 | 278 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 279 | 280 | return res; 281 | } 282 | 283 | int ioctl_read_toc_entry(int fd, uint8_t *buffer) 284 | { 285 | int res; 286 | struct lv2_atapi_cmnd_block atapi_cmnd; 287 | 288 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 12, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 289 | 290 | atapi_cmnd.pkt[0] = GPCMD_READ_TOC_PMA_ATIP; 291 | atapi_cmnd.pkt[6] = 0x01; 292 | atapi_cmnd.pkt[8] = 12; /* LSB of length */ 293 | 294 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 295 | 296 | return res; 297 | } 298 | 299 | int ioctl_read_track(int fd, uint8_t *buffer, uint8_t track) 300 | { 301 | int res; 302 | struct lv2_atapi_cmnd_block atapi_cmnd; 303 | 304 | sys_storage_init_atapi_cmnd(&atapi_cmnd, 48, ATAPI_PIO_DATA_IN_PROTO, ATAPI_DIR_READ); 305 | 306 | atapi_cmnd.pkt[0] = GPCMD_READ_TRACK_RZONE_INFO; 307 | atapi_cmnd.pkt[1] = 1; 308 | atapi_cmnd.pkt[5] = track; /* track */ 309 | atapi_cmnd.pkt[8] = 48; /* LSB of length */ 310 | 311 | res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer); 312 | 313 | return res; 314 | } 315 | 316 | #endif 317 | -------------------------------------------------------------------------------- /libs/libsacd/ioctl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __IOCTL_H__ 23 | #define __IOCTL_H__ 24 | 25 | #ifdef __lv2ppu__ 26 | 27 | #include 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | extern int ioctl_eject(int fd); 35 | extern int ioctl_init(int fd, uint8_t *buffer); 36 | extern int ioctl_enable_encryption(int fd, uint8_t *buffer, uint32_t lba); 37 | extern int ioctl_get_configuration(int fd, uint8_t *buffer); 38 | extern int ioctl_mode_sense(int fd, uint8_t *buffer); 39 | extern int ioctl_mode_select(int fd); 40 | extern int ioctl_get_event_status_notification(int fd, uint8_t *buffer); 41 | extern int ioctl_read_toc_header(int fd, uint8_t *buffer); 42 | extern int ioctl_read_toc_entry(int fd, uint8_t *buffer); 43 | extern int ioctl_read_track(int fd, uint8_t *buffer, uint8_t track); 44 | extern int ioctl_read_block(int fd, uint8_t *buffer, int lba); 45 | extern int ioctl_report_key_start(int fd, uint8_t *buffer); 46 | extern int ioctl_send_key(int fd, uint8_t agid, uint32_t key_size, uint8_t *key, uint8_t sequence); 47 | extern int ioctl_report_key(int fd, uint8_t agid, uint32_t *key_size, uint8_t *key, uint8_t sequence); 48 | extern int ioctl_report_key_finish(int fd, uint8_t agid); 49 | 50 | #ifdef __cplusplus 51 | }; 52 | #endif 53 | 54 | #endif 55 | 56 | #endif /* __IOCTL_H__ */ 57 | -------------------------------------------------------------------------------- /libs/libsacd/iso_writer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #ifdef __lv2ppu__ 26 | #include 27 | #elif defined(WIN32) 28 | #include 29 | #endif 30 | 31 | #include "scarletbook_output.h" 32 | 33 | static size_t iso_write_frame(scarletbook_output_format_t *ft, const uint8_t *buf, size_t len) 34 | { 35 | return fwrite(buf, 1, len * SACD_LSN_SIZE, ft->fd); 36 | } 37 | 38 | scarletbook_format_handler_t const * iso_format_fn(void) 39 | { 40 | static scarletbook_format_handler_t handler = 41 | { 42 | "ISO Image", 43 | "iso", 44 | 0, 45 | iso_write_frame, 46 | 0, 47 | OUTPUT_FLAG_RAW, 48 | 0 49 | }; 50 | return &handler; 51 | } 52 | -------------------------------------------------------------------------------- /libs/libsacd/sac_accessor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef __SAC_ACCESSOR_H__ 23 | #define __SAC_ACCESSOR_H__ 24 | 25 | #ifdef __lv2ppu__ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | //#define USE_ISOSELF 1 32 | 33 | #ifdef USE_ISOSELF 34 | #include 35 | #endif 36 | 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #define INTR_PPU_MB_SHIFT 0 43 | #define INTR_STOP_SHIFT 1 44 | #define INTR_HALT_SHIFT 2 45 | #define INTR_DMA_SHIFT 3 46 | #define INTR_SPU_MB_SHIFT 4 47 | #define INTR_PPU_MB_MASK (0x1 << INTR_PPU_MB_SHIFT) 48 | #define INTR_STOP_MASK (0x1 << INTR_STOP_SHIFT) 49 | #define INTR_HALT_MASK (0x1 << INTR_HALT_SHIFT) 50 | #define INTR_DMA_MASK (0x1 << INTR_DMA_SHIFT) 51 | #define INTR_SPU_MB_MASK (0x1 << INTR_SPU_MB_SHIFT) 52 | 53 | #define SPU_INTR_CLASS_2 (2) 54 | 55 | #define EIEIO __asm__ volatile ("eieio") 56 | 57 | /** configuration of sac accessor thread */ 58 | #define PRIMARY_PPU_THREAD_PRIO (1001) 59 | #define PRIMARY_PPU_STACK_SIZE (0x2000) 60 | 61 | #define DMA_BUFFER_SIZE (4 * 2048) 62 | #define EXIT_SAC_CMD (0xfefefeff) 63 | 64 | #ifdef USE_ISOSELF 65 | #define SAC_MODULE_LOCATION "/dev_flash/vsh/module/SacModule.spu.isoself" 66 | #else 67 | #define SAC_MODULE_LOCATION "/dev_hdd0/game/SACDRIP01/USRDIR/sac_module.spu.elf" 68 | #endif 69 | 70 | enum 71 | { 72 | SAC_CMD_INITIALIZE = 0 73 | , SAC_CMD_EXIT = 1 74 | , SAC_CMD_GENERATE_KEY_1 = 2 75 | , SAC_CMD_VALIDATE_KEY_1 = 3 76 | , SAC_CMD_GENERATE_KEY_2 = 4 77 | , SAC_CMD_VALIDATE_KEY_2 = 5 78 | , SAC_CMD_VALIDATE_KEY_3 = 6 79 | , SAC_CMD_ENCRYPT = 7 80 | , SAC_CMD_DECRYPT = 8 81 | } sac_command_t; 82 | 83 | typedef struct 84 | { 85 | uint8_t *buffer; 86 | 87 | uint8_t *module_buffer; 88 | unsigned int module_size; 89 | 90 | sys_ppu_thread_t handler; 91 | 92 | sys_cond_t mmio_cond; 93 | sys_mutex_t mmio_mutex; 94 | 95 | sys_raw_spu_t id; 96 | sys_interrupt_thread_handle_t ih; 97 | sys_interrupt_tag_t intrtag; 98 | 99 | uint32_t error_code; 100 | 101 | uint8_t * read_buffer; 102 | uint8_t * write_buffer; 103 | } sac_accessor_t; 104 | 105 | extern int create_sac_accessor(void); 106 | extern int destroy_sac_accessor(void); 107 | extern int sac_exec_initialize(void); 108 | extern int sac_exec_key_exchange(int); 109 | extern int sac_exec_decrypt_data(uint8_t *, uint32_t, uint8_t *); 110 | extern int sac_exec_exit(void); 111 | 112 | #ifdef __cplusplus 113 | }; 114 | #endif 115 | 116 | #endif 117 | 118 | #endif /* __SAC_ACCESSOR_H__ */ 119 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_input.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SACD_INPUT_H_INCLUDED 23 | #define SACD_INPUT_H_INCLUDED 24 | 25 | #include 26 | 27 | #if defined(__MINGW32__) || defined(_WIN32) 28 | # undef lseek 29 | # define lseek _lseeki64 30 | # undef fseeko 31 | # define fseeko fseeko64 32 | # undef ftello 33 | # define ftello ftello64 34 | # define flockfile(...) 35 | # define funlockfile(...) 36 | # define getc_unlocked getc 37 | # undef off_t 38 | # define off_t uint64_t 39 | # undef stat 40 | # define stat _stati64 41 | # define fstat _fstati64 42 | # define wstat _wstati64 43 | #endif 44 | 45 | #if defined(__lv2ppu__) 46 | #include 47 | #endif 48 | 49 | typedef struct sacd_input_s * sacd_input_t; 50 | 51 | extern sacd_input_t (*sacd_input_open) (const char *); 52 | extern int (*sacd_input_close) (sacd_input_t); 53 | extern ssize_t (*sacd_input_read) (sacd_input_t, int, int, void *); 54 | extern char * (*sacd_input_error) (sacd_input_t); 55 | extern int (*sacd_input_authenticate) (sacd_input_t); 56 | extern int (*sacd_input_decrypt) (sacd_input_t, uint8_t *, int); 57 | extern uint32_t (*sacd_input_total_sectors)(sacd_input_t); 58 | 59 | int sacd_input_setup(const char *); 60 | 61 | #endif /* SACD_INPUT_H_INCLUDED */ 62 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_pb_stream.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "socket.h" 27 | #include "sacd_pb_stream.h" 28 | 29 | static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) 30 | { 31 | bool ret; 32 | size_t written; 33 | p_socket socket = (p_socket) stream->state; 34 | 35 | ret = (socket_send(socket, (const char *) buf, count, &written, 0, 0) == IO_DONE && written == count); 36 | 37 | return ret; 38 | } 39 | 40 | static bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count) 41 | { 42 | int result; 43 | size_t got = 0; 44 | p_socket socket = (p_socket) stream->state; 45 | 46 | if (buf == NULL) 47 | { 48 | /* Well, this is a really inefficient way to skip input. */ 49 | /* It is only used when there are unknown fields. */ 50 | char dummy; 51 | while (count-- && socket_recv(socket, &dummy, 1, &got, MSG_WAITALL, 0) == IO_DONE && got == 1); 52 | return count == 0; 53 | } 54 | 55 | result = socket_recv(socket, (char *) buf, count, &got, MSG_WAITALL, 0); 56 | 57 | if (result != IO_DONE) 58 | stream->bytes_left = 0; /* EOF */ 59 | 60 | return got == count && result == IO_DONE; 61 | } 62 | 63 | pb_ostream_t pb_ostream_from_socket(p_socket socket) 64 | { 65 | pb_ostream_t stream = {&write_callback, (void*)socket, SIZE_MAX, 0}; 66 | return stream; 67 | } 68 | 69 | pb_istream_t pb_istream_from_socket(p_socket socket) 70 | { 71 | pb_istream_t stream = {&read_callback, (void*)socket, SIZE_MAX}; 72 | return stream; 73 | } 74 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_pb_stream.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef _SACD_PB_STREAM_H_ 23 | #define _SACD_PB_STREAM_H_ 24 | 25 | #include 26 | 27 | #include "socket.h" 28 | 29 | pb_ostream_t pb_ostream_from_socket(p_socket socket); 30 | pb_istream_t pb_istream_from_socket(p_socket socket); 31 | 32 | #endif /* _SACD_PB_STREAM_H_ */ 33 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_read_internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SACDREAD_INTERNAL_H 23 | #define SACDREAD_INTERNAL_H 24 | 25 | #ifdef _MSC_VER 26 | #include 27 | #endif /* _MSC_VER */ 28 | 29 | #define CHECK_VALUE(arg) \ 30 | if (!(arg)) { \ 31 | fprintf(stderr, "\n*** libsacdread: CHECK_VALUE failed in %s:%i ***" \ 32 | "\n*** for %s ***\n\n", \ 33 | __FILE__, __LINE__, # arg); \ 34 | } 35 | 36 | #endif /* SACDREAD_INTERNAL_H */ 37 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_reader.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SACD_READER_H_INCLUDED 23 | #define SACD_READER_H_INCLUDED 24 | 25 | #ifdef _MSC_VER 26 | 27 | #include 28 | #include 29 | #endif 30 | 31 | #include 32 | #include 33 | 34 | #include "sacd_input.h" 35 | 36 | /** 37 | * The SACD access interface. 38 | * 39 | * This file contains the functions that form the interface to audio tracks located on a SACD. 40 | */ 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /** 47 | * Opaque type that is used as a handle for one instance of an opened SACD. 48 | */ 49 | typedef struct sacd_reader_s sacd_reader_t; 50 | 51 | /** 52 | * Opens a block device of a SACD-ROM file, or an image file. 53 | * 54 | * @param path Specifies the the device or file to be used. 55 | * @return If successful a a read handle is returned. Otherwise 0 is returned. 56 | * 57 | * sacd = sacd_open(path); 58 | */ 59 | sacd_reader_t *sacd_open(const char *); 60 | 61 | /** 62 | * Closes and cleans up the SACD reader object. 63 | * 64 | * You must close all open files before calling this function. 65 | * 66 | * @param sacd A read handle that should be closed. 67 | * 68 | * sacd_close(sacd); 69 | */ 70 | void sacd_close(sacd_reader_t *); 71 | 72 | /** 73 | * Seeks and reads a block from sacd. 74 | * 75 | * @param sacd A read handle that should be closed. 76 | * @param lb_number The block number to seek to. 77 | * @param block_count The amount of blocks to read. 78 | * @param data The data pointer to read the block into. 79 | * 80 | * sacd_read_block_raw(sacd, lb_number, block_count, data); 81 | */ 82 | ssize_t sacd_read_block_raw(sacd_reader_t *, uint32_t, size_t, unsigned char *); 83 | 84 | /** 85 | * Decrypts audio sectors, only available on PS3 86 | */ 87 | int sacd_decrypt(sacd_reader_t *, uint8_t *, int); 88 | 89 | /** 90 | * Authenticates disc, only available on PS3 91 | */ 92 | int sacd_authenticate(sacd_reader_t *); 93 | 94 | /** 95 | * returns the total sector size of the image / disc 96 | */ 97 | uint32_t sacd_get_total_sectors(sacd_reader_t *); 98 | 99 | #ifdef __cplusplus 100 | }; 101 | #endif 102 | #endif /* SACD_READER_H_INCLUDED */ 103 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_ripper.pb.c: -------------------------------------------------------------------------------- 1 | /* Automatically generated nanopb constant definitions */ 2 | #include "sacd_ripper.pb.h" 3 | 4 | const uint32_t ServerRequest_sector_offset_default = 0; 5 | const uint32_t ServerRequest_sector_count_default = 0; 6 | 7 | 8 | const pb_field_t ServerRequest_fields[4] = { 9 | {1, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, 10 | offsetof(ServerRequest, type), 0, 11 | pb_membersize(ServerRequest, type), 0, 0}, 12 | 13 | {2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, 14 | pb_delta_end(ServerRequest, sector_offset, type), 0, 15 | pb_membersize(ServerRequest, sector_offset), 0, 16 | &ServerRequest_sector_offset_default}, 17 | 18 | {3, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, 19 | pb_delta_end(ServerRequest, sector_count, sector_offset), 0, 20 | pb_membersize(ServerRequest, sector_count), 0, 21 | &ServerRequest_sector_count_default}, 22 | 23 | PB_LAST_FIELD 24 | }; 25 | 26 | const pb_field_t ServerResponse_fields[4] = { 27 | {1, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, 28 | offsetof(ServerResponse, type), 0, 29 | pb_membersize(ServerResponse, type), 0, 0}, 30 | 31 | {2, PB_HTYPE_REQUIRED | PB_LTYPE_VARINT, 32 | pb_delta_end(ServerResponse, result, type), 0, 33 | pb_membersize(ServerResponse, result), 0, 0}, 34 | 35 | {3, PB_HTYPE_OPTIONAL | PB_LTYPE_BYTES, 36 | pb_delta_end(ServerResponse, data, result), 37 | pb_delta(ServerResponse, has_data, data), 38 | 512 * 2048, 0, 0}, 39 | 40 | PB_LAST_FIELD 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_ripper.pb.h: -------------------------------------------------------------------------------- 1 | #ifndef _PB_SACD_RIPPER_PB_H_ 2 | #define _PB_SACD_RIPPER_PB_H_ 3 | #include 4 | 5 | /* Enum definitions */ 6 | typedef enum { 7 | ServerRequest_Type_DISC_OPEN = 1, 8 | ServerRequest_Type_DISC_CLOSE = 2, 9 | ServerRequest_Type_DISC_READ = 3, 10 | ServerRequest_Type_DISC_SIZE = 4 11 | } ServerRequest_Type; 12 | 13 | typedef enum { 14 | ServerResponse_Type_DISC_OPENED = 1, 15 | ServerResponse_Type_DISC_CLOSED = 2, 16 | ServerResponse_Type_DISC_READ = 3, 17 | ServerResponse_Type_DISC_SIZE = 4 18 | } ServerResponse_Type; 19 | 20 | /* Struct definitions */ 21 | typedef struct { 22 | ServerRequest_Type type; 23 | uint32_t sector_offset; 24 | uint32_t sector_count; 25 | } ServerRequest; 26 | 27 | typedef struct { 28 | size_t size; 29 | uint8_t *bytes; 30 | } ServerResponse_data_t; 31 | 32 | typedef struct { 33 | ServerResponse_Type type; 34 | int64_t result; 35 | bool has_data; 36 | ServerResponse_data_t data; 37 | } ServerResponse; 38 | 39 | /* Default values for struct fields */ 40 | extern const uint32_t ServerRequest_sector_offset_default; 41 | extern const uint32_t ServerRequest_sector_count_default; 42 | 43 | /* Struct field encoding specification for nanopb */ 44 | extern const pb_field_t ServerRequest_fields[4]; 45 | extern const pb_field_t ServerResponse_fields[4]; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /libs/libsacd/sacd_ripper.proto: -------------------------------------------------------------------------------- 1 | import "nanopb.proto"; 2 | 3 | message ServerRequest 4 | { 5 | enum Type 6 | { 7 | DISC_OPEN = 1; 8 | DISC_CLOSE = 2; 9 | DISC_READ = 3; 10 | DISC_SIZE = 4; 11 | } 12 | required Type type = 1; 13 | required uint32 sector_offset = 2 [default = 0]; 14 | required uint32 sector_count = 3 [default = 0]; 15 | } 16 | 17 | message ServerResponse 18 | { 19 | enum Type 20 | { 21 | DISC_OPENED = 1; 22 | DISC_CLOSED = 2; 23 | DISC_READ = 3; 24 | DISC_SIZE = 4; 25 | } 26 | required Type type = 1; 27 | required int64 result = 2; 28 | optional bytes data = 3 [(nanopb).max_size = 1024000]; 29 | } 30 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include "scarletbook.h" 23 | 24 | const char *character_set[] = 25 | { 26 | "US-ASCII", 27 | "ISO646-JP", 28 | "ISO-8859-1", 29 | "SHIFT_JISX0213", 30 | "KSC5601.1987-0", 31 | "GB2312.1980-0", 32 | "BIG5", 33 | "ISO-8859-1", 34 | }; 35 | 36 | const char *album_genre[] = 37 | { 38 | "Not used" 39 | , "Not defined" 40 | , "Adult Contemporary" 41 | , "Alternative Rock" 42 | , "Children's Music" 43 | , "Classical" 44 | , "Contemporary Christian" 45 | , "Country" 46 | , "Dance" 47 | , "Easy Listening" 48 | , "Erotic" 49 | , "Folk" 50 | , "Gospel" 51 | , "Hip Hop" 52 | , "Jazz" 53 | , "Latin" 54 | , "Musical" 55 | , "New Age" 56 | , "Opera" 57 | , "Operetta" 58 | , "Pop Music" 59 | , "RAP" 60 | , "Reggae" 61 | , "Rock Music" 62 | , "Rhythm & Blues" 63 | , "Sound Effects" 64 | , "Sound Track" 65 | , "Spoken Word" 66 | , "World Music" 67 | , "Blues" 68 | }; 69 | 70 | const char *album_category[] = 71 | { 72 | "Not used" 73 | , "General" 74 | , "Japanese" 75 | }; 76 | 77 | 78 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_helpers.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include "scarletbook_helpers.h" 28 | 29 | #define MAX_DISC_ARTIST_LEN 60 30 | #define MAX_ALBUM_TITLE_LEN 60 31 | #define MAX_TRACK_TITLE_LEN 60 32 | #define MAX_TRACK_ARTIST_LEN 60 33 | 34 | char *get_album_dir(scarletbook_handle_t *handle) 35 | { 36 | char disc_artist[MAX_DISC_ARTIST_LEN + 1]; 37 | char disc_album_title[MAX_ALBUM_TITLE_LEN + 1]; 38 | char disc_album_year[5]; 39 | char *albumdir; 40 | master_text_t *master_text = &handle->master_text; 41 | char *artist = 0; 42 | char *album_title = 0; 43 | 44 | if (master_text->album_artist) 45 | artist = master_text->album_artist; 46 | else if (master_text->album_artist_phonetic) 47 | artist = master_text->album_artist_phonetic; 48 | else if (master_text->disc_artist) 49 | artist = master_text->disc_artist; 50 | else if (master_text->disc_artist_phonetic) 51 | artist = master_text->disc_artist_phonetic; 52 | 53 | if (master_text->album_title) 54 | album_title = master_text->album_title; 55 | else if (master_text->album_title_phonetic) 56 | album_title = master_text->album_title_phonetic; 57 | else if (master_text->disc_title) 58 | album_title = master_text->disc_title; 59 | else if (master_text->disc_title_phonetic) 60 | album_title = master_text->disc_title_phonetic; 61 | 62 | memset(disc_artist, 0, sizeof(disc_artist)); 63 | if (artist) 64 | { 65 | char *pos = strchr(artist, ';'); 66 | if (!pos) 67 | pos = artist + strlen(artist); 68 | utf8cpy(disc_artist, artist, min(pos-artist, MAX_DISC_ARTIST_LEN)); 69 | } 70 | 71 | memset(disc_album_title, 0, sizeof(disc_album_title)); 72 | if (album_title) 73 | { 74 | char *pos = strchr(album_title, ';'); 75 | if (!pos) 76 | pos = album_title + strlen(album_title); 77 | utf8cpy(disc_album_title, album_title, min(pos - album_title, MAX_ALBUM_TITLE_LEN)); 78 | } 79 | 80 | snprintf(disc_album_year, sizeof(disc_album_year), "%04d", handle->master_toc->disc_date_year); 81 | 82 | sanitize_filename(disc_artist); 83 | sanitize_filename(disc_album_title); 84 | 85 | if (strlen(disc_artist) > 0 && strlen(disc_album_title) > 0) 86 | albumdir = parse_format("%A - %L", 0, disc_album_year, disc_artist, disc_album_title, NULL); 87 | else if (strlen(disc_artist) > 0) 88 | albumdir = parse_format("%A", 0, disc_album_year, disc_artist, disc_album_title, NULL); 89 | else if (strlen(disc_album_title) > 0) 90 | albumdir = parse_format("%L", 0, disc_album_year, disc_artist, disc_album_title, NULL); 91 | else 92 | albumdir = parse_format("Unknown Album", 0, disc_album_year, disc_artist, disc_album_title, NULL); 93 | 94 | sanitize_filepath(albumdir); 95 | 96 | return albumdir; 97 | } 98 | 99 | char *get_music_filename(scarletbook_handle_t *handle, int area, int track, const char *override_title) 100 | { 101 | char *c; 102 | char track_artist[MAX_TRACK_ARTIST_LEN + 1]; 103 | char track_title[MAX_TRACK_TITLE_LEN + 1]; 104 | char disc_album_title[MAX_ALBUM_TITLE_LEN + 1]; 105 | char disc_album_year[5]; 106 | master_text_t *master_text = &handle->master_text; 107 | char *album_title = 0; 108 | 109 | if (master_text->album_title) 110 | album_title = master_text->album_title; 111 | else if (master_text->album_title_phonetic) 112 | album_title = master_text->album_title_phonetic; 113 | else if (master_text->disc_title) 114 | album_title = master_text->disc_title; 115 | else if (master_text->disc_title_phonetic) 116 | album_title = master_text->disc_title_phonetic; 117 | 118 | memset(track_artist, 0, sizeof(track_artist)); 119 | c = handle->area[area].area_track_text[track].track_type_performer; 120 | if (c) 121 | { 122 | utf8cpy(track_artist, c, MAX_TRACK_ARTIST_LEN); 123 | } 124 | 125 | memset(track_title, 0, sizeof(track_title)); 126 | c = handle->area[area].area_track_text[track].track_type_title; 127 | if (c) 128 | { 129 | utf8cpy(track_title, c, MAX_TRACK_TITLE_LEN); 130 | } 131 | 132 | memset(disc_album_title, 0, sizeof(disc_album_title)); 133 | if (album_title) 134 | { 135 | char *pos = strchr(album_title, ';'); 136 | if (!pos) 137 | pos = album_title + strlen(album_title); 138 | utf8cpy(disc_album_title, album_title, min(pos - album_title, MAX_ALBUM_TITLE_LEN)); 139 | } 140 | 141 | snprintf(disc_album_year, sizeof(disc_album_year), "%04d", handle->master_toc->disc_date_year); 142 | 143 | sanitize_filename(track_artist); 144 | sanitize_filename(disc_album_title); 145 | sanitize_filename(track_title); 146 | 147 | if (override_title && strlen(override_title) > 0) 148 | return parse_format("%N - %T", track + 1, disc_album_year, track_artist, disc_album_title, override_title); 149 | else if (strlen(track_artist) > 0 && strlen(track_title) > 0) 150 | return parse_format("%N - %A - %T", track + 1, disc_album_year, track_artist, disc_album_title, track_title); 151 | else if (strlen(track_artist) > 0) 152 | return parse_format("%N - %A", track + 1, disc_album_year, track_artist, disc_album_title, track_title); 153 | else if (strlen(track_title) > 0) 154 | return parse_format("%N - %T", track + 1, disc_album_year, track_artist, disc_album_title, track_title); 155 | else if (strlen(disc_album_title) > 0) 156 | return parse_format("%N - %L", track + 1, disc_album_year, track_artist, disc_album_title, track_title); 157 | else 158 | return parse_format("%N - Unknown Artist", track + 1, disc_album_year, track_artist, disc_album_title, track_title); 159 | } 160 | 161 | 162 | char *get_speaker_config_string(area_toc_t *area) 163 | { 164 | if (area->channel_count == 2 && area->extra_settings == 0) 165 | { 166 | return "2ch."; 167 | } 168 | else if (area->channel_count == 5 && area->extra_settings == 3) 169 | { 170 | return "5ch."; 171 | } 172 | else if (area->channel_count == 6 && area->extra_settings == 4) 173 | { 174 | return "5.1ch"; 175 | } 176 | else 177 | { 178 | return "Unknown"; 179 | } 180 | } 181 | 182 | char *get_frame_format_string(area_toc_t *area) 183 | { 184 | if (area->frame_format == FRAME_FORMAT_DSD_3_IN_14) 185 | { 186 | return "DSD 3 in 14"; 187 | } 188 | else if (area->frame_format == FRAME_FORMAT_DSD_3_IN_16) 189 | { 190 | return "DSD 3 in 16"; 191 | } 192 | else if (area->frame_format == FRAME_FORMAT_DST) 193 | { 194 | return "Lossless DST"; 195 | } 196 | else 197 | { 198 | return "Unknown"; 199 | } 200 | } 201 | 202 | int utf8cpy(char *dst, char *src, int n){ 203 | // n is the size of dst (including the last byte for null 204 | int i = 0; 205 | 206 | while(i < n){ 207 | int c; 208 | if(!(src[i] & 0x80)){ 209 | // ASCII code 210 | if(src[i] == '\0'){ 211 | break; 212 | } 213 | c = 1; 214 | } 215 | else if((src[i] & 0xe0) == 0xc0){ 216 | // 2-byte code 217 | c = 2; 218 | } 219 | else if((src[i] & 0xf0) == 0xe0){ 220 | // 3-byte code 221 | c = 3; 222 | } 223 | else if((src[i] & 0xf8) == 0xf0){ 224 | // 4-byte code 225 | c = 4; 226 | } 227 | else if(src[i] == '\0'){ 228 | break; 229 | } 230 | else{ 231 | break; 232 | } 233 | if(i + c <= n){ 234 | memcpy(dst + i, src + i, c * sizeof(char)); 235 | i += c; 236 | } 237 | else{ 238 | break; 239 | } 240 | } 241 | 242 | dst[i] = '\0'; 243 | return i; 244 | } 245 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_helpers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SCARLETBOOK_HELPERS_H_INCLUDED 23 | #define SCARLETBOOK_HELPERS_H_INCLUDED 24 | 25 | #include "scarletbook.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /** 32 | * helper functions.. 33 | */ 34 | static inline int has_two_channel(scarletbook_handle_t *handle) 35 | { 36 | return handle->twoch_area_idx != -1; 37 | } 38 | 39 | static inline int has_multi_channel(scarletbook_handle_t *handle) 40 | { 41 | return handle->mulch_area_idx != -1; 42 | } 43 | 44 | static inline int has_both_channels(scarletbook_handle_t *handle) 45 | { 46 | return handle->twoch_area_idx != -1 && handle->mulch_area_idx != -1; 47 | } 48 | 49 | static inline area_toc_t* get_two_channel(scarletbook_handle_t *handle) 50 | { 51 | return(handle->twoch_area_idx == -1 ? 0 : handle->area[handle->twoch_area_idx].area_toc); 52 | } 53 | 54 | static inline area_toc_t* get_multi_channel(scarletbook_handle_t *handle) 55 | { 56 | return(handle->mulch_area_idx == -1 ? 0 : handle->area[handle->mulch_area_idx].area_toc); 57 | } 58 | 59 | char *get_speaker_config_string(area_toc_t *); 60 | 61 | char *get_frame_format_string(area_toc_t *); 62 | 63 | char *get_album_dir(scarletbook_handle_t *); 64 | 65 | char *get_music_filename(scarletbook_handle_t *, int, int, const char *); 66 | 67 | int utf8cpy(char *, char *, int); 68 | 69 | #ifdef __cplusplus 70 | }; 71 | #endif 72 | #endif /* SCARLETBOOK_HELPERS_H_INCLUDED */ 73 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_id3.c: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include "scarletbook.h" 31 | 32 | #include 33 | #include 34 | 35 | int scarletbook_id3_tag_render(scarletbook_handle_t *handle, uint8_t *buffer, int area, int track) 36 | { 37 | const int sacd_id3_genres[] = { 38 | 12, /* Not used => Other */ 39 | 12, /* Not defined => Other */ 40 | 60, /* Adult Contemporary => Top 40 */ 41 | 40, /* Alternative Rock => AlternRock */ 42 | 12, /* Children's Music => Other */ 43 | 32, /* Classical => Classical */ 44 | 140, /* Contemporary Christian => Contemporary Christian */ 45 | 2, /* Country => Country */ 46 | 3, /* Dance => Dance */ 47 | 98, /* Easy Listening => Easy Listening */ 48 | 109, /* Erotic => Porn Groove */ 49 | 80, /* Folk => Folk */ 50 | 38, /* Gospel => Gospel */ 51 | 7, /* Hip Hop => Hip-Hop */ 52 | 8, /* Jazz => Jazz */ 53 | 86, /* Latin => Latin */ 54 | 77, /* Musical => Musical */ 55 | 10, /* New Age => New Age */ 56 | 103, /* Opera => Opera */ 57 | 104, /* Operetta => Chamber Music */ 58 | 13, /* Pop Music => Pop */ 59 | 15, /* RAP => Rap */ 60 | 16, /* Reggae => Reggae */ 61 | 17, /* Rock Music => Rock */ 62 | 14, /* Rhythm & Blues => R&B */ 63 | 37, /* Sound Effects => Sound Clip */ 64 | 24, /* Sound Track => Soundtrack */ 65 | 101, /* Spoken Word => Speech */ 66 | 48, /* World Music => Ethnic */ 67 | 0, /* Blues => Blues */ 68 | 12, /* Not used => Other */ 69 | }; 70 | struct id3_tag *tag; 71 | struct id3_frame *frame; 72 | char tmp[200]; 73 | int len; 74 | 75 | tag = id3_open_mem(0, ID3_OPENF_CREATE); 76 | 77 | memset(tmp, 0, sizeof(tmp)); 78 | 79 | if (handle->area[area].area_track_text[track].track_type_title) 80 | { 81 | char *track_type_title = charset_convert(handle->area[area].area_track_text[track].track_type_title, strlen(handle->area[area].area_track_text[track].track_type_title), "UTF-8", "ISO-8859-1"); 82 | frame = id3_add_frame(tag, ID3_TIT2); 83 | id3_set_text(frame, track_type_title); 84 | free(track_type_title); 85 | } 86 | else 87 | { 88 | master_text_t *master_text = &handle->master_text; 89 | char *album_title = 0; 90 | 91 | if (master_text->album_title) 92 | album_title = master_text->album_title; 93 | else if (master_text->album_title_phonetic) 94 | album_title = master_text->album_title_phonetic; 95 | else if (master_text->disc_title) 96 | album_title = master_text->disc_title; 97 | else if (master_text->disc_title_phonetic) 98 | album_title = master_text->disc_title_phonetic; 99 | 100 | if (album_title) 101 | { 102 | frame = id3_add_frame(tag, ID3_TIT2); 103 | album_title = charset_convert(album_title, strlen(album_title), "UTF-8", "ISO-8859-1"); 104 | id3_set_text(frame, album_title); 105 | free(album_title); 106 | } 107 | } 108 | // TPE2 is widely used as album artist 109 | if (handle->master_text.album_artist) 110 | { 111 | char *album_artist = handle->master_text.album_artist; 112 | frame = id3_add_frame(tag, ID3_TPE2); 113 | album_artist = charset_convert(album_artist, strlen(album_artist), "UTF-8", "ISO-8859-1"); 114 | id3_set_text(frame, album_artist); 115 | free(album_artist); 116 | } 117 | if (&handle->area[area].area_isrc_genre->isrc[track]) 118 | { 119 | char isrc[12]; 120 | char *isrc_conv; 121 | memcpy(isrc, handle->area[area].area_isrc_genre->isrc[track].country_code, 2); 122 | memcpy(isrc + 2, handle->area[area].area_isrc_genre->isrc[track].owner_code, 3); 123 | memcpy(isrc + 5, handle->area[area].area_isrc_genre->isrc[track].recording_year, 2); 124 | memcpy(isrc + 7, handle->area[area].area_isrc_genre->isrc[track].designation_code, 5); 125 | 126 | frame = id3_add_frame(tag, ID3_TSRC); 127 | isrc_conv = charset_convert(isrc, 12, "UTF-8", "ISO-8859-1"); 128 | id3_set_text(frame, isrc_conv); 129 | free(isrc_conv); 130 | } 131 | if (handle->master_text.album_publisher){ 132 | char *publisher = handle->master_text.album_publisher; 133 | frame = id3_add_frame(tag, ID3_TPUB); 134 | publisher = charset_convert(publisher, strlen(publisher), "UTF-8", "ISO-8859-1"); 135 | id3_set_text(frame, publisher); 136 | free(publisher); 137 | } 138 | if (handle->master_text.album_copyright){ 139 | char *copyright = handle->master_text.album_copyright; 140 | frame = id3_add_frame(tag, ID3_TCOP); 141 | copyright = charset_convert(copyright, strlen(copyright), "UTF-8", "ISO-8859-1"); 142 | id3_set_text(frame, copyright); 143 | free(copyright); 144 | } 145 | if (handle->master_toc){ 146 | master_toc_t *mtoc = handle->master_toc; 147 | char str[64]; 148 | char *str_conv; 149 | sprintf(str, "%d/%d", mtoc->album_sequence_number, mtoc->album_set_size); 150 | frame = id3_add_frame(tag, ID3_TPOS); 151 | str_conv = charset_convert(str, strlen(str), "UTF-8", "ISO-8859-1"); 152 | id3_set_text(frame,str_conv); 153 | free(str_conv); 154 | } 155 | if (handle->area[area].area_track_text[track].track_type_composer) 156 | { 157 | char *composer = handle->area[area].area_track_text[track].track_type_composer; 158 | frame = id3_add_frame(tag, ID3_TCOM); 159 | composer = charset_convert(composer, strlen(composer), "UTF-8", "ISO-8859-1"); 160 | id3_set_text(frame, composer); 161 | free(composer); 162 | } 163 | 164 | 165 | 166 | if (handle->area[area].area_track_text[track].track_type_performer) 167 | { 168 | char *performer = handle->area[area].area_track_text[track].track_type_performer; 169 | frame = id3_add_frame(tag, ID3_TPE1); 170 | performer = charset_convert(performer, strlen(performer), "UTF-8", "ISO-8859-1"); 171 | id3_set_text(frame, performer); 172 | free(performer); 173 | } 174 | else 175 | { 176 | master_text_t *master_text = &handle->master_text; 177 | char *artist = 0; 178 | 179 | // preferably we use the title as the artist name, as disc/album artist mostly contains garbage.. 180 | if (master_text->album_title) 181 | artist = master_text->album_title; 182 | else if (master_text->album_title_phonetic) 183 | artist = master_text->album_title_phonetic; 184 | else if (master_text->disc_title) 185 | artist = master_text->disc_title; 186 | else if (master_text->disc_title_phonetic) 187 | artist = master_text->disc_title_phonetic; 188 | else if (master_text->album_artist) 189 | artist = master_text->album_artist; 190 | else if (master_text->album_artist_phonetic) 191 | artist = master_text->album_artist_phonetic; 192 | else if (master_text->disc_artist) 193 | artist = master_text->disc_artist; 194 | else if (master_text->disc_artist_phonetic) 195 | artist = master_text->disc_artist_phonetic; 196 | 197 | if (artist) 198 | { 199 | frame = id3_add_frame(tag, ID3_TPE1); 200 | artist = charset_convert(artist, strlen(artist), "UTF-8", "ISO-8859-1"); 201 | id3_set_text(frame, artist); 202 | free(artist); 203 | } 204 | } 205 | 206 | { 207 | master_text_t *master_text = &handle->master_text; 208 | char *album_title = 0; 209 | 210 | if (master_text->album_title) 211 | album_title = master_text->album_title; 212 | else if (master_text->album_title_phonetic) 213 | album_title = master_text->album_title_phonetic; 214 | else if (master_text->disc_title) 215 | album_title = master_text->disc_title; 216 | else if (master_text->disc_title_phonetic) 217 | album_title = master_text->disc_title_phonetic; 218 | 219 | if (album_title) 220 | { 221 | frame = id3_add_frame(tag, ID3_TALB); 222 | album_title = charset_convert(album_title, strlen(album_title), "UTF-8", "ISO-8859-1"); 223 | id3_set_text(frame, album_title); 224 | free(album_title); 225 | } 226 | } 227 | 228 | frame = id3_add_frame(tag, ID3_TCON); 229 | id3_set_text(frame, (char *) genre_table[sacd_id3_genres[handle->area[area].area_isrc_genre->track_genre[track].genre & 0x1f]]); 230 | 231 | snprintf(tmp, 200, "%04d", handle->master_toc->disc_date_year); 232 | frame = id3_add_frame(tag, ID3_TYER); 233 | id3_set_text(frame, tmp); 234 | 235 | snprintf(tmp, 200, "%02d%02d", handle->master_toc->disc_date_month, handle->master_toc->disc_date_day); 236 | frame = id3_add_frame(tag, ID3_TDAT); 237 | id3_set_text(frame, tmp); 238 | 239 | snprintf(tmp, 200, "%d/%d", track + 1,handle->area[area].area_toc->track_count); // internally tracks start from 0 240 | frame = id3_add_frame(tag, ID3_TRCK); 241 | id3_set_text(frame, tmp); 242 | 243 | len = id3_write_tag(tag, buffer); 244 | id3_close(tag); 245 | 246 | return len; 247 | } 248 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_id3.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SCARLETBOOK_ID3_H_INCLUDED 23 | #define SCARLETBOOK_ID3_H_INCLUDED 24 | 25 | #include "scarletbook.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | int scarletbook_id3_tag_render(scarletbook_handle_t *, uint8_t *, int, int); 32 | 33 | #ifdef __cplusplus 34 | }; 35 | #endif 36 | #endif /* SCARLETBOOK_ID3_H_INCLUDED */ 37 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_output.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SCARLETBOOK_OUTPUT_H_INCLUDED 23 | #define SCARLETBOOK_OUTPUT_H_INCLUDED 24 | 25 | #ifdef __lv2ppu__ 26 | #include "dst_decoder_ps3.h" 27 | #else 28 | #include 29 | #endif 30 | 31 | #include "scarletbook.h" 32 | 33 | // forward declaration 34 | typedef struct scarletbook_output_format_t scarletbook_output_format_t; 35 | typedef struct scarletbook_output_s scarletbook_output_t; 36 | 37 | enum 38 | { 39 | OUTPUT_FLAG_RAW = 1 << 0, 40 | OUTPUT_FLAG_DSD = 1 << 1, 41 | OUTPUT_FLAG_DST = 1 << 2, 42 | OUTPUT_FLAG_EDIT_MASTER = 1 << 3 43 | }; 44 | 45 | // Handler structure defined by each output format. 46 | typedef struct scarletbook_format_handler_t 47 | { 48 | char const *description; 49 | char const *name; 50 | int (*startwrite)(scarletbook_output_format_t *ft); 51 | size_t (*write)(scarletbook_output_format_t *ft, const uint8_t *buf, size_t len); 52 | int (*stopwrite)(scarletbook_output_format_t *ft); 53 | int flags; 54 | size_t priv_size; 55 | } 56 | scarletbook_format_handler_t; 57 | 58 | typedef int (*fwprintf_callback_t)(FILE *stream, const wchar_t *format, ...); 59 | 60 | struct scarletbook_output_format_t 61 | { 62 | int area; 63 | int track; 64 | uint32_t start_lsn; 65 | uint32_t length_lsn; 66 | uint32_t current_lsn; 67 | char *filename; 68 | 69 | int channel_count; 70 | 71 | FILE *fd; 72 | char *write_cache; 73 | uint64_t write_length; 74 | uint64_t write_offset; 75 | 76 | int dst_encoded_import; 77 | int dsd_encoded_export; 78 | 79 | scarletbook_format_handler_t handler; 80 | void *priv; 81 | 82 | int error_nr; 83 | char error_str[256]; 84 | 85 | dst_decoder_t *dst_decoder; 86 | 87 | scarletbook_handle_t *sb_handle; 88 | fwprintf_callback_t cb_fwprintf; 89 | 90 | int dsf_nopad; 91 | struct list_head sub_queue; 92 | struct list_head siblings; 93 | }; 94 | 95 | typedef void (*stats_progress_callback_t)(uint32_t stats_total_sectors, uint32_t stats_total_sectors_processed, 96 | uint32_t stats_current_file_total_sectors, uint32_t stats_current_file_sectors_processed); 97 | 98 | typedef void (*stats_track_callback_t)(char *filename, int current_track, int total_tracks, int dst_decomp); 99 | 100 | scarletbook_output_t *scarletbook_output_create(scarletbook_handle_t *, stats_track_callback_t, stats_progress_callback_t, fwprintf_callback_t); 101 | int scarletbook_output_destroy(scarletbook_output_t *); 102 | int scarletbook_output_enqueue_track(scarletbook_output_t *, int, int, char *, char *, int, int, int); 103 | int scarletbook_output_enqueue_raw_sectors(scarletbook_output_t *, int, int, char *, char *); 104 | int scarletbook_output_start(scarletbook_output_t *); 105 | void scarletbook_output_interrupt(scarletbook_output_t *); 106 | int scarletbook_output_is_busy(scarletbook_output_t *); 107 | int scarletbook_output_join_process_frames_thread(scarletbook_output_t *); 108 | 109 | #endif /* SCARLETBOOK_OUTPUT_H_INCLUDED */ 110 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_print.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SCARLETBOOK_PRINT_H_INCLUDED 23 | #define SCARLETBOOK_PRINT_H_INCLUDED 24 | 25 | #include 26 | #include "scarletbook.h" 27 | 28 | void scarletbook_print(scarletbook_handle_t *); 29 | 30 | #endif /* SCARLETBOOK_PRINT_H_INCLUDED */ 31 | -------------------------------------------------------------------------------- /libs/libsacd/scarletbook_read.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef SCARLETBOOK_READ_H_INCLUDED 23 | #define SCARLETBOOK_READ_H_INCLUDED 24 | 25 | #include "scarletbook.h" 26 | #include "sacd_reader.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /** 33 | * handle = scarletbook_open(sacd, title); 34 | * 35 | * Opens a scarletbook structure and reads in all the data. 36 | * Returns a handle to a completely parsed structure. 37 | */ 38 | scarletbook_handle_t *scarletbook_open(sacd_reader_t *, int); 39 | 40 | /** 41 | * initialize scarletbook audio frames structs 42 | */ 43 | void scarletbook_frame_init(scarletbook_handle_t *handle); 44 | 45 | /** 46 | * callback when a complete audio frame has been read 47 | */ 48 | typedef void (*frame_read_callback_t)(scarletbook_handle_t *handle, uint8_t* frame_data, size_t frame_size, void *userdata); 49 | 50 | /** 51 | * processes scarletbook audio frames and does a callback in case it found a frame 52 | */ 53 | void scarletbook_process_frames(scarletbook_handle_t *, uint8_t *, int, int, frame_read_callback_t, void *); 54 | 55 | /** 56 | * scarletbook_close(ifofile); 57 | * Cleans up the scarletbook information. This will free all data allocated for the 58 | * substructures. 59 | */ 60 | void scarletbook_close(scarletbook_handle_t *); 61 | 62 | #ifdef __cplusplus 63 | }; 64 | #endif 65 | #endif /* SCARLETBOOK_READ_H_INCLUDED */ 66 | -------------------------------------------------------------------------------- /libs/libsacd/version.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SACD Ripper - https://github.com/sacd-ripper/ 3 | * 4 | * Copyright (c) 2010-2015 by respective authors. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #ifndef VERSION_H_INCLUDED 23 | #define VERSION_H_INCLUDED 24 | #define _STRINGIZER(arg) #arg 25 | #define STRINGIZER(arg) _STRINGIZER(arg) 26 | 27 | //#define SACD_RIPPER_VERSION 00308 28 | #define SACD_RIPPER_VERSION_STRING STRINGIZER(GIT_COMMIT_HASH) 29 | #define SACD_RIPPER_REPO STRINGIZER(GIT_REPO_URL) 30 | 31 | //#define SACD_RIPPER_VERSION_REVISION (SACD_RIPPER_VERSION / 100000) 32 | //#define SACD_RIPPER_VERSION_MAJOR (SACD_RIPPER_VERSION / 100 % 1000) 33 | //#define SACD_RIPPER_VERSION_MINOR (SACD_RIPPER_VERSION % 100) 34 | 35 | #define SACD_RIPPER_VERSION_INFO \ 36 | "SACD Ripper\n" \ 37 | SACD_RIPPER_VERSION_STRING "\n" \ 38 | "Copyright (c) 2010-2015 by respective authors.\n" \ 39 | 40 | #endif /* VERSION_H_INCLUDED */ 41 | -------------------------------------------------------------------------------- /readme.rst: -------------------------------------------------------------------------------- 1 | Disclaimer 2 | ========== 3 | DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 4 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 5 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 6 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 7 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 8 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 9 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 10 | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 11 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 12 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 13 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 14 | DAMAGE. 15 | 16 | What this is 17 | ============ 18 | 19 | This is a fork of sacd-ripper/sacd-ripper. For original release documents, please refer to https://github.com/sacd-ripper/sacd-ripper . This fork focuses only on improvement of sacd_extract, so most of the irrelevant codes have been removed. 20 | 21 | This fork adds the following additional features to the original sacd_extract. 22 | 23 | 1. Padding-less DSF generation (-z): Some players do not handle zero padding in DSF correctly resulting in a pop noise at a track transition. With this option, instead of zero padding, the data fragment that doesn't perfectly fit in the 4096 Bytes/channel block size at the tail of a track is carried forward to the head of the next track so no zero padding is needed. This is a loss-less process. This option cannot be combined with the -t option because continuous processing of the entire album is needed for this option to work. 24 | 25 | 2. Concurrent ISO+DSF/DSDIFF processing (-w): With this option, both ISO (-I) and DSF (-s) or DSDIFF (-p) can be generated concurrently. This is much more efficient than generating ISO and DSF/DSDIFF sequentially because ISO generation is a very light process in terms of CPU usage while DST decompression (mandatory for DSF, optional for DSDIFF) is not. The run time of this process is expected to be the slower of ISO and DSF/DSDIFF generation. 26 | 27 | 3. Output directory options (-o and -y): These allow users to specify the output directory. For the concurent processing mode, -o is for ISO and -y is for DSF/DSDIFF. The directories specified by these options must exist. Output directories default to the current directory. 28 | 29 | 4. Enabled max compiler optimization in CMakeList.txt for gcc. This provides about 3x speed boost to DST decoding (mandatory for DSF generation) for Linux and MacOS. 30 | 31 | 5. More ID3v2 frames are added. TSRC (ISRC), TPUB (Publisher), TCOP (Copyright message), TCOM (Composer), and TPE2 frames have been added. TPE2 is used as album artist which is a common practice. Also, the fix for ID3 size coding issue contributed by David Bryant has been merged. 32 | 33 | 6. Mingw-w64 support: This allows compilation of a Windows binary without Visual Studio. 34 | 35 | 7. A little more aggressive multithreading: Raw read and DST decoding, which used to happen sequentially, are performed in parallel. 36 | 37 | 8. Stereo and multi-channel extraction in one shot: No longer need to run sacd_extract twice to extract stereo and multi-channel tracks. In other words, the -2 and -m options can be used simultaneously for DSF/DSDIFF generation. 38 | 39 | Development of this software is primarily done on Linux. Functionality on Windows has been checked. Windows binary needs to be compiled with Mingw-w64. Visual Studio is no longer supported. 40 | 41 | Usage 42 | ====================================== 43 | 44 | The following options are available for the sacd_extract commandline tool: :: 45 | 46 | -2, --2ch-tracks : Export two channel tracks (default) 47 | -m, --mch-tracks : Export multi-channel tracks 48 | -e, --output-dsdiff-em : output as Philips DSDIFF (Edit Master) file 49 | -p, --output-dsdiff : output as Philips DSDIFF file 50 | -s, --output-dsf : output as Sony DSF file 51 | -z, --dsf-nopad : Do not zero pad DSF (cannot be used with -t) 52 | -t, --select-track : only output selected track(s) (ex. -t 1,5,13) 53 | -I, --output-iso : output as RAW ISO 54 | -w, --concurrent : Concurrent ISO+DSF/DSDIFF processing mode 55 | -c, --convert-dst : convert DST to DSD 56 | -C, --export-cue : Export a CUE Sheet 57 | -i, --input[=FILE] : set source and determine if "iso" image, 58 | device or server (ex. -i 192.168.1.10:2002) 59 | -o, --output-dir[=DIR] : Output directory (ISO output dir for concurrent processing mode) 60 | -y, --output-dir-conc[=DIR] : DSF/DSDIFF Output directory for concurrent processing mode 61 | -P, --print : display disc and track information 62 | 63 | 64 | Usage examples 65 | ============== 66 | 67 | Extract all stereo tracks in uncompressed DSDIFF from an ISO to /home/user/blah/:: 68 | 69 | $ sacd_extract -2 -p -c -i"Foo_Bar_RIP.ISO" -o /home/user/blah 70 | 71 | Extract all stereo tracks in padding-less DSF files from an ISO to /home/user/blah/:: 72 | 73 | $ sacd_extract -2 -s -z -i"Foo_Bar_RIP.ISO" -o /home/user/blah 74 | 75 | Extract an ISO from a server to /home/user/blah/.iso:: 76 | 77 | $ sacd_extract -I -i192.168.1.10:2002 -o /home/user/blah 78 | 79 | Concurrently extract an ISO file to /home/user/blah/.iso and all stereo tracks in DSF to /tmp/blah/ from a server.:: 80 | 81 | $ sacd_extract -I -s -w -z -i192.168.1.10:2002 -o /home/user/blah -y /tmp/blah 82 | 83 | Concurrently extract an ISO file to /home/user/blah/.iso and all stereo and multi-channel tracks in DSF to /tmp/blah/ from a server.:: 84 | 85 | $ sacd_extract -I -s -w -z -2 -m -i192.168.1.10:2002 -o /home/user/blah -y /tmp/blah 86 | 87 | 88 | Compilation 89 | =========== 90 | 91 | Linux:: 92 | 93 | $ cd tools/sacd_extract 94 | $ cmake . 95 | $ make 96 | 97 | Windows binary compilation on Linux using Mingw-w64 preceded by iconv compilation for Mingw-w64:: 98 | 99 | $ tar -xzf libiconv-1.15.tar.gz 100 | $ cd libiconv-1.15 101 | $ ./configure --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32 --enable-static 102 | $ make 103 | $ sudo make install 104 | 105 | $ cd tools/sacd_extract 106 | $ cmake -DMINGW64=YES 107 | $ make 108 | 109 | macOS:: 110 | 111 | $ xcode-select --install 112 | $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 113 | $ brew install cmake 114 | $ git clone https://github.com/setmind/sacd-ripper.git 115 | $ cd sacd-ripper/tools/sacd_extract 116 | $ cmake . 117 | $ make 118 | 119 | -------------------------------------------------------------------------------- /todo: -------------------------------------------------------------------------------- 1 | TODO 2 | 3 | version 0.3.x 4 | 5 | - add CUE Sheet support 6 | - logging 7 | - cleanup logging, split lm_main into multiple destinations 8 | - write log along each consecutive rip 9 | - write INFO,NOTICE,etc.. 10 | - the log should contain more information: 11 | - date/time 12 | - output format (ISO, mch DSDIFF (DSD), etc.) 13 | - add option to embed sac_module & decoder 14 | - use output_format_t.error_number for error handling 15 | - catch read failures 16 | - do not stop and continue decoding and reading 17 | - specify max amount of read errors 18 | - skipping DST/DSD frames 19 | - skip TOCs 20 | - log read errors 21 | -------------------------------------------------------------------------------- /tools/sacd_extract/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMake build file for SACD Extract 2 | 3 | cmake_minimum_required(VERSION 2.6) 4 | 5 | # Mingw-w64 support 6 | OPTION(MINGW64 "Mingw-w64" NO) 7 | if (MINGW64 MATCHES "YES") 8 | MESSAGE(STATUS "Mingw-w64 mode enabled") 9 | SET(CMAKE_SYSTEM_NAME Windows) 10 | SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") 11 | SET(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 12 | SET(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) 13 | SET(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) 14 | endif (MINGW64 MATCHES "YES") 15 | 16 | execute_process( 17 | COMMAND git describe --tags --dirty --abbrev=64 18 | OUTPUT_VARIABLE GIT_COMMIT_HASH 19 | RESULT_VARIABLE GIT_COMMIT_HASH_RESULT 20 | OUTPUT_STRIP_TRAILING_WHITESPACE 21 | ) 22 | 23 | execute_process( 24 | COMMAND git remote get-url origin 25 | OUTPUT_VARIABLE GIT_REPO_URL 26 | RESULT_VARIABLE GIT_REPO_URL_RESULT 27 | OUTPUT_STRIP_TRAILING_WHITESPACE 28 | ) 29 | 30 | # Obtain git commit hash and repo url 31 | if(${GIT_COMMIT_HASH_RESULT} GREATER 0) 32 | add_definitions("-DGIT_COMMIT_HASH=NA") 33 | else(${GIT_COMMIT_HASH_RESULT} GREATER 0) 34 | add_definitions("-DGIT_COMMIT_HASH=${GIT_COMMIT_HASH}") 35 | MESSAGE(STATUS "git commit hash: ${GIT_COMMIT_HASH}") 36 | endif(${GIT_COMMIT_HASH_RESULT} GREATER 0) 37 | 38 | if(${GIT_REPO_URL_RESULT} GREATER 0) 39 | add_definitions("-DGIT_REPO_URL=NA") 40 | else(${GIT_REPO_URL_RESULT} GREATER 0) 41 | add_definitions("-DGIT_REPO_URL=\"${GIT_REPO_URL}\"") 42 | MESSAGE(STATUS "git repo url: ${GIT_REPO_URL}") 43 | endif(${GIT_REPO_URL_RESULT} GREATER 0) 44 | 45 | project(sacd_extract C) 46 | 47 | # Load some macros. 48 | SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}") 49 | 50 | # Macros we'll need 51 | include(CheckIncludeFile) 52 | include(CheckFunctionExists) 53 | include(CheckTypeSize) 54 | include(FindThreads) 55 | 56 | # Include directory paths 57 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 58 | include_directories(${sacd_extract_SOURCE_DIR}) 59 | 60 | include_directories("../../libs/libcommon") 61 | include_directories("../../libs/libdstdec") 62 | include_directories("../../libs/libid3") 63 | include_directories("../../libs/libsacd") 64 | 65 | STRING(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER) 66 | if(NOT CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG") 67 | if (CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) 68 | add_definitions( 69 | -pipe 70 | -Wall -Wextra -Wcast-align -Wpointer-arith -O3 71 | -Wno-unused-parameter) 72 | endif () 73 | if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm*") 74 | add_definitions( 75 | -msse2) 76 | endif () 77 | endif () 78 | 79 | if(WIN32) 80 | set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIRARIES} -lpthread -lws2_32 -liconv -static") 81 | elseif(APPLE) 82 | set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIRARIES} -liconv -lpthread") 83 | else() 84 | add_definitions(-D_FILE_OFFSET_BITS=64) 85 | set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIRARIES} -lpthread") 86 | endif() 87 | 88 | file(GLOB libcommon_headers ../../libs/libcommon/*.h) 89 | file(GLOB libcommon_sources ../../libs/libcommon/*.c) 90 | source_group(libcommon FILES ${libcommon_headers} ${libcommon_sources}) 91 | 92 | file(GLOB libdstdec_headers ../../libs/libdstdec/*.h) 93 | file(GLOB libdstdec_sources ../../libs/libdstdec/*.c) 94 | source_group(libdstdec FILES ${libdstdec_headers} ${libdstdec_sources}) 95 | 96 | file(GLOB libid3_headers ../../libs/libid3/*.h) 97 | file(GLOB libid3_sources ../../libs/libid3/*.c) 98 | source_group(libid3 FILES ${libid3_headers} ${libid3_sources}) 99 | 100 | file(GLOB libsacd_headers ../../libs/libsacd/*.h) 101 | file(GLOB libsacd_sources ../../libs/libsacd/*.c) 102 | source_group(libsacd FILES ${libsacd_headers} ${libsacd_sources}) 103 | 104 | file(GLOB main_headers ./*.h) 105 | file(GLOB main_sources ./*.c) 106 | source_group(main FILES ${main_headers} ${main_sources}) 107 | 108 | add_executable(sacd_extract 109 | ${main_headers} ${main_sources} 110 | ${libcommon_headers} ${libcommon_sources} 111 | ${libdstdec_headers} ${libdstdec_sources} 112 | ${libid3_headers} ${libid3_sources} 113 | ${libsacd_headers} ${libsacd_sources} 114 | ) 115 | -------------------------------------------------------------------------------- /tools/sacd_extract/changelog: -------------------------------------------------------------------------------- 1 | version 0.3.7 2 | 3 | - fixed a bug where arranger phonetic was referenced incorrectly during print (-P) 4 | - option to allow individual dsf/dsdiff track extraction 5 | - added (foobar) compatible escaping to cuesheets 6 | - added user optional output filename/folder (last parameter) 7 | 8 | version 0.3.6 9 | 10 | - network speed improvement 11 | - added native OS X support 12 | - gapless is on by default for individual tracks 13 | - fixed issue where CUE export wrote to wrong filename 14 | 15 | version 0.3.5 16 | 17 | - added ID3 tags to Edit Master for multiple ID3 tagging 18 | - added option to export individual CUE Sheets 19 | - fixed DSTI table where DST Edit Master > 2GB 20 | - fixed SACD to ID3 genre conversion table 21 | 22 | version 0.3.4 (bug fix release, please update if running 0.3.3) 23 | 24 | - fixed a bug where DSTI was incorrectly part of DSD chunk 25 | 26 | version 0.3.3 (bug fix release, please update if running 0.3.2) 27 | 28 | - fixed a bug where a wrong DSDIFF header was written for edit masters 29 | 30 | version 0.3.2 31 | 32 | - added DSDIFF Edit Master (single DSD file) support 33 | - added CUE Sheet support for Edit Master 34 | - added DST frame buffer overflow protection 35 | - added DST frame index chunk support 36 | - removed gapless support (replaced by DSDIFF Edit Master) 37 | - merged Maxims optimized FIR decoder 38 | -------------------------------------------------------------------------------- /tools/sacd_extract/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. 3 | 4 | NOTE: The canonical source of this file is maintained with the GNU C Library. 5 | Bugs can be reported to bug-glibc@gnu.org. 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20 | USA. */ 21 | 22 | #ifndef _GETOPT_H 23 | #define _GETOPT_H 1 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* For communication from `getopt' to the caller. 30 | When `getopt' finds an option that takes an argument, 31 | the argument value is returned here. 32 | Also, when `ordering' is RETURN_IN_ORDER, 33 | each non-option ARGV-element is returned here. */ 34 | 35 | extern char *optarg; 36 | 37 | /* Index in ARGV of the next element to be scanned. 38 | This is used for communication to and from the caller 39 | and for communication between successive calls to `getopt'. 40 | 41 | On entry to `getopt', zero means this is the first call; initialize. 42 | 43 | When `getopt' returns -1, this is the index of the first of the 44 | non-option elements that the caller should itself scan. 45 | 46 | Otherwise, `optind' communicates from one call to the next 47 | how much of ARGV has been scanned so far. */ 48 | 49 | extern int optind; 50 | 51 | /* Callers store zero here to inhibit the error message `getopt' prints 52 | for unrecognized options. */ 53 | 54 | extern int opterr; 55 | 56 | /* Set to an option character which was unrecognized. */ 57 | 58 | extern int optopt; 59 | 60 | /* Describe the long-named options requested by the application. 61 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 62 | of `struct option' terminated by an element containing a name which is 63 | zero. 64 | 65 | The field `has_arg' is: 66 | no_argument (or 0) if the option does not take an argument, 67 | required_argument (or 1) if the option requires an argument, 68 | optional_argument (or 2) if the option takes an optional argument. 69 | 70 | If the field `flag' is not NULL, it points to a variable that is set 71 | to the value given in the field `val' when the option is found, but 72 | left unchanged if the option is not found. 73 | 74 | To have a long-named option do something other than set an `int' to 75 | a compiled-in constant, such as set a value from `optarg', set the 76 | option's `flag' field to zero and its `val' field to a nonzero 77 | value (the equivalent single-letter option character, if there is 78 | one). For long options that have a zero `flag' field, `getopt' 79 | returns the contents of the `val' field. */ 80 | 81 | struct option 82 | { 83 | #if defined (__STDC__) && __STDC__ 84 | const char *name; 85 | #else 86 | char *name; 87 | #endif 88 | /* has_arg can't be an enum because some compilers complain about 89 | type mismatches in all the code that assumes it is an int. */ 90 | int has_arg; 91 | int *flag; 92 | int val; 93 | }; 94 | 95 | /* Names for the values of the `has_arg' field of `struct option'. */ 96 | 97 | #define no_argument 0 98 | #define required_argument 1 99 | #define optional_argument 2 100 | 101 | #if defined (__STDC__) && __STDC__ 102 | #ifdef __GNU_LIBRARY__ 103 | /* Many other libraries have conflicting prototypes for getopt, with 104 | differences in the consts, in stdlib.h. To avoid compilation 105 | errors, only prototype getopt for the GNU C library. */ 106 | extern int getopt (int argc, char *const *argv, const char *shortopts); 107 | #else /* not __GNU_LIBRARY__ */ 108 | extern int getopt (); 109 | #endif /* __GNU_LIBRARY__ */ 110 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, 111 | const struct option *longopts, int *longind); 112 | extern int getopt_long_only (int argc, char *const *argv, 113 | const char *shortopts, 114 | const struct option *longopts, int *longind); 115 | 116 | /* Internal only. Users should not call this directly. */ 117 | extern int _getopt_internal (int argc, char *const *argv, 118 | const char *shortopts, 119 | const struct option *longopts, int *longind, 120 | int long_only); 121 | #else /* not __STDC__ */ 122 | extern int getopt (); 123 | extern int getopt_long (); 124 | extern int getopt_long_only (); 125 | 126 | extern int _getopt_internal (); 127 | #endif /* __STDC__ */ 128 | 129 | #ifdef __cplusplus 130 | } 131 | #endif 132 | 133 | #endif /* getopt.h */ 134 | -------------------------------------------------------------------------------- /tools/sacd_extract/getopt1.c: -------------------------------------------------------------------------------- 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. 2 | Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 3 | Free Software Foundation, Inc. 4 | 5 | NOTE: The canonical source of this file is maintained with the GNU C Library. 6 | Bugs can be reported to bug-glibc@gnu.org. 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the 10 | Free Software Foundation; either version 2, or (at your option) any 11 | later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software 20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 21 | USA. */ 22 | 23 | #ifdef HAVE_CONFIG_H 24 | #include 25 | #endif 26 | 27 | #include "getopt.h" 28 | 29 | #if !defined __STDC__ || !__STDC__ 30 | /* This is a separate conditional since some stdc systems 31 | reject `defined (const)'. */ 32 | #ifndef const 33 | #define const 34 | #endif 35 | #endif 36 | 37 | #include 38 | 39 | /* Comment out all this code if we are using the GNU C Library, and are not 40 | actually compiling the library itself. This code is part of the GNU C 41 | Library, but also included in many other GNU distributions. Compiling 42 | and linking in this code is a waste when using the GNU C library 43 | (especially if it is a shared library). Rather than having every GNU 44 | program understand `configure --with-gnu-libc' and omit the object files, 45 | it is simpler to just do this in the source for each such file. */ 46 | 47 | #define GETOPT_INTERFACE_VERSION 2 48 | #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 49 | #include 50 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION 51 | #define ELIDE_CODE 52 | #endif 53 | #endif 54 | 55 | #ifndef ELIDE_CODE 56 | 57 | 58 | /* This needs to come after some library #include 59 | to get __GNU_LIBRARY__ defined. */ 60 | #ifdef __GNU_LIBRARY__ 61 | #include 62 | #endif 63 | 64 | #ifndef NULL 65 | #define NULL 0 66 | #endif 67 | 68 | int 69 | getopt_long (argc, argv, options, long_options, opt_index) 70 | int argc; 71 | char *const *argv; 72 | const char *options; 73 | const struct option *long_options; 74 | int *opt_index; 75 | { 76 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 77 | } 78 | 79 | /* Like getopt_long, but '-' as well as '--' can indicate a long option. 80 | If an option that starts with '-' (not '--') doesn't match a long option, 81 | but does match a short option, it is parsed as a short option 82 | instead. */ 83 | 84 | int 85 | getopt_long_only (argc, argv, options, long_options, opt_index) 86 | int argc; 87 | char *const *argv; 88 | const char *options; 89 | const struct option *long_options; 90 | int *opt_index; 91 | { 92 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 93 | } 94 | 95 | 96 | #endif /* Not ELIDE_CODE. */ 97 | 98 | #ifdef TEST 99 | 100 | #include 101 | 102 | int 103 | main (argc, argv) 104 | int argc; 105 | char **argv; 106 | { 107 | int c; 108 | int digit_optind = 0; 109 | 110 | while (1) 111 | { 112 | int this_option_optind = optind ? optind : 1; 113 | int option_index = 0; 114 | static struct option long_options[] = 115 | { 116 | {"add", 1, 0, 0}, 117 | {"append", 0, 0, 0}, 118 | {"delete", 1, 0, 0}, 119 | {"verbose", 0, 0, 0}, 120 | {"create", 0, 0, 0}, 121 | {"file", 1, 0, 0}, 122 | {0, 0, 0, 0} 123 | }; 124 | 125 | c = getopt_long (argc, argv, "abc:d:0123456789", 126 | long_options, &option_index); 127 | if (c == -1) 128 | break; 129 | 130 | switch (c) 131 | { 132 | case 0: 133 | printf ("option %s", long_options[option_index].name); 134 | if (optarg) 135 | printf (" with arg %s", optarg); 136 | printf ("\n"); 137 | break; 138 | 139 | case '0': 140 | case '1': 141 | case '2': 142 | case '3': 143 | case '4': 144 | case '5': 145 | case '6': 146 | case '7': 147 | case '8': 148 | case '9': 149 | if (digit_optind != 0 && digit_optind != this_option_optind) 150 | printf ("digits occur in two different argv-elements.\n"); 151 | digit_optind = this_option_optind; 152 | printf ("option %c\n", c); 153 | break; 154 | 155 | case 'a': 156 | printf ("option a\n"); 157 | break; 158 | 159 | case 'b': 160 | printf ("option b\n"); 161 | break; 162 | 163 | case 'c': 164 | printf ("option c with value `%s'\n", optarg); 165 | break; 166 | 167 | case 'd': 168 | printf ("option d with value `%s'\n", optarg); 169 | break; 170 | 171 | case '?': 172 | break; 173 | 174 | default: 175 | printf ("?? getopt returned character code 0%o ??\n", c); 176 | } 177 | } 178 | 179 | if (optind < argc) 180 | { 181 | printf ("non-option ARGV-elements: "); 182 | while (optind < argc) 183 | printf ("%s ", argv[optind++]); 184 | printf ("\n"); 185 | } 186 | 187 | exit (0); 188 | } 189 | 190 | #endif /* TEST */ 191 | --------------------------------------------------------------------------------