platform ps2, handle audio similar to psp
[picodrive.git] / pico / cd / cdd.c
CommitLineData
274fcc35 1/***************************************************************************************
2 * Genesis Plus
3 * CD drive processor & CD-DA fader
4 *
5 * Copyright (C) 2012-2013 Eke-Eke (Genesis Plus GX)
6 *
7 * Redistribution and use of this code or any derivative works are permitted
8 * provided that the following conditions are met:
9 *
10 * - Redistributions may not be sold, nor may they be used in a commercial
11 * product or activity.
12 *
13 * - Redistributions that are modified from the original source must include the
14 * complete source code, including the source code for all components used by a
15 * binary built from the modified sources. However, as a special exception, the
16 * source code distributed need not include anything that is normally distributed
17 * (in either source or binary form) with the major components (compiler, kernel,
18 * and so on) of the operating system on which the executable runs, unless that
19 * component itself accompanies the executable.
20 *
21 * - Redistributions must reproduce the above copyright notice, this list of
22 * conditions and the following disclaimer in the documentation and/or other
23 * materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ****************************************************************************************/
38
39#include "../pico_int.h"
40#include "genplus_macros.h"
15ca7152 41#include "cd_parse.h"
274fcc35 42#include "cdd.h"
43
44#ifdef USE_LIBTREMOR
45#define SUPPORTED_EXT 20
46#else
47#define SUPPORTED_EXT 10
48#endif
49
50cdd_t cdd;
51
02ff0254 52#define is_audio(index) \
53 (cdd.toc.tracks[index].type & CT_AUDIO)
54
274fcc35 55/* BCD conversion lookup tables */
56static const uint8 lut_BCD_8[100] =
57{
58 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
59 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
60 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
61 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
62 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
63 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
64 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
65 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
66 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
67 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
68};
69
70static const uint16 lut_BCD_16[100] =
71{
72 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
73 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109,
74 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209,
75 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309,
76 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409,
77 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509,
78 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607, 0x0608, 0x0609,
79 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x0708, 0x0709,
80 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809,
81 0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, 0x0909,
82};
83
84/* pre-build TOC */
85static const uint16 toc_snatcher[21] =
86{
87 56014, 495, 10120, 20555, 1580, 5417, 12502, 16090, 6553, 9681,
88 8148, 20228, 8622, 6142, 5858, 1287, 7424, 3535, 31697, 2485,
89 31380
90};
91
92static const uint16 toc_lunar[52] =
93{
94 5422, 1057, 7932, 5401, 6380, 6592, 5862, 5937, 5478, 5870,
95 6673, 6613, 6429, 4996, 4977, 5657, 3720, 5892, 3140, 3263,
96 6351, 5187, 3249, 1464, 1596, 1750, 1751, 6599, 4578, 5205,
97 1550, 1827, 2328, 1346, 1569, 1613, 7199, 4928, 1656, 2549,
98 1875, 3901, 1850, 2399, 2028, 1724, 4889, 14551, 1184, 2132,
99 685, 3167
100};
101
102static const uint32 toc_shadow[15] =
103{
104 10226, 70054, 11100, 12532, 12444, 11923, 10059, 10167, 10138, 13792,
105 11637, 2547, 2521, 3856, 900
106};
107
108static const uint32 toc_dungeon[13] =
109{
110 2250, 22950, 16350, 24900, 13875, 19950, 13800, 15375, 17400, 17100,
111 3325, 6825, 25275
112};
113
114static const uint32 toc_ffight[26] =
115{
116 11994, 9742, 10136, 9685, 9553, 14588, 9430, 8721, 9975, 9764,
117 9704, 12796, 585, 754, 951, 624, 9047, 1068, 817, 9191, 1024,
118 14562, 10320, 8627, 3795, 3047
119};
120
121static const uint32 toc_ffightj[29] =
122{
123 11994, 9752, 10119, 9690, 9567, 14575, 9431, 8731, 9965, 9763,
124 9716, 12791, 579, 751, 958, 630, 9050, 1052, 825, 9193, 1026,
125 14553, 9834, 10542, 1699, 1792, 1781, 3783, 3052
126};
127
ba11a481 128#if 0
274fcc35 129/* supported WAVE file header (16-bit stereo samples @44.1kHz) */
130static const unsigned char waveHeader[32] =
131{
132 0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,
133 0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61
134};
ba11a481 135#endif
274fcc35 136
137#ifdef USE_LIBTREMOR
138#ifdef DISABLE_MANY_OGG_OPEN_FILES
139static void ogg_free(int i)
140{
141 /* clear OGG file descriptor to prevent file from being closed */
142 cdd.toc.tracks[i].vf.datasource = NULL;
143
144 /* close VORBIS file structure */
145 ov_clear(&cdd.toc.tracks[i].vf);
146
147 /* indicates that the track is a seekable VORBIS file */
148 cdd.toc.tracks[i].vf.seekable = 1;
149
150 /* reset file reading position */
151 fseek(cdd.toc.tracks[i].fd, 0, SEEK_SET);
152}
153#endif
154#endif
155
156void cdd_reset(void)
157{
158 /* reset cycle counter */
159 cdd.cycles = 0;
160
161 /* reset drive access latency */
162 cdd.latency = 0;
163
164 /* reset track index */
ce5c904a 165 cdd.index = -1;
274fcc35 166
167 /* reset logical block address */
168 cdd.lba = 0;
169
170 /* reset status */
7b3ddc11 171 cdd.status = NO_DISC;
172
274fcc35 173 /* reset CD-DA fader (full volume) */
174 cdd.volume = 0x400;
175
176 /* clear CD-DA output */
177 cdd.audio[0] = cdd.audio[1] = 0;
178}
179
180/* FIXME: use cdd_read_audio() instead */
181static void cdd_change_track(int index, int lba)
182{
183 int i, base, lba_offset, lb_len;
184
4aaedc89 185 for (i = index; i >= 0; i--)
274fcc35 186 if (cdd.toc.tracks[i].fd != NULL)
187 break;
188
189 Pico_mcd->cdda_stream = cdd.toc.tracks[i].fd;
190 base = cdd.toc.tracks[index].offset;
191 lba_offset = lba - cdd.toc.tracks[index].start;
192 lb_len = cdd.toc.tracks[index].end - cdd.toc.tracks[index].start;
193
194 elprintf(EL_CD, "play #%d lba %d base %d", index, lba, base);
195
196 cdda_start_play(base, lba_offset, lb_len);
197}
198
44479027 199static off_t read_pos = -1;
274fcc35 200
44479027 201void cdd_seek(int index, int lba)
274fcc35 202{
44479027 203 int aindex = (index < 0 ? -index : index);
274fcc35 204
205#ifdef USE_LIBTREMOR
206#ifdef DISABLE_MANY_OGG_OPEN_FILES
44479027 207 /* check if track index has changed */
208 if (index != cdd.index)
274fcc35 209 {
44479027 210 /* close previous track VORBIS file structure to save memory */
211 if (cdd.index >= 0 && cdd.toc.tracks[cdd.index].vf.datasource)
212 {
213 ogg_free(cdd.index);
214 }
215
216 /* open current track VORBIS file */
217 if (cdd.toc.tracks[aindex].vf.seekable)
218 {
219 ov_open(cdd.toc.tracks[aindex].fd,&cdd.toc.tracks[aindex].vf,0,0);
220 }
274fcc35 221 }
222#endif
223#endif
224
44479027 225 /* update current track index and LBA */
226 cdd.index = aindex;
227 cdd.lba = lba;
274fcc35 228
44479027 229 /* stay within track limits when seeking files */
274fcc35 230 if (lba < cdd.toc.tracks[cdd.index].start)
231 {
232 lba = cdd.toc.tracks[cdd.index].start;
233 }
234
44479027 235 /* seek to current block */
02ff0254 236 if (!is_audio(cdd.index))
274fcc35 237 {
238 /* DATA track */
44479027 239 read_pos = lba * cdd.sectorSize;
240 pm_seek(cdd.toc.tracks[cdd.index].fd, read_pos, SEEK_SET);
274fcc35 241 }
242#ifdef USE_LIBTREMOR
243 else if (cdd.toc.tracks[cdd.index].vf.seekable)
244 {
274fcc35 245 /* VORBIS AUDIO track */
246 ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
247 }
248#endif
249#if 0
250 else if (cdd.toc.tracks[cdd.index].fd)
251 {
252 /* PCM AUDIO track */
253 fseek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
254 }
255#else
256 else
257 {
258 cdd_change_track(cdd.index, lba);
259 }
260#endif
44479027 261}
262
263int cdd_context_save(uint8 *state)
264{
265 int bufferptr = 0;
266
267 save_param(&cdd.cycles, sizeof(cdd.cycles));
268 save_param(&cdd.latency, sizeof(cdd.latency));
269 save_param(&cdd.index, sizeof(cdd.index));
270 save_param(&cdd.lba, sizeof(cdd.lba));
271 save_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
272 save_param(&cdd.volume, sizeof(cdd.volume));
273 save_param(&cdd.status, sizeof(cdd.status));
274
275 return bufferptr;
276}
277
278int cdd_context_load(uint8 *state)
279{
280 int bufferptr = 0;
281
282 load_param(&cdd.cycles, sizeof(cdd.cycles));
283 load_param(&cdd.latency, sizeof(cdd.latency));
284 load_param(&cdd.index, sizeof(cdd.index));
285 load_param(&cdd.lba, sizeof(cdd.lba));
286 load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
287 load_param(&cdd.volume, sizeof(cdd.volume));
288 load_param(&cdd.status, sizeof(cdd.status));
289
290 /* seek to current track position */
291 cdd_seek(-cdd.index, cdd.lba);
274fcc35 292
293 return bufferptr;
294}
295
296int cdd_context_load_old(uint8 *state)
297{
298 memcpy(&cdd.lba, state + 8, sizeof(cdd.lba));
44479027 299 cdd_seek(-cdd.index, cdd.lba);
300
274fcc35 301 return 12 * 4;
302}
303
304int cdd_load(const char *filename, int type)
305{
306 char header[0x210];
307 int ret;
308
309 /* first unmount any loaded disc */
310 cdd_unload();
311
312 /* genplus parses cue here, in PD we use our own parser */
313 ret = load_cd_image(filename, &type);
314 if (ret != 0)
315 return ret;
316
317 /* read first 16 bytes */
318 pm_read(header, 0x10, cdd.toc.tracks[0].fd);
319
320 /* look for valid CD image ID string */
321 if (memcmp("SEGADISCSYSTEM", header, 14))
322 {
323 /* if not found, read next 16 bytes */
324 pm_read(header, 0x10, cdd.toc.tracks[0].fd);
325
326 /* look again for valid CD image ID string */
327 if (memcmp("SEGADISCSYSTEM", header, 14))
328 {
329 elprintf(EL_STATUS|EL_ANOMALY, "cd: bad cd image?");
330 /* assume bin without security code */
331 }
332
333 /* BIN format (2352 bytes data blocks) */
334 cdd.sectorSize = 2352;
335 }
336 else
337 {
338 /* ISO format (2048 bytes data blocks) */
339 cdd.sectorSize = 2048;
340 }
341
02ff0254 342 ret = (type == CT_ISO ? 2048 : 2352);
274fcc35 343 if (ret != cdd.sectorSize)
344 elprintf(EL_STATUS|EL_ANOMALY, "cd: type detection mismatch");
15ca7152 345 pm_sectorsize(cdd.sectorSize, cdd.toc.tracks[0].fd);
274fcc35 346
347 /* read CD image header + security code */
348 pm_read(header + 0x10, 0x200, cdd.toc.tracks[0].fd);
349
350 /* Simulate audio tracks if none found */
351 if (cdd.toc.last == 1)
352 {
353 /* Some games require exact TOC infos */
354 if (strstr(header + 0x180,"T-95035") != NULL)
355 {
356 /* Snatcher */
357 cdd.toc.last = cdd.toc.end = 0;
358 do
359 {
360 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
361 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_snatcher[cdd.toc.last];
362 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
363 cdd.toc.last++;
364 }
365 while (cdd.toc.last < 21);
366 }
367 else if (strstr(header + 0x180,"T-127015") != NULL)
368 {
369 /* Lunar - The Silver Star */
370 cdd.toc.last = cdd.toc.end = 0;
371 do
372 {
373 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
374 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_lunar[cdd.toc.last];
375 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
376 cdd.toc.last++;
377 }
378 while (cdd.toc.last < 52);
379 }
380 else if (strstr(header + 0x180,"T-113045") != NULL)
381 {
382 /* Shadow of the Beast II */
383 cdd.toc.last = cdd.toc.end = 0;
384 do
385 {
386 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
387 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_shadow[cdd.toc.last];
388 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
389 cdd.toc.last++;
390 }
391 while (cdd.toc.last < 15);
392 }
393 else if (strstr(header + 0x180,"T-143025") != NULL)
394 {
395 /* Dungeon Explorer */
396 cdd.toc.last = cdd.toc.end = 0;
397 do
398 {
399 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
400 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_dungeon[cdd.toc.last];
401 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
402 cdd.toc.last++;
403 }
404 while (cdd.toc.last < 13);
405 }
406 else if (strstr(header + 0x180,"MK-4410") != NULL)
407 {
408 /* Final Fight CD (USA, Europe) */
409 cdd.toc.last = cdd.toc.end = 0;
410 do
411 {
412 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
413 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffight[cdd.toc.last];
414 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
415 cdd.toc.last++;
416 }
417 while (cdd.toc.last < 26);
418 }
419 else if (strstr(header + 0x180,"G-6013") != NULL)
420 {
421 /* Final Fight CD (Japan) */
422 cdd.toc.last = cdd.toc.end = 0;
423 do
424 {
425 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
426 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffightj[cdd.toc.last];
427 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
428 cdd.toc.last++;
429 }
430 while (cdd.toc.last < 29);
431 }
432#if 0
433 else
434 {
435 /* default TOC (99 tracks & 2s per audio tracks) */
436 do
437 {
438 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + 2*75;
439 cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + 2*75;
440 cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
441 cdd.toc.last++;
442 }
443 while ((cdd.toc.last < 99) && (cdd.toc.end < 56*60*75));
444 }
445#endif
446 }
447
448 /* Lead-out */
449 cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
450
451 /* CD loaded */
452 cdd.loaded = 1;
7b3ddc11 453
454 /* disc not scanned yet */
455 cdd.status = NO_DISC;
456
274fcc35 457 return 0;
458}
459
460int cdd_unload(void)
461{
462 int was_loaded = cdd.loaded;
463
464 if (cdd.loaded)
465 {
466 int i;
467
7e77080f 468 /* stop audio streaming */
469 Pico_mcd->cdda_stream = NULL;
470
274fcc35 471 /* close CD tracks */
472 if (cdd.toc.tracks[0].fd)
473 {
474 pm_close(cdd.toc.tracks[0].fd);
475 cdd.toc.tracks[0].fd = NULL;
15ca7152 476 if (cdd.toc.tracks[0].fname)
ef3241d2 477 free(cdd.toc.tracks[0].fname);
15ca7152 478 cdd.toc.tracks[0].fname = NULL;
274fcc35 479 }
480
481 for (i = 1; i < cdd.toc.last; i++)
482 {
483#ifdef USE_LIBTREMOR
484 if (cdd.toc.tracks[i].vf.datasource)
485 {
486 /* close VORBIS file (if still opened) */
487 ov_clear(&cdd.toc.tracks[i].vf);
488 }
489 else
490#endif
491 if (cdd.toc.tracks[i].fd)
492 {
493 /* close file */
494 if (Pico_mcd->cdda_type == CT_MP3)
495 fclose(cdd.toc.tracks[i].fd);
496 else
15ca7152 497 pm_close(cdd.toc.tracks[i].fd);
498 cdd.toc.tracks[i].fd = NULL;
499 if (cdd.toc.tracks[i].fname)
ef3241d2 500 free(cdd.toc.tracks[i].fname);
15ca7152 501 cdd.toc.tracks[i].fname = NULL;
274fcc35 502
503 /* detect single file images */
504 if (cdd.toc.tracks[i+1].fd == cdd.toc.tracks[i].fd)
505 {
506 /* exit loop */
507 i = cdd.toc.last;
508 }
509 }
510 }
511
512 /* CD unloaded */
513 cdd.loaded = 0;
7b3ddc11 514
515 if (cdd.status != CD_OPEN)
516 cdd.status = NO_DISC;
274fcc35 517 }
518
519 /* reset TOC */
520 memset(&cdd.toc, 0x00, sizeof(cdd.toc));
521
522 /* unknown CD image file format */
523 cdd.sectorSize = 0;
524
525 return was_loaded;
526}
527
528void cdd_read_data(uint8 *dst)
529{
530 /* only read DATA track sectors */
44479027 531 if (!is_audio(cdd.index) && (cdd.lba >= cdd.toc.tracks[cdd.index].start) &&
532 (cdd.lba < cdd.toc.tracks[cdd.index].end))
274fcc35 533 {
44479027 534 off_t pos;
535
274fcc35 536 /* BIN format ? */
537 if (cdd.sectorSize == 2352)
538 {
539 /* skip 16-byte header */
44479027 540 pos = cdd.lba * 2352 + 16;
541 }
542 else
543 {
544 pos = cdd.lba * cdd.sectorSize;
545 }
546
547 if (pos != read_pos) {
548 pm_seek(cdd.toc.tracks[cdd.index].fd, pos, SEEK_SET);
549 read_pos = pos;
274fcc35 550 }
551
552 /* read sector data (Mode 1 = 2048 bytes) */
44479027 553 read_pos += pm_read(dst, 2048, cdd.toc.tracks[cdd.index].fd);
274fcc35 554 }
555}
556
557#if 0
558void cdd_read_audio(unsigned int samples)
559{
560 /* previous audio outputs */
561 int16 l = cdd.audio[0];
562 int16 r = cdd.audio[1];
563
564 /* get number of internal clocks (samples) needed */
565 samples = blip_clocks_needed(blip[0], samples);
566
567 /* audio track playing ? */
f47d0a28 568 if (!Pico_mcd->s68k_regs[0x36+0] && cdd.toc.tracks[cdd.index].fd)
274fcc35 569 {
570 int i, mul, delta;
571
572 /* current CD-DA fader volume */
573 int curVol = cdd.volume;
574
575 /* CD-DA fader volume setup (0-1024) */
576 int endVol = Pico_mcd->regs[0x34>>1].w >> 4;
577
578 /* read samples from current block */
579#ifdef USE_LIBTREMOR
580 if (cdd.toc.tracks[cdd.index].vf.datasource)
581 {
582 int len, done = 0;
583 int16 *ptr = (int16 *) (cdc.ram);
584 samples = samples * 4;
585 while (done < samples)
586 {
587 len = ov_read(&cdd.toc.tracks[cdd.index].vf, (char *)(cdc.ram + done), samples - done, 0);
588 if (len <= 0)
589 {
590 done = samples;
591 break;
592 }
593 done += len;
594 }
595 samples = done / 4;
596
597 /* process 16-bit (host-endian) stereo samples */
598 for (i=0; i<samples; i++)
599 {
600 /* CD-DA fader multiplier (cf. LC7883 datasheet) */
601 /* (MIN) 0,1,2,3,4,8,12,16,20...,1020,1024 (MAX) */
602 mul = (curVol & 0x7fc) ? (curVol & 0x7fc) : (curVol & 0x03);
603
604 /* left channel */
605 delta = ((ptr[0] * mul) / 1024) - l;
606 ptr++;
607 l += delta;
608 blip_add_delta_fast(blip[0], i, delta);
609
610 /* right channel */
611 delta = ((ptr[0] * mul) / 1024) - r;
612 ptr++;
613 r += delta;
614 blip_add_delta_fast(blip[1], i, delta);
615
616 /* update CD-DA fader volume (one step/sample) */
617 if (curVol < endVol)
618 {
619 /* fade-in */
620 curVol++;
621 }
622 else if (curVol > endVol)
623 {
624 /* fade-out */
625 curVol--;
626 }
627 else if (!curVol)
628 {
629 /* audio will remain muted until next setup */
630 break;
631 }
632 }
633 }
634 else
635#endif
636 {
637#ifdef LSB_FIRST
638 int16 *ptr = (int16 *) (cdc.ram);
639#else
640 uint8 *ptr = cdc.ram;
641#endif
642 fread(cdc.ram, 1, samples * 4, cdd.toc.tracks[cdd.index].fd);
643
644 /* process 16-bit (little-endian) stereo samples */
645 for (i=0; i<samples; i++)
646 {
647 /* CD-DA fader multiplier (cf. LC7883 datasheet) */
648 /* (MIN) 0,1,2,3,4,8,12,16,20...,1020,1024 (MAX) */
649 mul = (curVol & 0x7fc) ? (curVol & 0x7fc) : (curVol & 0x03);
650
651 /* left channel */
652 #ifdef LSB_FIRST
653 delta = ((ptr[0] * mul) / 1024) - l;
654 ptr++;
655 #else
656 delta = (((int16)((ptr[0] + ptr[1]*256)) * mul) / 1024) - l;
657 ptr += 2;
658 #endif
659 l += delta;
660 blip_add_delta_fast(blip[0], i, delta);
661
662 /* right channel */
663 #ifdef LSB_FIRST
664 delta = ((ptr[0] * mul) / 1024) - r;
665 ptr++;
666 #else
667 delta = (((int16)((ptr[0] + ptr[1]*256)) * mul) / 1024) - r;
668 ptr += 2;
669 #endif
670 r += delta;
671 blip_add_delta_fast(blip[1], i, delta);
672
673 /* update CD-DA fader volume (one step/sample) */
674 if (curVol < endVol)
675 {
676 /* fade-in */
677 curVol++;
678 }
679 else if (curVol > endVol)
680 {
681 /* fade-out */
682 curVol--;
683 }
684 else if (!curVol)
685 {
686 /* audio will remain muted until next setup */
687 break;
688 }
689 }
690 }
691
692 /* save current CD-DA fader volume */
693 cdd.volume = curVol;
694
695 /* save last audio output for next frame */
696 cdd.audio[0] = l;
697 cdd.audio[1] = r;
698 }
699 else
700 {
701 /* no audio output */
702 if (l) blip_add_delta_fast(blip[0], 0, -l);
703 if (r) blip_add_delta_fast(blip[1], 0, -r);
704
705 /* save audio output for next frame */
706 cdd.audio[0] = 0;
707 cdd.audio[1] = 0;
708 }
709
710 /* end of Blip Buffer timeframe */
711 blip_end_frame(blip[0], samples);
712 blip_end_frame(blip[1], samples);
713}
714#endif
715
716
717void cdd_update(void)
718{
719#ifdef LOG_CDD
720