#include <process.h>
#include <windows.h>
#define strcasecmp _stricmp
-#define usleep(x) (Sleep((x) / 1000))
#else
#include <pthread.h>
#include <sys/time.h>
static unsigned char cdbuffer[CD_FRAMESIZE_RAW];
static unsigned char subbuffer[SUB_FRAMESIZE];
-static unsigned char sndbuffer[CD_FRAMESIZE_RAW * 10];
-
-#define CDDA_FRAMETIME (1000 * (sizeof(sndbuffer) / CD_FRAMESIZE_RAW) / 75)
-
-#ifdef _WIN32
-static HANDLE threadid;
-#else
-static pthread_t threadid;
-#endif
-static unsigned int initial_offset = 0;
static boolean playing = FALSE;
static boolean cddaBigEndian = FALSE;
// cdda sectors in toc, byte offset in file
static unsigned int cdda_cur_sector;
-static unsigned int cdda_first_sector;
static unsigned int cdda_file_offset;
/* Frame offset into CD image where pregap data would be found if it was there.
* If a game seeks there we must *not* return subchannel data since it's
}
}
-#ifndef _WIN32
-static long GetTickCount(void) {
- static time_t initial_time = 0;
- struct timeval now;
-
- gettimeofday(&now, NULL);
-
- if (initial_time == 0) {
- initial_time = now.tv_sec;
- }
-
- return (now.tv_sec - initial_time) * 1000L + now.tv_usec / 1000L;
-}
-#endif
-
-// this thread plays audio data
-#ifdef _WIN32
-static void playthread(void *param)
-#else
-static void *playthread(void *param)
-#endif
-{
- long osleep, d, t, i, s;
- unsigned char tmp;
- int ret = 0, sector_offs;
-
- t = GetTickCount();
-
- while (playing) {
- s = 0;
- for (i = 0; i < sizeof(sndbuffer) / CD_FRAMESIZE_RAW; i++) {
- sector_offs = cdda_cur_sector - cdda_first_sector;
- if (sector_offs < 0) {
- d = CD_FRAMESIZE_RAW;
- memset(sndbuffer + s, 0, d);
- }
- else {
- d = cdimg_read_func(cddaHandle, cdda_file_offset,
- sndbuffer + s, sector_offs);
- if (d < CD_FRAMESIZE_RAW)
- break;
- }
-
- s += d;
- cdda_cur_sector++;
- }
-
- if (s == 0) {
- playing = FALSE;
- initial_offset = 0;
- break;
- }
-
- if (!cdr.Muted && playing) {
- if (cddaBigEndian) {
- for (i = 0; i < s / 2; i++) {
- tmp = sndbuffer[i * 2];
- sndbuffer[i * 2] = sndbuffer[i * 2 + 1];
- sndbuffer[i * 2 + 1] = tmp;
- }
- }
-
- // can't do it yet due to readahead..
- //cdrAttenuate((short *)sndbuffer, s / 4, 1);
- do {
- ret = SPU_playCDDAchannel((short *)sndbuffer, s);
- if (ret == 0x7761)
- {
- usleep(6 * 1000);
- }
- } while (ret == 0x7761 && playing); // rearmed_wait
- }
-
- if (ret != 0x676f) { // !rearmed_go
- // do approx sleep
- long now;
-
- // HACK: stop feeding data while emu is paused
- extern int stop;
- while (stop && playing)
- {
- usleep(10000);
- }
-
- now = GetTickCount();
- osleep = t - now;
- if (osleep <= 0) {
- osleep = 1;
- t = now;
- }
- else if (osleep > CDDA_FRAMETIME) {
- osleep = CDDA_FRAMETIME;
- t = now;
- }
-
- usleep(osleep * 1000);
- t += CDDA_FRAMETIME;
- }
-
- }
-
-#ifdef _WIN32
- _endthread();
-#else
- pthread_exit(0);
- return NULL;
-#endif
-}
-
-// stop the CDDA playback
-static void stopCDDA() {
- if (!playing) {
- return;
- }
-
- playing = FALSE;
-#ifdef _WIN32
- WaitForSingleObject(threadid, INFINITE);
-#else
- pthread_join(threadid, NULL);
-#endif
-}
-
-// start the CDDA playback
-static void startCDDA(void) {
- if (playing) {
- stopCDDA();
- }
-
- playing = TRUE;
-
-#ifdef _WIN32
- threadid = (HANDLE)_beginthread(playthread, 0, NULL);
-#else
- pthread_create(&threadid, NULL, playthread, NULL);
-#endif
-}
-
// this function tries to get the .toc file of the given .bin
// the necessary data is put into the ti (trackinformation)-array
static int parsetoc(const char *isofile) {
fclose(subHandle);
subHandle = NULL;
}
- stopCDDA();
cddaHandle = NULL;
if (compr_img != NULL) {
// plays cdda audio
// sector: byte 0 - minute; byte 1 - second; byte 2 - frame
// does NOT uses bcd format
-static long CALLBACK ISOplay(unsigned char *time) {
- unsigned int i;
-
- if (numtracks <= 1)
- return 0;
-
- // find the track
- cdda_cur_sector = msf2sec((char *)time);
- for (i = numtracks; i > 1; i--) {
- cdda_first_sector = msf2sec(ti[i].start);
- if (cdda_first_sector <= cdda_cur_sector + 2 * 75)
- break;
- }
- cdda_file_offset = ti[i].start_offset;
-
- // find the file that contains this track
- for (; i > 1; i--)
- if (ti[i].handle != NULL)
- break;
-
- cddaHandle = ti[i].handle;
-
- if (SPU_playCDDAchannel != NULL)
- startCDDA();
-
+static long CALLBACK ISOplay(void) {
+ playing = TRUE;
return 0;
}
// stops cdda audio
static long CALLBACK ISOstop(void) {
- stopCDDA();
+ playing = FALSE;
return 0;
}
cdrStruct cdr;
static unsigned char *pTransfer;
+static s16 read_buf[CD_FRAMESIZE_RAW/2];
/* CD-ROM magic numbers */
#define CdlSync 0
static void cdrPlayInterrupt_Autopause()
{
+ u32 abs_lev_max = 0;
+ boolean abs_lev_chselect;
+ u32 i;
+
if ((cdr.Mode & MODE_AUTOPAUSE) && cdr.TrackChanged) {
CDR_LOG( "CDDA STOP\n" );
StopCdda();
}
else if (((cdr.Mode & MODE_REPORT) || cdr.FastForward || cdr.FastBackward)) {
-
+ CDR_readCDDA(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], (u8 *)read_buf);
cdr.Result[0] = cdr.StatP;
cdr.Result[1] = cdr.subq.Track;
cdr.Result[2] = cdr.subq.Index;
+
+ abs_lev_chselect = cdr.subq.Absolute[1] & 0x01;
+
+ /* 8 is a hack. For accuracy, it should be 588. */
+ for (i = 0; i < 8; i++)
+ {
+ abs_lev_max = MAX_VALUE(abs_lev_max, abs(read_buf[i * 2 + abs_lev_chselect]));
+ }
+ abs_lev_max = MIN_VALUE(abs_lev_max, 32767);
+ abs_lev_max |= abs_lev_chselect << 15;
if (cdr.subq.Absolute[2] & 0x10) {
cdr.Result[3] = cdr.subq.Relative[0];
cdr.Result[5] = cdr.subq.Absolute[2];
}
- cdr.Result[6] = 0;
- cdr.Result[7] = 0;
+ cdr.Result[6] = abs_lev_max >> 0;
+ cdr.Result[7] = abs_lev_max >> 8;
// Rayman: Logo freeze (resultready + dataready)
cdr.ResultReady = 1;
cdrPlayInterrupt_Autopause();
if (!cdr.Play) return;
+
+ if (CDR_readCDDA && !cdr.Muted && cdr.Mode & MODE_REPORT) {
+ cdrAttenuate(read_buf, CD_FRAMESIZE_RAW / 4, 1);
+ if (SPU_playCDDAchannel)
+ SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW);
+ }
cdr.SetSectorPlay[2]++;
if (cdr.SetSectorPlay[2] == 75) {
cdr.TrackChanged = FALSE;
if (!Config.Cdda)
- CDR_play(cdr.SetSectorPlay);
+ CDR_play();
// Vib Ribbon: gameplay checks flag
cdr.StatP &= ~STATUS_SEEK;
Find_CurTrack(cdr.SetSectorPlay);
if (!Config.Cdda)
- CDR_play(cdr.SetSectorPlay);
+ CDR_play();
}
if ((cdr.freeze_ver & 0xffffff00) != 0x63647200) {