/* mutex must be locked */
static void refresh_trackinfo (gboolean warning)
{
    trigger_monitor ();

    if (pcdrom_drive == NULL)
    {
        open_cd ();
        if (pcdrom_drive == NULL)
            return;
    }

    int mode = cdio_get_discmode (pcdrom_drive->p_cdio);
#ifdef _WIN32 /* cdio_get_discmode reports the wrong disk type sometimes */
    if (mode == CDIO_DISC_MODE_NO_INFO || mode == CDIO_DISC_MODE_ERROR)
#else
    if (mode != CDIO_DISC_MODE_CD_DA && mode != CDIO_DISC_MODE_CD_MIXED)
#endif
    {
        if (warning)
        {
            if (mode == CDIO_DISC_MODE_NO_INFO)
                cdaudio_error (_("Drive is empty."));
            else
                cdaudio_error (_("Unsupported disk type."));
        }

        /* reset libcdio, else it will not read a new disk correctly */
        if (pcdrom_drive)
        {
            cdda_close (pcdrom_drive);
            pcdrom_drive = NULL;
        }

        g_free (trackinfo);
        trackinfo = NULL;
        return;
    }

    if (trackinfo == NULL || cdio_get_media_changed (pcdrom_drive->p_cdio))
    {
        g_free (trackinfo);
        trackinfo = NULL;
        scan_cd ();
    }
}
Beispiel #2
0
static gboolean
xmms_cdda_init (xmms_xform_t *xform)
{
	CdIo_t *cdio = NULL;
	cdrom_drive_t *drive = NULL;
	const gchar *url;
	gchar **url_data = NULL;
	gchar *url_end;
	xmms_cdda_data_t *data;
	guint playtime;
	lsn_t first_lsn;
	track_t track;
	gchar *disc_id = NULL;
	gchar *cddb_id = NULL;
	xmms_config_property_t *val;
	const gchar *device;
	const gchar *metakey;
	gboolean ret = TRUE;

	g_return_val_if_fail (xform, FALSE);
	url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL);

	if (g_ascii_strcasecmp (url, "cdda://") == 0) {
		xmms_xform_outdata_type_add (xform,
		                             XMMS_STREAM_TYPE_MIMETYPE,
		                             "application/x-xmms2-playlist-entries",
		                             XMMS_STREAM_TYPE_END);
		return TRUE;
	}

	val = xmms_xform_config_lookup (xform, "device");
	device = xmms_config_property_get_string (val);

	if (!get_disc_ids (device, &disc_id, &cddb_id, 0)) {
		return FALSE;
	}

	url += 7;
	url_data = g_strsplit (url, "/", 2);

	if (g_ascii_strcasecmp (url_data[0], disc_id)) {
		xmms_log_error ("Wrong disc inserted.");
		ret = FALSE;
		goto end;
	}

	if (url_data[1] == NULL) {
		xmms_log_error ("Missing track number.");
		ret = FALSE;
		goto end;
	}

	track = strtol (url_data[1], &url_end, 10);
	if (url_data[1] == url_end) {
		xmms_log_error ("Invalid track, need a number.");
		ret = FALSE;
		goto end;
	}

	cdio = open_cd (xform);
	if (!cdio) {
		ret = FALSE;
		goto end;
	}

	drive = cdio_cddap_identify_cdio (cdio, 1, NULL);
	if (!drive) {
		xmms_log_error ("Failed to identify drive.");
		ret = FALSE;
		goto end;
	}

	if (cdio_cddap_open (drive)) {
		xmms_log_error ("Unable to open disc.");
		ret = FALSE;
		goto end;
	}

	first_lsn = cdio_cddap_track_firstsector (drive, track);
	if (first_lsn == -1) {
		xmms_log_error ("No such track.");
		ret = FALSE;
		goto end;
	}

	data = g_new (xmms_cdda_data_t, 1);
	data->cdio = cdio;
	data->drive = drive;
	data->track = track;
	data->first_lsn = first_lsn;
	data->last_lsn = cdio_cddap_track_lastsector (drive, data->track);
	data->current_lsn = first_lsn;
	data->buf_used = CDIO_CD_FRAMESIZE_RAW;

	playtime = (data->last_lsn - data->first_lsn) *
	           1000.0 / CDIO_CD_FRAMES_PER_SEC;

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
	xmms_xform_metadata_set_int (xform, metakey, playtime);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
	xmms_xform_metadata_set_int (xform, metakey, 141120);

	xmms_xform_metadata_set_str (xform, "disc_id", url_data[0]);
	xmms_xform_metadata_set_str (xform, "cddb_id", cddb_id);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR;
	xmms_xform_metadata_set_int (xform, metakey, track);

	xmms_xform_private_data_set (xform, data);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_S16,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             2,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             44100,
	                             XMMS_STREAM_TYPE_END);

end:
	/* These are to be destroyed in every cases... */
	g_free (cddb_id);
	g_free (disc_id);
	g_strfreev (url_data);

	/* destroy cdio/drive in case of failure */
	if (!ret) {
		if (drive) {
			cdio_cddap_close_no_free_cdio (drive);
		}
		if (cdio) {
			cdio_destroy (cdio);
		}
	}

	return ret;
}
Beispiel #3
0
static int
run(int cmd, char *arg)
{
	long speed;
	int l, r, rc, count;

	switch (cmd) {

	case CMD_QUIT:
		exit (0);

	case CMD_INFO:
		if (fd < 0 && ! open_cd ())
			return (0);

		return info (arg);

	case CMD_CDID:
		if (fd < 0 && ! open_cd ())
			return (0);

		return cdid ();

	case CMD_STATUS:
		if (fd < 0 && ! open_cd ())
			return (0);

		return pstatus (arg);

	case CMD_NEXT:
	case CMD_PREVIOUS:
		if (fd < 0 && ! open_cd ())
			return (0);

		while (isspace (*arg))
			arg++;

		return next_prev (arg, cmd);

	case CMD_PAUSE:
		if (fd < 0 && ! open_cd ())
			return (0);

		return ioctl (fd, CDIOCPAUSE);

	case CMD_RESUME:
		if (fd < 0 && ! open_cd ())
			return (0);

		return ioctl (fd, CDIOCRESUME);

	case CMD_STOP:
		if (fd < 0 && ! open_cd ())
			return (0);

		rc = ioctl (fd, CDIOCSTOP);

		(void) ioctl (fd, CDIOCALLOW);

		return (rc);

	case CMD_RESET:
		if (fd < 0 && ! open_cd ())
			return (0);

		rc = ioctl (fd, CDIOCRESET);
		if (rc < 0)
			return rc;
		close(fd);
		fd = -1;
		return (0);

	case CMD_DEBUG:
		if (fd < 0 && ! open_cd ())
			return (0);

		if (! strcasecmp (arg, "on"))
			return ioctl (fd, CDIOCSETDEBUG);

		if (! strcasecmp (arg, "off"))
			return ioctl (fd, CDIOCCLRDEBUG);

		warnx("invalid command arguments");

		return (0);

	case CMD_EJECT:
		if (fd < 0 && ! open_cd ())
			return (0);

		(void) ioctl (fd, CDIOCALLOW);
		rc = ioctl (fd, CDIOCEJECT);
		if (rc < 0)
			return (rc);
		return (0);

	case CMD_CLOSE:
		if (fd < 0 && ! open_cd ())
			return (0);

		(void) ioctl (fd, CDIOCALLOW);
		rc = ioctl (fd, CDIOCCLOSE);
		if (rc < 0)
			return (rc);
		close(fd);
		fd = -1;
		return (0);

	case CMD_PLAY:
		if (fd < 0 && ! open_cd ())
			return (0);

		while (isspace (*arg))
			arg++;

		return play (arg);

	case CMD_SET:
		if (! strcasecmp (arg, "msf"))
			msf = 1;
		else if (! strcasecmp (arg, "lba"))
			msf = 0;
		else
			warnx("invalid command arguments");
		return (0);

	case CMD_VOLUME:
		if (fd < 0 && !open_cd ())
			return (0);

		if (! strlen (arg)) {
			char volume[] = "volume";

		    	return pstatus (volume);
		}

		if (! strncasecmp (arg, "left", strlen(arg)))
			return ioctl (fd, CDIOCSETLEFT);

		if (! strncasecmp (arg, "right", strlen(arg)))
			return ioctl (fd, CDIOCSETRIGHT);

		if (! strncasecmp (arg, "mono", strlen(arg)))
			return ioctl (fd, CDIOCSETMONO);

		if (! strncasecmp (arg, "stereo", strlen(arg)))
			return ioctl (fd, CDIOCSETSTERIO);

		if (! strncasecmp (arg, "mute", strlen(arg)))
			return ioctl (fd, CDIOCSETMUTE);

		count = sscanf (arg, "%d %d", &l, &r);
		if (count == 1)
		    return setvol (l, l);
		if (count == 2)
		    return setvol (l, r);
		warnx("invalid command arguments");
		return (0);

	case CMD_SPEED:
		if (fd < 0 && ! open_cd ())
			return (0);

		errno = 0;
		if (strcasecmp("max", arg) == 0)
			speed = CDR_MAX_SPEED;
		else
			speed = strtol(arg, NULL, 10) * 177;
		if (speed <= 0 || speed > INT_MAX) {
			warnx("invalid command arguments %s", arg);
			return (0);
		}
		return ioctl(fd, CDRIOCREADSPEED, &speed);

	default:
	case CMD_HELP:
		help ();
		return (0);

	}
}