Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanFukusyaYa/DriveAccess/cuesheet.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download) (as text)
Mon Nov 1 14:34:11 2010 UTC (13 years, 5 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +70 -70 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * @file cuesheet.h
3 * @brief 円盤を複写
4 * @author BananaJinn
5 * @version $Id: cuesheet.c,v 1.3 2010/09/06 14:31:45 bananajinn Exp $
6 * 円盤複写屋
7 * Copyright (C) 2004-2010 BananaJinn<banana@mxh.mesh.ne.jp>.
8 */
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "mem.h"
14 #include "aspi.h"
15 #include "struct.h"
16 #include "cmd.h"
17 #include "log.h"
18 #include "discinfo.h"
19
20 #define SEND_GAPDATA 1
21
22 /**
23 * Next Writable Address を取得
24 * @param[in] drive 書込装置構造体
25 * @param[in] track_num トラック番号
26 * @param[out] nwa_ret NWA
27 * @retval RET_OK 正常終了
28 * @retval RET_NG エラー
29 */
30 static int GetNWA(CMDDRIVE *drive, WORD track_num, DWORD *nwa_ret)
31 {
32 DWORD nwa = -150;
33 int ret;
34 struct _TRACKINFO *ti;
35
36 if(REALDRIVE(drive)){
37 ret = SendReadTrackInfo(drive, track_num);
38 if(ret!=RET_OK){
39 DispCommandError(drive);
40 return ret;
41 }
42 ti = (struct _TRACKINFO *)drive->data_buf;
43 nwa = Get4bytes(ti->next_writable_addr);
44 if(nwa == (DWORD)0){
45 nwa -= 150;
46 }
47 }
48 *nwa_ret = nwa;
49 return RET_OK;
50 }
51
52 /**
53 * 新しいキューシート用のメモリを確保
54 * @param[in,out] cs キューシート
55 * @param[in,out] num_cs キューシートのエントリ数
56 * @param[in] num 確保するエントリ数
57 * @return 確保した新しい領域のポインタを返す。エラーの場合は NULL を返す。
58 */
59 static struct _CUESHEET *NewSheet(struct _CUESHEET **cs, int *num_cs, int num)
60 {
61 struct _CUESHEET *result = NULL;
62 *cs = (struct _CUESHEET *)MemResize(
63 *cs, (*num_cs+num)*sizeof(struct _CUESHEET));
64 if(*cs != NULL){
65 result = &(*cs)[*num_cs];
66 *num_cs += num;
67 }
68 return result;
69 }
70
71 /**
72 * メディアカタログ番号設定
73 * @param[in,out] cs キューシート
74 * @param[in,out] num_cs キューシートのエントリ数
75 * @param[in] discinfo ディスク情報
76 * @retval RET_OK 正常終了
77 * @retval RET_MEMERR メモリ不足
78 */
79 static int SetMCN(struct _CUESHEET **cs, int *num_cs, CPDISCINFO *discinfo)
80 {
81 struct _CUESHEET *csp = NewSheet(cs, num_cs, 2);
82 DebugLog("CreateCueSheet: Media catalog number.\n");
83 if(csp == NULL){
84 return RET_MEMERR;
85 }
86
87 csp->ctladr = CSADR_MCN;
88 memcpy(&csp->tno, discinfo->media_catalog_number, 7);
89 csp++;
90 csp->ctladr = CSADR_MCN;
91 memcpy(&csp->tno, discinfo->media_catalog_number+7, 7);
92 return RET_OK;
93 }
94
95
96 /**
97 * ISRC設定
98 * @param[in,out] cs キューシート
99 * @param[in,out] num_cs キューシートのエントリ数
100 * @param[in] track_num トラック番号
101 * @param[in] cpti トラック情報
102 * @retval RET_OK 正常終了
103 * @retval RET_MEMERR メモリ不足
104 */
105 static int SetISRC(struct _CUESHEET **cs, int *num_cs, WORD track_num,
106 CPTRACKINFO *cpti)
107 {
108 struct _CUESHEET *csp = NewSheet(cs, num_cs, 2);
109 DebugLog("CreateCueSheet: ISRC.\n");
110 if(csp == NULL){
111 return RET_MEMERR;
112 }
113
114 csp->ctladr = CSADR_ISRC;
115 csp->tno = (BYTE)track_num;
116 memcpy(&csp->index, cpti->isrc, 6);
117 csp++;
118 csp->ctladr = CSADR_ISRC;
119 csp->tno = (BYTE)track_num;
120 memcpy(&csp->index, cpti->isrc+6, 6);
121 return RET_OK;
122 }
123
124
125 /**
126 * Lead-in設定
127 * @param[in,out] cs キューシート
128 * @param[in,out] num_cs キューシートのエントリ数
129 * @param[in] cpti トラック情報
130 * @param[in] cdtext CD-TEXT有効フラグ
131 * @param[in] nwa NWA
132 * @retval RET_OK 正常終了
133 * @retval RET_MEMERR メモリ不足
134 */
135 static int SetLeadIn(struct _CUESHEET **cs, int *num_cs, CPTRACKINFO *cpti,
136 BOOL cdtext, DWORD nwa)
137 {
138 struct _CUESHEET *csp = NewSheet(cs, num_cs, 1);
139 DebugLog("CreateCueSheet: Lead-in.\n");
140 if(csp == NULL){
141 return RET_MEMERR;
142 }
143 csp->ctladr = IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)
144 ? CSCTL_DATA : CSCTL_AUDIO;
145 csp->ctladr |= CSADR_NORMAL;
146 csp->tno = 0;
147 csp->index = 0;
148 csp->dataform = cdtext ? 0x41 : 0x01;
149 csp->scms = 0;
150 /*LBA2MSF(nwa, &csp->min, &csp->sec, &csp->frame);*/
151 /** Lead-in は常に0 */
152 csp->min = 0;
153 csp->sec = 0;
154 csp->frame = 0;
155 return RET_OK;
156 }
157
158 /**
159 * Lead-out設定
160 * @param[in,out] cs キューシート
161 * @param[in,out] num_cs キューシートのエントリ数
162 * @param[in] cpti トラック情報
163 * @param[in] nwa NWA
164 * @retval RET_OK 正常終了
165 * @retval RET_MEMERR メモリ不足
166 */
167 static int SetLeadOut(struct _CUESHEET **cs, int *num_cs,
168 CPTRACKINFO *cpti, DWORD nwa)
169 {
170 struct _CUESHEET *csp = NewSheet(cs, num_cs, 1);
171 DebugLog("CreateCueSheet: Lead-out.\n");
172 if(csp == NULL){
173 return RET_MEMERR;
174 }
175 csp->ctladr = IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)
176 ? CSCTL_DATA : CSCTL_AUDIO;
177 csp->ctladr |= CSADR_NORMAL;
178 csp->tno = 0xAA;
179 csp->index = 1;
180 if(!IS_TRACKMODE_DATA(cpti->trackinfo.track_mode))
181 csp->dataform = 0x01;
182 else
183 csp->dataform = cpti->mode2 ? 0x24 : 0x14;
184 csp->scms = cpti->trackinfo.copy ? 0x80 : 0;
185 LBA2MSF(nwa, &csp->min, &csp->sec, &csp->frame);
186 return RET_OK;
187 }
188
189
190 /**
191 * プリギャップ設定
192 * @param[in,out] cs キューシート
193 * @param[in,out] num_cs キューシートのエントリ数
194 * @param[in] track_num トラック番号
195 * @param[in] lcpti 直前トラック情報
196 * @param[in] cpti 現在トラック情報
197 * @param[in] gap_len プリギャップ長
198 * @param[in] twopart 2パートプリギャップかどうか
199 * @param[in,out] nwa NWA
200 * @retval RET_OK 正常終了
201 * @retval RET_MEMERR メモリ不足
202 */
203 static int SetPreGap(struct _CUESHEET **cs, int *num_cs, WORD track_num,
204 CPTRACKINFO *lcpti, CPTRACKINFO *cpti,
205 DWORD gap_len, BOOL twopart, DWORD *nwa)
206 {
207 struct _CUESHEET *csp = NULL;
208 DebugLog("CreateCueSheet: PreGap. track=%d gap=%ld nwa=0x%08lX\n",
209 track_num, (long)gap_len, *nwa);
210 if(gap_len > 0){
211 if(twopart && gap_len > 150){
212 csp = NewSheet(cs, num_cs, 1);
213 if(csp == NULL){
214 return RET_MEMERR;
215 }
216 csp->ctladr =
217 IS_TRACKMODE_DATA(lcpti->trackinfo.track_mode)
218 ? CSCTL_DATA : CSCTL_AUDIO;
219 csp->ctladr |= CSADR_NORMAL;
220 csp->tno = (BYTE)track_num;
221 csp->index = 0;
222 #if SEND_GAPDATA
223 if(!IS_TRACKMODE_DATA(lcpti->trackinfo.track_mode)){
224 csp->dataform = 0x00;
225 }
226 else{
227 csp->dataform = lcpti->mode2 ? 0x20 : 0x10;
228 }
229 #else
230 if(!IS_TRACKMODE_DATA(lcpti->trackinfo.track_mode)){
231 csp->dataform = 0x01;
232 }
233 else{
234 csp->dataform = lcpti->mode2 ? 0x24 : 0x14;
235 }
236 #endif
237 csp->scms = lcpti->trackinfo.copy ? 0x80 : 0;
238 LBA2MSF(*nwa, &csp->min, &csp->sec, &csp->frame);
239 *nwa += (gap_len-150);
240 gap_len = 150;
241 }
242 csp = NewSheet(cs, num_cs, 1);
243 if(csp == NULL){
244 return RET_MEMERR;
245 }
246 csp->ctladr = IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)
247 ? CSCTL_DATA : CSCTL_AUDIO;
248 csp->ctladr |= CSADR_NORMAL;
249 csp->tno = (BYTE)track_num;
250 csp->index = 0;
251 #if SEND_GAPDATA
252 if(!IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)){
253 csp->dataform = 0x00;
254 }
255 else{
256 csp->dataform = cpti->mode2 ? 0x20 : 0x10;
257 }
258 #else
259 if(!IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)){
260 csp->dataform = 0x01;
261 }
262 else{
263 csp->dataform = cpti->mode2 ? 0x24 : 0x14;
264 }
265 #endif
266 csp->scms = cpti->trackinfo.copy ? 0x80 : 0;
267 LBA2MSF(*nwa, &csp->min, &csp->sec, &csp->frame);
268 *nwa += gap_len;
269 }
270 return RET_OK;
271 }
272
273
274 /**
275 * Audioまたはデータトラック設定
276 * @param[in,out] cs キューシート
277 * @param[in,out] num_cs キューシートのエントリ数
278 * @param[in] track_num トラック番号
279 * @param[in] cpti トラック情報
280 * @param[in,out] nwa NWA
281 * @retval RET_OK 正常終了
282 * @retval RET_MEMERR メモリ不足
283 */
284 static int SetTrack(struct _CUESHEET **cs, int *num_cs,
285 WORD track_num, CPTRACKINFO *cpti, DWORD *nwa)
286 {
287 struct _CUESHEET *csp = NewSheet(cs, num_cs, 1);
288 DebugLog("CreateCueSheet: Track%d.\n", track_num);
289 if(csp == NULL){
290 return RET_MEMERR;
291 }
292 csp->ctladr = IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)
293 ? CSCTL_DATA : CSCTL_AUDIO;
294 csp->ctladr |= CSADR_NORMAL;
295 csp->tno = (BYTE)track_num;
296 csp->index = 1;
297 if(!IS_TRACKMODE_DATA(cpti->trackinfo.track_mode))
298 csp->dataform = 0x00;
299 else
300 csp->dataform = cpti->mode2 ? 0x20 : 0x10;
301 csp->scms = cpti->trackinfo.copy ? 0x80 : 0;
302 LBA2MSF(*nwa, &csp->min, &csp->sec, &csp->frame);
303 *nwa += Get4bytes(cpti->trackinfo.track_size);
304
305 return RET_OK;
306 }
307
308 /**
309 * SAO記録用CueSheetの作成
310 * @param[in] drive 書込装置構造体
311 * @param[in] discinfo ディスク情報
312 * @param[in] track_start 開始トラック番号
313 * @param[out] cs_ret 作成したCueSheet
314 * @param[out] numcs_ret 作成したCueSheet配列の要素数
315 * @param[in] enable_cdtext もしあればCD-TEXTを有効にするかどうか
316 * @retval RET_OK 正常終了
317 * @retval RET_NG エラー
318 */
319 int CreateCueSheet(CMDDRIVE *drive, CPDISCINFO *discinfo,
320 WORD track_start,
321 struct _CUESHEET **cs_ret, int *numcs_ret,
322 BOOL enable_cdtext)
323 {
324 struct _CUESHEET *cs = NULL;
325 int cur_cs = 0;
326 int num_cs = 0;
327 DWORD gap_len;
328 WORD sess_num = 0;
329 DWORD nwa;
330 CPTRACKINFO *cpti=NULL, *lcpti=NULL;
331 int ret;
332 BOOL gap_2part;
333 BOOL cdtext=FALSE;
334 WORD track_num;
335
336 if(track_start==1 && discinfo->cdtext_size>0 && enable_cdtext){
337 cdtext = TRUE;
338 }
339
340 track_num = track_start;
341 cur_cs = 0;
342 num_cs = 0;
343 sess_num = 0;
344
345 ret = GetNWA(drive, track_num, &nwa);
346 if(ret != RET_OK){
347 return ret;
348 }
349
350 if(strlen((char *)discinfo->media_catalog_number)!=0){
351 /* Media Catalog Number */
352 ret = SetMCN(&cs, &num_cs, discinfo);
353 if(ret != RET_OK){
354 return ret;
355 }
356 }
357
358 cpti = NULL;
359 lcpti = NULL;
360 ret = RET_OK;
361 for( ; track_num <= discinfo->tracks; track_num++){
362 lcpti = cpti;
363 cpti = &discinfo->trackinfo[track_num-1];
364 gap_len = 0;
365 if(sess_num==0){
366 sess_num = SESSION_NUMBER(&cpti->trackinfo);
367 ret = SetLeadIn(&cs, &num_cs, cpti, cdtext, nwa);
368 if(ret != RET_OK){
369 return ret;
370 }
371 if(sess_num >= 2){
372 nwa -= 150; /* pregap分 */
373 }
374 gap_len = Get4bytes(cpti->trackinfo.track_start) - nwa;
375 }
376 else if(sess_num != SESSION_NUMBER(&cpti->trackinfo)){
377 cpti = lcpti;
378 break;
379 }
380
381 if(strlen((char *)cpti->isrc)!=0){
382 ret = SetISRC(&cs, &num_cs, track_num, cpti);
383 if(ret != RET_OK){
384 return ret;
385 }
386 }
387 gap_2part = FALSE;
388 if(gap_len==0){
389 #if 1 /* こっちの方が良いかな? */
390 if(lcpti!=NULL){
391 gap_len = Get4bytes(cpti->trackinfo.track_start) -
392 (Get4bytes(lcpti->trackinfo.track_start) +
393 Get4bytes(lcpti->trackinfo.track_size));
394 if(IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)){
395 /* DATA */
396 if(!IS_TRACKMODE_DATA(lcpti->trackinfo.track_mode) ||
397 lcpti->mode2 != cpti->mode2){
398 /* 2part */
399 DebugLog("CreateCueSheet: Two part pregap.(cdda -> data)\n");
400 gap_2part = TRUE;
401 }
402 }
403 else{
404 /* AUDIO */
405 if(IS_TRACKMODE_DATA(lcpti->trackinfo.track_mode)){
406 /* 前回DATAの場合もかな? */
407 DebugLog("CreateCueSheet: Two part pregap.(data -> cdda)\n");
408 gap_2part = TRUE;
409 }
410 }
411 }
412 #else
413 if(!IS_TRACKMODE_DATA(cpti->trackinfo.track_mode)){
414 /* AUDIO */
415 gap_len = cpti->pause_len;
416 }
417 else if(lcpti!=NULL){
418 /* DATA で 2nd 以降 */
419 gap_len = 150;
420 if(!IS_TRACKMODE_DATA(lcpti->trackinfo.track_mode) ||
421 lcpti->mode2 != cpti->mode2){
422 /* 2part */
423 gap_len = 75+150;
424 gap_2part = TRUE;
425 }
426 }
427 #endif
428 }
429 nwa = Get4bytes(cpti->trackinfo.track_start) - gap_len;
430 ret = SetPreGap(&cs, &num_cs, track_num, lcpti, cpti,
431 gap_len, gap_2part, &nwa);
432 if(ret != RET_OK){
433 return ret;
434 }
435 /* Audio/Data */
436 ret = SetTrack(&cs, &num_cs, track_num, cpti, &nwa);
437 if(ret != RET_OK){
438 return ret;
439 }
440 }
441 /* Lead-out */
442 ret = SetLeadOut(&cs, &num_cs, cpti, nwa);
443 if(ret != RET_OK){
444 return ret;
445 }
446
447 *cs_ret = cs;
448 *numcs_ret = num_cs;
449 DebugLog("CreateCueSheet: Done.\n");
450 return RET_OK;
451 }
452

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26