1 /*
2 * This file is part of cyanrip.
3 *
4 * cyanrip is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * cyanrip is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with cyanrip; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #pragma once
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <string.h>
25 #include <math.h>
26 #include "../config.h"
27 #include "version.h"
28
29 #include <cdio/paranoia/paranoia.h>
30 #include <libavutil/mem.h>
31 #include <libavutil/dict.h>
32 #include <libavutil/avstring.h>
33 #include <libavutil/intreadwrite.h>
34 #include <libavcodec/avcodec.h>
35
36 enum cyanrip_output_formats {
37 CYANRIP_FORMAT_FLAC = 0,
38 CYANRIP_FORMAT_TTA,
39 CYANRIP_FORMAT_OPUS,
40 CYANRIP_FORMAT_AAC,
41 CYANRIP_FORMAT_WAVPACK,
42 CYANRIP_FORMAT_ALAC,
43 CYANRIP_FORMAT_MP3,
44 CYANRIP_FORMAT_VORBIS,
45 CYANRIP_FORMAT_WAV,
46 CYANRIP_FORMAT_AAC_MP4,
47 CYANRIP_FORMAT_OPUS_MP4,
48 CYANRIP_FORMAT_PCM,
49
50 CYANRIP_FORMATS_NB,
51 };
52
53 enum cyanrip_pregap_action {
54 CYANRIP_PREGAP_DEFAULT = 0,
55 CYANRIP_PREGAP_DROP,
56 CYANRIP_PREGAP_MERGE,
57 CYANRIP_PREGAP_TRACK,
58 };
59
60 enum CRIPAccuDBStatus {
61 CYANRIP_ACCUDB_DISABLED = 0,
62 CYANRIP_ACCUDB_NOT_FOUND,
63 CYANRIP_ACCUDB_ERROR,
64 CYANRIP_ACCUDB_MISMATCH,
65 CYANRIP_ACCUDB_FOUND,
66 };
67
68 enum CRIPPathType {
69 CRIP_PATH_COVERART, /* arg must be a CRIPArt * */
70 CRIP_PATH_TRACK, /* arg must be a cyanrip_track * */
71 CRIP_PATH_LOG, /* arg must be NULL */
72 };
73
74 enum CRIPSanitize {
75 CRIP_SANITIZE_SIMPLE, /* Replace unacceptable symbols with _ */
76 CRIP_SANITIZE_OS_SIMPLE, /* Same as above, but only replaces symbols not allowed on current OS */
77 CRIP_SANITIZE_UNICODE, /* Replace unacceptable symbols with visually identical unicode equivalents */
78 CRIP_SANITIZE_OS_UNICODE, /* Same as above, but only replaces symbols not allowed on current OS */
79 };
80
81 typedef struct cyanrip_settings {
82 char *dev_path;
83 char *folder_name_scheme;
84 char *track_name_scheme;
85 char *log_name_scheme;
86 enum CRIPSanitize sanitize_method;
87 int speed;
88 int frame_max_retries;
89 int offset;
90 int over_under_read_frames;
91 int print_info_only;
92 int disable_mb;
93 float bitrate;
94 int decode_hdcd;
95 int disable_accurip;
96 int disable_coverart_db;
97 int overread_leadinout;
98 int eject_on_success_rip;
99 enum cyanrip_pregap_action pregap_action[99];
100 int rip_indices_count;
101 int rip_indices[99];
102 int paranoia_level;
103
104 enum cyanrip_output_formats outputs[CYANRIP_FORMATS_NB];
105 int outputs_num;
106 } cyanrip_settings;
107
108 typedef struct CRIPAccuDBEntry {
109 int confidence;
110 uint32_t checksum; /* We don't know which version it is */
111 uint32_t checksum_450;
112 } CRIPAccuDBEntry;
113
114 typedef struct CRIPArt {
115 AVDictionary *meta;
116 char *source_url;
117 char *title; /* Temporary, used during parsing only, copied to meta, do not free */
118
119 AVPacket *pkt;
120 AVCodecParameters *params;
121
122 uint8_t *data;
123 size_t size;
124 char *extension;
125 } CRIPArt;
126
127 typedef struct cyanrip_track {
128 int number; /* Human readable track number, may be 0 */
129 int cd_track_number; /* Actual track on the CD, may be 0 */
130 AVDictionary *meta; /* Disc's AVDictionary gets copied here */
131
132 int track_is_data;
133 int preemphasis;
134
135 size_t nb_samples; /* Track duration in samples */
136
137 int frames_before_disc_start;
138 lsn_t frames; /* Actual number of frames to read, != samples */
139 int frames_after_disc_end;
140
141 lsn_t pregap_lsn;
142 lsn_t start_lsn;
143 lsn_t start_lsn_sig;
144 lsn_t end_lsn;
145 lsn_t end_lsn_sig;
146
147 ptrdiff_t partial_frame_byte_offs;
148
149 CRIPArt art; /* One cover art, will not be saved */
150
151 int computed_crcs;
152 uint32_t eac_crc;
153 uint32_t acurip_checksum_v1;
154 uint32_t acurip_checksum_v1_450;
155 uint32_t acurip_checksum_v2;
156 int acurip_track_is_first;
157 int acurip_track_is_last;
158
159 enum CRIPAccuDBStatus ar_db_status;
160 CRIPAccuDBEntry *ar_db_entries;
161 int ar_db_nb_entries;
162 int ar_db_max_confidence;
163 } cyanrip_track;
164
165 typedef struct cyanrip_ctx {
166 cdrom_drive_t *drive;
167 cdrom_paranoia_t *paranoia;
168 CdIo_t *cdio;
169 FILE *logfile[CYANRIP_FORMATS_NB];
170 cyanrip_settings settings;
171
172 cyanrip_track tracks[198];
173 int nb_tracks; /* Total number of output tracks */
174 int nb_cd_tracks; /* Total tracks the CD signals */
175 int disregard_cd_isrc; /* If one track doesn't have ISRC, universally the rest won't */
176
177 char *mb_submission_url;
178
179 /* Non-track bound cover art */
180 CRIPArt cover_arts[32];
181 int nb_cover_arts;
182
183 /* Drive caps */
184 cdio_drive_read_cap_t rcap;
185 cdio_drive_write_cap_t wcap;
186 cdio_drive_misc_cap_t mcap;
187
188 /* Metadata */
189 AVDictionary *meta;
190 enum CRIPAccuDBStatus ar_db_status;
191
192 /* Destination folder */
193 const char *base_dst_folder;
194
195 int success;
196 int total_error_count;
197 lsn_t start_lsn;
198 lsn_t end_lsn;
199 lsn_t duration_frames;
200 } cyanrip_ctx;
201
202 typedef struct cyanrip_out_fmt {
203 const char *name;
204 const char *folder_suffix;
205 const char *ext;
206 const char *lavf_name;
207 int coverart_supported;
208 int compression_level;
209 int lossless;
210 enum AVCodecID codec;
211 } cyanrip_out_fmt;
212
213 extern const cyanrip_out_fmt crip_fmt_info[];
214
215 char *crip_get_path(cyanrip_ctx *ctx, enum CRIPPathType type, int create_dirs,
216 const cyanrip_out_fmt *fmt, void *arg);
217
dict_get(AVDictionary * dict,const char * key)218 static inline const char *dict_get(AVDictionary *dict, const char *key)
219 {
220 AVDictionaryEntry *e = av_dict_get(dict, key, NULL, 0);
221 return e ? e->value : NULL;
222 }
223
cyanrip_frames_to_duration(uint32_t frames,char * str)224 static inline void cyanrip_frames_to_duration(uint32_t frames, char *str)
225 {
226 if (!str)
227 return;
228 const double tot = frames/75.0; /* 75 frames per second */
229 const int hr = tot/3600.0;
230 const int min = (tot/60.0) - (hr * 60.0);
231 const int sec = tot - ((hr * 3600.0) + min * 60.0);
232 const int msec = tot - sec;
233 snprintf(str, 13, "%02i:%02i:%02i.%03i", hr, min, sec, msec);
234 }
235
cyanrip_samples_to_duration(uint32_t samples,char * str)236 static inline void cyanrip_samples_to_duration(uint32_t samples, char *str)
237 {
238 if (!str)
239 return;
240 const double tot = samples/44100.0; /* 44100 samples per second */
241 const int hr = tot/3600.0;
242 const int min = (tot/60.0) - (hr * 60.0);
243 const int sec = tot - ((hr * 3600.0) + min * 60.0);
244 const int msec = tot - sec;
245 snprintf(str, 13, "%02i:%02i:%02i.%03i", hr, min, sec, msec);
246 }
247
cmp_numbers(const void * a,const void * b)248 static inline int cmp_numbers(const void *a, const void *b)
249 {
250 return *((int *)a) > *((int *)b);
251 }
252
253 extern uint64_t paranoia_status[PARANOIA_CB_FINISHED + 1];
254 extern const int crip_max_paranoia_level;
255