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