Пример #1
0
static DWORD MSF_Add(DWORD d1, DWORD d2)
{
    WORD c, m, s, f;
    f = MCI_MSF_FRAME(d1)  + MCI_MSF_FRAME(d2);
    c = f / CDFRAMES_PERSEC;
    f = f % CDFRAMES_PERSEC;
    s = MCI_MSF_SECOND(d1) + MCI_MSF_SECOND(d2) + c;
    c = s / 60;
    s = s % 60;
    m = MCI_MSF_MINUTE(d1) + MCI_MSF_MINUTE(d2) + c; /* may be > 60 */
    return MCI_MAKE_MSF(m,s,f);
}
Пример #2
0
bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) {
	*position = 0;

	DWORD flags = MCI_STATUS_ITEM | MCI_WAIT;

	MCI_STATUS_PARMS mci_status;
	mci_status.dwItem = MCI_STATUS_MODE;
	if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) return true;
	switch (mci_status.dwReturn) {
		case MCI_MODE_NOT_READY:
		case MCI_MODE_OPEN:
		case MCI_MODE_STOP:
			return true;	// not ready/undefined status
		case MCI_MODE_PLAY:
		case MCI_MODE_PAUSE:
			mci_status.dwItem = MCI_STATUS_POSITION;
			if (!mci_CDioctl(MCI_STATUS, flags, &mci_status)) {
				*position = MSF_TO_FRAMES(
					MCI_MSF_MINUTE(mci_status.dwReturn),
					MCI_MSF_SECOND(mci_status.dwReturn),
					MCI_MSF_FRAME(mci_status.dwReturn));
			}
			return false;	// no error, position read
		default:
			break;
	}
	return false;
}
Пример #3
0
int PlatPlayCDDA(int track)
{
	DWORD dwReturn;
    MCI_SET_PARMS mciSetParms = {0,0,0};
    MCI_PLAY_PARMS mciPlayParms = {0,0,0};
	MCI_STATUS_PARMS mciStatusParms = {0,0,0,0};

    /* check the cdDeviceId */
    if(cdDeviceID==NO_DEVICE) return SOUND_PLATFORMERROR;
    
    /* set the time format */
	mciSetParms.dwTimeFormat = MCI_FORMAT_MSF;
	dwReturn = mciSendCommand((UINT)cdDeviceID,MCI_SET,MCI_SET_TIME_FORMAT,(DWORD)(LPVOID) &mciSetParms);
	if(dwReturn)
	{
//    	NewOnScreenMessage("CD ERROR - TIME FORMAT");
    	/* error */
    	return SOUND_PLATFORMERROR;
	}  
	
	/* find the length of the track... */
	mciStatusParms.dwItem = MCI_STATUS_LENGTH;
	mciStatusParms.dwTrack = track;
    dwReturn = mciSendCommand((UINT)cdDeviceID,MCI_STATUS,MCI_STATUS_ITEM|MCI_TRACK,(DWORD)(LPVOID)&mciStatusParms);
	if(dwReturn)
	{
    	/* error */
//    	NewOnScreenMessage("CD ERROR - GET LENGTH");
    	return SOUND_PLATFORMERROR;
	}  

    /* set the time format */
	mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
	dwReturn = mciSendCommand((UINT)cdDeviceID,MCI_SET,MCI_SET_TIME_FORMAT,(DWORD)(LPVOID) &mciSetParms);
	if(dwReturn)
	{
    	/* error */
//    	NewOnScreenMessage("CD ERROR - TIME FORMAT");
    	return SOUND_PLATFORMERROR;
	}  

	/* play the track: set up for notification when track finishes, or an error occurs */ 
    mciPlayParms.dwFrom=MCI_MAKE_TMSF(track,0,0,0);
    mciPlayParms.dwTo=MCI_MAKE_TMSF(track,	MCI_MSF_MINUTE(mciStatusParms.dwReturn),
    										MCI_MSF_SECOND(mciStatusParms.dwReturn),
    										MCI_MSF_FRAME(mciStatusParms.dwReturn));
    mciPlayParms.dwCallback=(DWORD)hWndMain;
    dwReturn = mciSendCommand((UINT)cdDeviceID,MCI_PLAY,MCI_FROM|MCI_TO|MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);
	if(dwReturn)
    {
    	/* error */
//    	NewOnScreenMessage("CD ERROR - PLAY");
    	return SOUND_PLATFORMERROR;
    }
    return 0;
}
Пример #4
0
/**************************************************************************
 * 			MCICDA_CalcFrame			[internal]
 */
static DWORD MCICDA_CalcFrame(WINE_MCICDAUDIO* wmcda, DWORD dwTime)
{
    DWORD	dwFrame = 0;
    UINT	wTrack;
    CDROM_TOC   toc;
    DWORD       br;
    BYTE*       addr;

    TRACE("(%p, %08X, %u);\n", wmcda, wmcda->dwTimeFormat, dwTime);

    switch (wmcda->dwTimeFormat) {
    case MCI_FORMAT_MILLISECONDS:
	dwFrame = ((dwTime - 1) * CDFRAMES_PERSEC + 500) / 1000;
	TRACE("MILLISECONDS %u\n", dwFrame);
	break;
    case MCI_FORMAT_MSF:
	TRACE("MSF %02u:%02u:%02u\n",
	      MCI_MSF_MINUTE(dwTime), MCI_MSF_SECOND(dwTime), MCI_MSF_FRAME(dwTime));
	dwFrame += CDFRAMES_PERMIN * MCI_MSF_MINUTE(dwTime);
	dwFrame += CDFRAMES_PERSEC * MCI_MSF_SECOND(dwTime);
	dwFrame += MCI_MSF_FRAME(dwTime);
	break;
    case MCI_FORMAT_TMSF:
    default: /* unknown format ! force TMSF ! ... */
	wTrack = MCI_TMSF_TRACK(dwTime);
        if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
                             &toc, sizeof(toc), &br, NULL))
            return 0;
        if (wTrack < toc.FirstTrack || wTrack > toc.LastTrack)
            return 0;
        TRACE("MSF %02u-%02u:%02u:%02u\n",
              MCI_TMSF_TRACK(dwTime), MCI_TMSF_MINUTE(dwTime),
              MCI_TMSF_SECOND(dwTime), MCI_TMSF_FRAME(dwTime));
        addr = toc.TrackData[wTrack - toc.FirstTrack].Address;
        TRACE("TMSF trackpos[%u]=%d:%d:%d\n",
              wTrack, addr[1], addr[2], addr[3]);
        dwFrame = CDFRAMES_PERMIN * (addr[1] + MCI_TMSF_MINUTE(dwTime)) +
            CDFRAMES_PERSEC * (addr[2] + MCI_TMSF_SECOND(dwTime)) +
            addr[3] + MCI_TMSF_FRAME(dwTime);
	break;
    }
    return dwFrame;
}
Пример #5
0
long cdrom_notification_routine ( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{

	if ( cdrom_track_repeat )
	{

		MCI_PLAY_PARMS
			play_parameters;

		MCI_STATUS_PARMS
			status_parameters;

		DWORD
			value;

		status_parameters.dwItem = MCI_STATUS_LENGTH;
		status_parameters.dwTrack = cdrom_track_playing;

		value = mciSendCommand ( cdrom_device_id, MCI_STATUS, ( MCI_TRACK | MCI_STATUS_ITEM ), ( DWORD ) ( LPVOID ) &status_parameters );

		if ( !value )
		{

			int
				minutes,
				seconds,
				frames;
	
			minutes = MCI_MSF_MINUTE ( status_parameters.dwReturn ),
			seconds = MCI_MSF_SECOND ( status_parameters.dwReturn ),
			frames = MCI_MSF_FRAME ( status_parameters.dwReturn ),
	
			play_parameters.dwFrom = 0;
			play_parameters.dwTo = 0;
			play_parameters.dwFrom = MCI_MAKE_TMSF ( cdrom_track_playing, 0, 0, 0 );
			play_parameters.dwTo = MCI_MAKE_TMSF ( cdrom_track_playing, minutes, seconds, frames );
			play_parameters.dwCallback = ( DWORD ) application_window;
	
			mciSendCommand ( cdrom_device_id, MCI_PLAY, ( MCI_FROM | MCI_TO | MCI_NOTIFY ), ( DWORD ) ( LPVOID ) &play_parameters );
		}
	}
	else
	{

		cdrom_audio_track_playing = FALSE;
	}

	return ( TRUE );
}
Пример #6
0
static void test_play(HWND hwnd)
{
    MCIDEVICEID wDeviceID;
    MCI_PARMS_UNION parm;
    MCIERROR err, ok_hw;
    DWORD numtracks, track, duration;
    DWORD factor = winetest_interactive ? 3 : 1;
    char buf[1024];
    memset(buf, 0, sizeof(buf));
    parm.gen.dwCallback = (DWORD_PTR)hwnd; /* once to rule them all */

    err = mciSendString("open cdaudio alias c notify shareable", buf, sizeof(buf), hwnd);
    ok(!err || err == MCIERR_CANNOT_LOAD_DRIVER || err == MCIERR_MUST_USE_SHAREABLE,
       "mci open cdaudio notify returned %s\n", dbg_mcierr(err));
    test_notification(hwnd, "open alias notify", err ? 0 : MCI_NOTIFY_SUCCESSFUL);
    /* Native returns MUST_USE_SHAREABLE when there's trouble with the hardware
     * (e.g. unreadable disk) or when Media Player already has the device open,
     * yet adding that flag does not help get past this error. */

    if(err) {
        skip("Cannot open any cdaudio device, %s.\n", dbg_mcierr(err));
        return;
    }
    wDeviceID = atoi(buf);
    ok(!strcmp(buf,"1"), "mci open deviceId: %s, expected 1\n", buf);

    err = mciSendString("capability c has video notify", buf, sizeof(buf), hwnd);
    ok(!err, "capability video: %s\n", dbg_mcierr(err));
    if(!err) ok(!strcmp(buf, "false"), "capability video is %s\n", buf);
    test_notification(hwnd, "capability notify", MCI_NOTIFY_SUCCESSFUL);

    err = mciSendString("capability c can play", buf, sizeof(buf), hwnd);
    ok(!err, "capability video: %s\n", dbg_mcierr(err));
    if(!err) ok(!strcmp(buf, "true"), "capability play is %s\n", buf);

    err = mciSendString("capability c", buf, sizeof(buf), NULL);
    ok(err == MCIERR_MISSING_PARAMETER, "capability nokeyword: %s\n", dbg_mcierr(err));

    parm.caps.dwItem = 0x4001;
    parm.caps.dwReturn = 0xFEEDABAD;
    err = mciSendCommand(wDeviceID, MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM, (DWORD_PTR)&parm);
    ok(err == MCIERR_UNSUPPORTED_FUNCTION, "GETDEVCAPS %x: %s\n", parm.caps.dwItem, dbg_mcierr(err));

    parm.caps.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
    err = mciSendCommand(wDeviceID, MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM, (DWORD_PTR)&parm);
    ok(!err, "GETDEVCAPS device type: %s\n", dbg_mcierr(err));
    if(!err) ok( parm.caps.dwReturn == MCI_DEVTYPE_CD_AUDIO, "getdevcaps device type: %u\n", parm.caps.dwReturn);

    err = mciSendCommand(wDeviceID, MCI_RECORD, 0, (DWORD_PTR)&parm);
    ok(err == MCIERR_UNSUPPORTED_FUNCTION, "MCI_RECORD: %s\n", dbg_mcierr(err));

    /* Wine's MCI_MapMsgAtoW crashes on MCI_SAVE without parm->lpfilename */
    parm.save.lpfilename = "foo";
    err = mciSendCommand(wDeviceID, MCI_SAVE, 0, (DWORD_PTR)&parm);
    ok(err == MCIERR_UNSUPPORTED_FUNCTION, "MCI_SAVE: %s\n", dbg_mcierr(err));

    /* commands from the core set are UNSUPPORTED, others UNRECOGNIZED */
    err = mciSendCommand(wDeviceID, MCI_STEP, 0, (DWORD_PTR)&parm);
    ok(err == MCIERR_UNRECOGNIZED_COMMAND, "MCI_STEP: %s\n", dbg_mcierr(err));

    parm.status.dwItem = MCI_STATUS_TIME_FORMAT;
    parm.status.dwReturn = 0xFEEDABAD;
    err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm);
    ok(!err, "STATUS time format: %s\n", dbg_mcierr(err));
    if(!err) ok(parm.status.dwReturn == MCI_FORMAT_MSF, "status time default format: %ld\n", parm.status.dwReturn);

    /* "CD-Audio" */
    err = mciSendString("info c product wait notify", buf, sizeof(buf), hwnd);
    ok(!err, "info product: %s\n", dbg_mcierr(err));
    test_notification(hwnd, "info notify", err ? 0 : MCI_NOTIFY_SUCCESSFUL);

    parm.status.dwItem = MCI_STATUS_MEDIA_PRESENT;
    parm.status.dwReturn = 0xFEEDABAD;
    err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm);
    ok(err || parm.status.dwReturn == TRUE || parm.status.dwReturn == FALSE,
       "STATUS media present: %s\n", dbg_mcierr(err));

    if (parm.status.dwReturn != TRUE) {
        skip("No CD-ROM in drive.\n");
        return;
    }

    parm.status.dwItem = MCI_STATUS_MODE;
    err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm);
    ok(!err, "STATUS mode: %s\n", dbg_mcierr(err));
    switch(parm.status.dwReturn) {
    case MCI_MODE_NOT_READY:
        skip("CD-ROM mode not ready (DVD in drive?)\n");
        return;
    case MCI_MODE_OPEN: /* should not happen with MEDIA_PRESENT */
        skip("CD-ROM drive is open\n");
        /* set door closed may not work. */
        return;
    default: /* play/record/seek/pause */
        ok(parm.status.dwReturn==MCI_MODE_STOP, "STATUS mode is %lx\n", parm.status.dwReturn);
        /* fall through */
    case MCI_MODE_STOP: /* normal */
        break;
    }

    /* Initial mode is "stopped" with a CD in drive */
    err = mciSendString("status c mode", buf, sizeof(buf), hwnd);
    ok(!err, "status mode: %s\n", dbg_mcierr(err));
    if(!err) ok(!strcmp(buf, "stopped"), "status mode is initially %s\n", buf);

    err = mciSendString("status c ready", buf, sizeof(buf), hwnd);
    ok(!err, "status ready: %s\n", dbg_mcierr(err));
    if(!err) ok(!strcmp(buf, "true"), "status ready with media is %s\n", buf);

    err = mciSendString("info c product identity", buf, sizeof(buf), hwnd);
    ok(!err, "info 2flags: %s\n", dbg_mcierr(err)); /* not MCIERR_FLAGS_NOT_COMPATIBLE */
    /* Precedence rule p>u>i verified experimentally, not tested here. */

    err = mciSendString("info c identity", buf, sizeof(buf), hwnd);
    ok(!err || err == MCIERR_HARDWARE, "info identity: %s\n", dbg_mcierr(err));
    /* a blank disk causes MCIERR_HARDWARE and other commands to fail likewise. */
    ok_hw = err;

    err = mciSendString("info c upc", buf, sizeof(buf), hwnd);
    ok(err == ok_hw || err == MCIERR_NO_IDENTITY, "info upc: %s\n", dbg_mcierr(err));

    parm.status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
    parm.status.dwReturn = 0;
    err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm);
    ok(err == ok_hw, "STATUS number of tracks: %s\n", dbg_mcierr(err));
    numtracks = parm.status.dwReturn;
    /* cf. MAXIMUM_NUMBER_TRACKS */
    ok(0 < numtracks && numtracks <= 99, "number of tracks=%ld\n", parm.status.dwReturn);

    err = mciSendString("status c length", buf, sizeof(buf), hwnd);
    ok(err == ok_hw, "status length: %s\n", dbg_mcierr(err));
    if(!err) trace("CD length %s\n", buf);

    if(err) { /* MCIERR_HARDWARE when given a blank disk */
        skip("status length %s (blank disk?)\n", dbg_mcierr(ok_hw));
        return;
    }

    /* Linux leaves the drive at some random position,
     * native initialises to the start position below. */
    err = mciSendString("status c position", buf, sizeof(buf), hwnd);
    ok(!err, "status position: %s\n", dbg_mcierr(err));
    if(!err) todo_wine ok(!strcmp(buf, "00:02:00") || !strcmp(buf, "00:02:33") || !strcmp(buf, "00:03:00"),
                "status position initially %s\n", buf);
    /* 2 seconds is the initial position even with data tracks. */

    err = mciSendString("status c position start notify", buf, sizeof(buf), hwnd);
    ok(err == ok_hw, "status position start: %s\n", dbg_mcierr(err));
    if(!err) ok(!strcmp(buf, "00:02:00") || !strcmp(buf, "00:02:33") || !strcmp(buf, "00:03:00"),
                "status position start %s\n", buf);
    test_notification(hwnd, "status notify", err ? 0 : MCI_NOTIFY_SUCCESSFUL);

    err = mciSendString("status c position start track 1 notify", buf, sizeof(buf), hwnd);
    ok(err == MCIERR_FLAGS_NOT_COMPATIBLE, "status position start: %s\n", dbg_mcierr(err));
    test_notification(hwnd, "status 2flags", err ? 0 : MCI_NOTIFY_SUCCESSFUL);

    err = mciSendString("play c from 00:02:00 to 00:01:00 notify", buf, sizeof(buf), hwnd);
    todo_wine ok(err == MCIERR_OUTOFRANGE, "play 2s to 1s: %s\n", dbg_mcierr(err));
    test_notification(hwnd, "play 2s to 1s", err ? 0 : MCI_NOTIFY_SUCCESSFUL);

    err = mciSendString("resume c", buf, sizeof(buf), hwnd);
    ok(err == MCIERR_HARDWARE || /* Win9x */ err == MCIERR_UNSUPPORTED_FUNCTION,
       "resume without play: %s\n", dbg_mcierr(err)); /* not NONAPPLICABLE_FUNCTION */
    /* vmware with a .iso (data-only) yields no error on NT/w2k */

    err = mciSendString("seek c wait", buf, sizeof(buf), hwnd);
    ok(err == MCIERR_MISSING_PARAMETER, "seek noflag: %s\n", dbg_mcierr(err));

    err = mciSendString("seek c to start to end", buf, sizeof(buf), hwnd);
    ok(err == MCIERR_FLAGS_NOT_COMPATIBLE || broken(!err), "seek to start+end: %s\n", dbg_mcierr(err));
    /* Win9x only errors out with Seek to start to <position> */

    /* set Wine to a defined position before play */
    err = mciSendString("seek c to start notify", buf, sizeof(buf), hwnd);
    ok(!err, "seek to start: %s\n", dbg_mcierr(err));
    test_notification(hwnd, "seek to start", err ? 0 : MCI_NOTIFY_SUCCESSFUL);
    /* Win9X Status position / current track then sometimes report the end position / track! */

    err = mciSendString("status c mode", buf, sizeof(buf), hwnd);
    ok(!err, "status mode: %s\n", dbg_mcierr(err));
    if(!err) ok(!strcmp(buf, "stopped"), "status mode after seek is %s\n", buf);

    /* MCICDA ignores MCI_SET_VIDEO
     * One xp machine ignored SET_AUDIO, one w2k and one w7 machine honoured it
     * and simultaneously toggled the mute button in the mixer control panel.
     * Or does it only depend on the HW, not the OS? */
    err = mciSendString("set c video audio all on", buf, sizeof(buf), hwnd);
    ok(!err, "set video/audio: %s\n", dbg_mcierr(err));

    err = mciSendString("set c time format ms", buf, sizeof(buf), hwnd);
    ok(!err, "set time format ms: %s\n", dbg_mcierr(err));

    memset(buf, 0, sizeof(buf));
    err = mciSendString("status c position start", buf, sizeof(buf), hwnd);
    ok(!err, "status position start (ms): %s\n", dbg_mcierr(err));
    duration = atoi(buf);
    if(!err) ok(duration > 2000, "status position initially %sms\n", buf);
    /* 00:02:00 corresponds to 2001 ms, 02:33 -> 2441 etc. */

    err = mciSendString("status c position start track 1", buf, sizeof(buf), hwnd);
    ok(err == MCIERR_FLAGS_NOT_COMPATIBLE, "status position start+track: %s\n", dbg_mcierr(err));

    err = mciSendString("status c notify wait", buf, sizeof(buf), hwnd);
    ok(err == MCIERR_MISSING_PARAMETER, "status noflag: %s\n", dbg_mcierr(err));

    err = mciSendString("status c length track 1", buf, sizeof(buf), hwnd);
    ok(!err, "status length (ms): %s\n", dbg_mcierr(err));
    if(!err) {
        trace("track #1 length %sms\n", buf);
        duration = atoi(buf);
    } else duration = 2001; /* for the position test below */

    if (0) { /* causes some native systems to return Seek and Play with MCIERR_HARDWARE */
        /* depending on capability can eject only? */
        err = mciSendString("set c door closed notify", buf, sizeof(buf), hwnd);
        ok(!err, "set door closed: %s\n", dbg_mcierr(err));
        test_notification(hwnd, "door closed", err ? 0 : MCI_NOTIFY_SUCCESSFUL);
    }
    /* Changing the disk while the MCI device is open causes the Status
     * command to report stale data.  Native obviously caches the TOC. */

    /* status type track is localised, strcmp("audio|other") may fail. */
    parm.status.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
    parm.status.dwTrack = 1;
    parm.status.dwReturn = 0xFEEDABAD;
    err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM|MCI_TRACK, (DWORD_PTR)&parm);
    ok(!err, "STATUS type track 1: %s\n", dbg_mcierr(err));
    ok(parm.status.dwReturn==MCI_CDA_TRACK_OTHER || parm.status.dwReturn==MCI_CDA_TRACK_AUDIO,
       "unknown track type %lx\n", parm.status.dwReturn);

    if (parm.status.dwReturn == MCI_CDA_TRACK_OTHER) {
        /* Find an audio track */
        parm.status.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
        parm.status.dwTrack = numtracks;
        parm.status.dwReturn = 0xFEEDABAD;
        err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM|MCI_TRACK, (DWORD_PTR)&parm);
        ok(!err, "STATUS type track %u: %s\n", numtracks, dbg_mcierr(err));
        ok(parm.status.dwReturn == MCI_CDA_TRACK_OTHER || parm.status.dwReturn == MCI_CDA_TRACK_AUDIO,
           "unknown track type %lx\n", parm.status.dwReturn);
        track = (!err && parm.status.dwReturn == MCI_CDA_TRACK_AUDIO) ? numtracks : 0;

        /* Seek to start (above) skips over data tracks
         * In case of a data only CD, it seeks to the end of disk, however
         * another Status position a few seconds later yields MCIERR_HARDWARE. */
        parm.status.dwItem = MCI_STATUS_POSITION;
        parm.status.dwReturn = 2000;
        err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm);
        ok(!err || broken(err == MCIERR_HARDWARE), "STATUS position: %s\n", dbg_mcierr(err));

        if(!err && track) ok(parm.status.dwReturn > duration,
            "Seek did not skip data tracks, position %lums\n", parm.status.dwReturn);
        /* dwReturn > start + length(#1) may fail because of small position report fluctuation.
         * On some native systems, status position fluctuates around the target position;
         * Successive calls return varying positions! */

        err = mciSendString("set c time format msf", buf, sizeof(buf), hwnd);
        ok(!err, "set time format msf: %s\n", dbg_mcierr(err));

        parm.status.dwItem = MCI_STATUS_LENGTH;
        parm.status.dwTrack = 1;
        parm.status.dwReturn = 0xFEEDABAD;
        err = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM|MCI_TRACK, (DWORD_PTR)&parm);
        ok(!err, "STATUS length track %u: %s\n", parm.status.dwTrack, dbg_mcierr(err));
        duration = parm.status.dwReturn;
        trace("track #1 length: %02um:%02us:%02uframes\n",
              MCI_MSF_MINUTE(duration), MCI_MSF_SECOND(duration), MCI_MSF_FRAME(duration));
        ok(duration>>24==0, "CD length high bits %08X\n", duration);

        /* TODO only with mixed CDs? */
        /* play track 1 to length silently works with data tracks */
        parm.play.dwFrom = MCI_MAKE_MSF(0,2,0);
        parm.play.dwTo = duration; /* omitting 2 seconds from end */
        err = mciSendCommand(wDeviceID, MCI_PLAY, MCI_FROM|MCI_TO, (DWORD_PTR)&parm);
        ok(!err, "PLAY data to %08X: %s\n", duration, dbg_mcierr(err));

        Sleep(1500*factor); /* Time to spin up, hopefully less than track length */

        err = mciSendString("status c mode", buf, sizeof(buf), hwnd);
        ok(!err, "status mode: %s\n", dbg_mcierr(err));
        if(!err) ok(!strcmp(buf, "stopped"), "status mode on data is %s\n", buf);
    } else if (parm.status.dwReturn == MCI_CDA_TRACK_AUDIO) {
Пример #7
0
/* Get CD-ROM status */
static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
{
	CDstatus status;
	MCI_STATUS_PARMS mci_status;
	DWORD flags;

	flags = MCI_STATUS_ITEM | MCI_WAIT;
	mci_status.dwItem = MCI_STATUS_MODE;
	if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) < 0 ) {
		status = CD_ERROR;
	} else {
		switch (mci_status.dwReturn) {
			case MCI_MODE_NOT_READY:
			case MCI_MODE_OPEN:
				status = CD_TRAYEMPTY;
				break;
			case MCI_MODE_STOP:
#ifdef BROKEN_MCI_PAUSE
				if ( SDL_paused[cdrom->id] ) {
					status = CD_PAUSED;
				} else {
					status = CD_STOPPED;
				}
#else
				status = CD_STOPPED;
#endif /* BROKEN_MCI_PAUSE */
				break;
			case MCI_MODE_PLAY:
#ifdef BROKEN_MCI_PAUSE
				if ( SDL_paused[cdrom->id] ) {
					status = CD_PAUSED;
				} else {
					status = CD_PLAYING;
				}
#else
				status = CD_PLAYING;
#endif /* BROKEN_MCI_PAUSE */
				break;
			case MCI_MODE_PAUSE:
				status = CD_PAUSED;
				break;
			default:
				status = CD_ERROR;
				break;
		}
	}
	if ( position ) {
		if ( status == CD_PLAYING || (status == CD_PAUSED) ) {
			mci_status.dwItem = MCI_STATUS_POSITION;
			if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags,
							&mci_status) == 0 ) {
				*position = MSF_TO_FRAMES(
					MCI_MSF_MINUTE(mci_status.dwReturn),
					MCI_MSF_SECOND(mci_status.dwReturn),
					MCI_MSF_FRAME(mci_status.dwReturn));
			} else {
				*position = 0;
			}
		} else {
			*position = 0;
		}
	}
	return(status);
}
Пример #8
0
static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
{
	MCI_STATUS_PARMS mci_status;
	int i, okay;
	DWORD flags;

	okay = 0;
	mci_status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
	flags = MCI_STATUS_ITEM | MCI_WAIT;
	if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) {
		cdrom->numtracks = mci_status.dwReturn;
		if ( cdrom->numtracks > SDL_MAX_TRACKS ) {
			cdrom->numtracks = SDL_MAX_TRACKS;
		}
		/* Read all the track TOC entries */
		flags = MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT;
		for ( i=0; i<cdrom->numtracks; ++i ) {
			cdrom->track[i].id = i+1;
			mci_status.dwTrack = cdrom->track[i].id;
#ifdef MCI_CDA_STATUS_TYPE_TRACK
			mci_status.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
			if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags,
							&mci_status) < 0 ) {
				break;
			}
			if ( mci_status.dwReturn == MCI_CDA_TRACK_AUDIO ) {
				cdrom->track[i].type = SDL_AUDIO_TRACK;
			} else {
				cdrom->track[i].type = SDL_DATA_TRACK;
			}
#else
			cdrom->track[i].type = SDL_AUDIO_TRACK;
#endif
			mci_status.dwItem = MCI_STATUS_POSITION;
			if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags,
							&mci_status) < 0 ) {
				break;
			}
			cdrom->track[i].offset = MSF_TO_FRAMES(
					MCI_MSF_MINUTE(mci_status.dwReturn),
					MCI_MSF_SECOND(mci_status.dwReturn),
					MCI_MSF_FRAME(mci_status.dwReturn));
			cdrom->track[i].length = 0;
			if ( i > 0 ) {
				cdrom->track[i-1].length =
						cdrom->track[i].offset-
						cdrom->track[i-1].offset;
			}
		}
		if ( i == cdrom->numtracks ) {
			mci_status.dwTrack = cdrom->track[i - 1].id;
			mci_status.dwItem = MCI_STATUS_LENGTH;
			if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags,
							&mci_status) == 0 ) {
				cdrom->track[i - 1].length = MSF_TO_FRAMES(
					MCI_MSF_MINUTE(mci_status.dwReturn),
					MCI_MSF_SECOND(mci_status.dwReturn),
					MCI_MSF_FRAME(mci_status.dwReturn));
				/* compute lead-out offset */
				cdrom->track[i].offset = cdrom->track[i - 1].offset +
					cdrom->track[i - 1].length;
				cdrom->track[i].length = 0;
				okay = 1;
			}
		}
	}
	return(okay ? 0 : -1);
}
Пример #9
0
int internal_play_cd_audio_track ( void *data )
{

	int
		track;

	track = *( ( int * ) data );

	if ( cdrom_device_captured )
	{

		MCI_PLAY_PARMS
			play_parameters;

		MCI_STATUS_PARMS
			status_parameters;

		DWORD
			value;

		status_parameters.dwItem = MCI_STATUS_LENGTH;
		status_parameters.dwTrack = track;

		value = mciSendCommand ( cdrom_device_id, MCI_STATUS, ( MCI_TRACK | MCI_STATUS_ITEM ), ( DWORD ) ( LPVOID ) &status_parameters );

		if ( value )
		{

			debug_log ( "Unable to get track length" );
		}
		else
		{

			int
				minutes,
				seconds,
				frames;
	
			minutes = MCI_MSF_MINUTE ( status_parameters.dwReturn ),
			seconds = MCI_MSF_SECOND ( status_parameters.dwReturn ),
			frames = MCI_MSF_FRAME ( status_parameters.dwReturn ),
	
			play_parameters.dwFrom = 0;
			play_parameters.dwTo = 0;
			play_parameters.dwFrom = MCI_MAKE_TMSF ( track, 0, 0, 0 );
			play_parameters.dwTo = MCI_MAKE_TMSF ( track, minutes, seconds, frames );
			play_parameters.dwCallback = ( DWORD ) application_window;
	
			value = mciSendCommand ( cdrom_device_id, MCI_PLAY, ( MCI_FROM | MCI_TO | MCI_NOTIFY ), ( DWORD ) ( LPVOID ) &play_parameters );
	
			if ( value )
			{
	
				//
				// Ditch the cd player!
				//
	
				debug_log ( "Unable to play cd" );
	
				release_cd_audio_device ();
			}
			else
			{
	
				cdrom_audio_track_playing = TRUE;
			}
		}
	}

	return ( TRUE );
}