⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdaudio.c

📁 xmms-1.2.10.tar.gz学习使用的就下吧
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		pthread_join(dae_data.thread, NULL);		cdda_ip.output->close_audio();	}	else		ioctl(cdda_playing.fd, XMMS_PAUSE, 0);	close(cdda_playing.fd);	cdda_playing.fd = -1;	if (!cdda_playing.drive.dae)	{		to_info = g_malloc(sizeof (*to_info));		to_info->device = g_strdup(cdda_playing.drive.device);		to_info->id = gtk_timeout_add(STOP_DELAY * 100, stop_timeout,					      to_info);		timeout_list = g_list_prepend(timeout_list, to_info);	}}static void cdda_pause(short p){	if (cdda_playing.drive.dae)	{		cdda_ip.output->pause(p);		return;	}	if (p)	{		pause_time = get_time();		ioctl(cdda_playing.fd, XMMS_PAUSE, 0);	}	else	{		ioctl(cdda_playing.fd, XMMS_RESUME, 0);		pause_time = -1;	}	is_paused = p;}#ifdef XMMS_CDROM_SOLARIS/* * Lowlevel cdrom access, Solaris style (Solaris, Linux) */static void play_ioctl(struct cdda_msf *start, struct cdda_msf *end){	struct cdrom_msf msf;		msf.cdmsf_min0 = start->minute;	msf.cdmsf_sec0 = start->second;	msf.cdmsf_frame0 = start->frame;	msf.cdmsf_min1 = end->minute;	msf.cdmsf_sec1 = end->second;	msf.cdmsf_frame1 = end->frame;	ioctl(cdda_playing.fd, CDROMPLAYMSF, &msf);}static int get_current_frame(void){	struct cdrom_subchnl subchnl;	subchnl.cdsc_format = CDROM_MSF;	if (ioctl(cdda_playing.fd, CDROMSUBCHNL, &subchnl) < 0)		return -1;	switch (subchnl.cdsc_audiostatus)	{		case CDROM_AUDIO_COMPLETED:		case CDROM_AUDIO_ERROR:			return -1;	}	return (LBA(subchnl.cdsc_absaddr.msf));}#if !defined(CDROMVOLREAD)static int volume_left = 100, volume_right = 100;#endifstatic void drive_get_volume(int *l, int *r){#if defined(CDROMVOLREAD)	struct cdrom_volctrl vol;	if (cdda_playing.fd!=-1 && !ioctl(cdda_playing.fd, CDROMVOLREAD, &vol))	{		*l = (100 * vol.channel0) / 255;		*r = (100 * vol.channel1) / 255;	}#if 0	else if (cdda_playing.fd != -1)		g_message("CDROMVOLREAD failed");#endif#else	*l = volume_left;	*r = volume_right;#endif}static void drive_set_volume(int l, int r){	struct cdrom_volctrl vol;	if (cdda_playing.fd != -1)	{		vol.channel0 = vol.channel2 = (l * 255) / 100;		vol.channel1 = vol.channel3 = (r * 255) / 100;		ioctl(cdda_playing.fd, CDROMVOLCTRL, &vol);	}#if !defined(CDROMVOLREAD)	volume_left = l;	volume_right = r;#endif}#ifdef CDROMREADAUDIOint read_audio_data(int fd, int pos, int num, void *buf){	struct cdrom_read_audio cdra;#if 1	cdra.addr.lba = pos - CDDA_MSF_OFFSET;	cdra.addr_format = CDROM_LBA;#else		cdra.addr.msf.minute = pos / (60 * 75);	cdra.addr.msf.second = (pos / 75) % 60;	cdra.addr.msf.frame = pos % 75;	cdra.addr_format = CDROM_MSF;#endif		cdra.nframes = num;	cdra.buf = buf;	if (ioctl(fd, CDROMREADAUDIO, &cdra) < 0)		return -errno;	return cdra.nframes;}#endif /* CDROMREADAUDIO */#if defined(CDROMCDDA)int read_audio_data(int fd, int pos, int num, void *buf){	struct cdrom_cdda cdra;	cdra.cdda_addr = pos - CDDA_MSF_OFFSET;	cdra.cdda_length = num;	cdra.cdda_data = buf;	cdra.cdda_subcode = CDROM_DA_NO_SUBCODE;	if (ioctl(fd, CDROMCDDA, &cdra) < 0)		return -errno;	return cdra.cdda_length;}#endifstatic gboolean cdda_get_toc_lowlevel(int fd, cdda_disc_toc_t *info){	struct cdrom_tochdr tochdr;	struct cdrom_tocentry tocentry;	int i;	if (ioctl(fd, CDROMREADTOCHDR, &tochdr))		return FALSE;	for (i = tochdr.cdth_trk0; i <= tochdr.cdth_trk1; i++)	{				tocentry.cdte_format = CDROM_MSF;		tocentry.cdte_track = i;		if (ioctl(fd, CDROMREADTOCENTRY, &tocentry))			return FALSE;		info->track[i].minute = tocentry.cdte_addr.msf.minute;		info->track[i].second = tocentry.cdte_addr.msf.second;		info->track[i].frame = tocentry.cdte_addr.msf.frame;		info->track[i].flags.data_track =			tocentry.cdte_ctrl == CDROM_DATA_TRACK;	}	/* Get the leadout track */	tocentry.cdte_track = CDROM_LEADOUT;	tocentry.cdte_format = CDROM_MSF;	if (ioctl(fd, CDROMREADTOCENTRY, &tocentry))		return FALSE;	info->leadout.minute = tocentry.cdte_addr.msf.minute;	info->leadout.second = tocentry.cdte_addr.msf.second;	info->leadout.frame = tocentry.cdte_addr.msf.frame;		info->first_track = tochdr.cdth_trk0;	info->last_track = tochdr.cdth_trk1;	return TRUE;}#endif#ifdef XMMS_CDROM_BSD/* * Lowlevel cdrom access, BSD style (FreeBSD, OpenBSD, NetBSD, Darwin) */static void play_ioctl(struct cdda_msf *start, struct cdda_msf *end){	struct ioc_play_msf msf;	msf.start_m = start->minute;	msf.start_s = start->second;	msf.start_f = start->frame;	msf.end_m = end->minute;	msf.end_s = end->second;	msf.end_f = end->frame;	ioctl(cdda_playing.fd, CDIOCPLAYMSF, &msf);}static int get_current_frame(void){	struct ioc_read_subchannel subchnl;	struct cd_sub_channel_info subinfo;	subchnl.address_format = CD_MSF_FORMAT;	subchnl.data_format = CD_CURRENT_POSITION;	subchnl.track = 0;	subchnl.data_len = sizeof(subinfo);	subchnl.data = &subinfo;	if (ioctl(cdda_playing.fd, CDIOCREADSUBCHANNEL, &subchnl) < 0)		return -1;#ifdef XMMS_CDROM_BSD_DARWIN	return ((subchnl.data->what.position.absaddr[1] * 60		 subchnl.data->what.position.absaddr[2]) * 75 +		subchnl.data->what.position.absaddr[3]);#else	return (LBA(subchnl.data->what.position.absaddr.msf));#endif}static void drive_get_volume(int *l, int *r){	struct ioc_vol vol;		if (cdda_playing.fd != -1)	{		ioctl(cdda_playing.fd, CDIOCGETVOL, &vol);		*l = (100 * vol.vol[0]) / 255;		*r = (100 * vol.vol[1]) / 255;	}}static void drive_set_volume(int l, int r){	struct ioc_vol vol;	if (cdda_playing.fd != -1)	{		vol.vol[0] = vol.vol[2] = (l * 255) / 100;		vol.vol[1] = vol.vol[3] = (r * 255) / 100;		ioctl(cdda_playing.fd, CDIOCSETVOL, &vol);	}}#ifdef __FreeBSD__# if defined(CDIOCREADAUDIO)/* Digital extraction before ATAng */int read_audio_data(int fd, int pos, int num, void *buf){	struct ioc_read_audio cdra;	cdra.address.lba = pos - CDDA_MSF_OFFSET;	cdra.address_format = CD_LBA_FORMAT;	cdra.nframes = num;	cdra.buffer = buf;	if (ioctl(fd, CDIOCREADAUDIO, &cdra) < 0)		return -errno;	return cdra.nframes;}# else/* Digital extraction with ATAng */int read_audio_data(int fd, int pos, int num, void *buf){		int bsize = 2352;	if (ioctl(fd, CDRIOCSETBLOCKSIZE, &bsize) == -1)		return -errno;	if (pread(fd, buf, num*bsize, (pos - 150)*bsize) != num*bsize)		return 0;	return num;	 	}# endif /* CDIOCREADAUDIO */#endif#ifdef XMMS_CDROM_BSD_NETBSD /* NetBSD, OpenBSD */static gboolean cdda_get_toc_lowlevel(int fd, cdda_disc_toc_t *info){	struct ioc_toc_header tochdr;	struct ioc_read_toc_entry tocentry;	struct cd_toc_entry tocentrydata;	int i;	if (ioctl(fd, CDIOREADTOCHEADER, &tochdr))		return FALSE;	for (i = tochdr.starting_track; i <= tochdr.ending_track; i++)	{				tocentry.address_format = CD_MSF_FORMAT;		tocentry.starting_track = i;		tocentry.data = &tocentrydata;		tocentry.data_len = sizeof(tocentrydata);		if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry))			return FALSE;		info->track[i].minute = tocentry.data->addr.msf.minute;		info->track[i].second = tocentry.data->addr.msf.second;		info->track[i].frame = tocentry.data->addr.msf.frame;		info->track[i].flags.data_track =		    (tocentry.data->control & 4) == 4;	}	/* Get the leadout track */	tocentry.address_format = CD_MSF_FORMAT;	tocentry.starting_track = 0xAA;	tocentry.data = &tocentrydata;	tocentry.data_len = sizeof(tocentrydata);	if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry))		return FALSE;	info->leadout.minute = tocentry.data->addr.msf.minute;	info->leadout.second = tocentry.data->addr.msf.second;	info->leadout.frame = tocentry.data->addr.msf.frame;		info->first_track = tochdr.starting_track;	info->last_track = tochdr.ending_track;	return TRUE;}#elif defined(XMMS_CDROM_BSD_DARWIN)static gboolean cdda_get_toc_lowlevel(int fd, cdda_disc_toc_t *info){	struct ioc_toc_header tochdr;	struct ioc_read_toc_entry tocentry;	int i;	if (ioctl(fd, CDIOREADTOCHEADER, &tochdr))		return FALSE;	for (i = tochdr.starting_track; i <= tochdr.ending_track; i++)	{				tocentry.address_format = CD_MSF_FORMAT;		tocentry.starting_track = i;		if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry))			return FALSE;		info->track[i].minute =	tocentry.data->addr[1];		info->track[i].second = tocentry.data->addr[2];		info->track[i].frame = tocentry.data->addr[3];		info->track[i].flags.data_track =			(tocentry.data->control & 4) == 4;	}	/* Get the leadout track */	tocentry.address_format = CD_MSF_FORMAT;	tocentry.starting_track = 0xAA;	if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry))		return FALSE;	info->leadout.minute = tocentry.data->addr[1];	info->leadout.second = tocentry.data->addr[2];	info->leadout.frame = tocentry.data->addr[3];	return TRUE;}#else /* FreeBSD */static gboolean cdda_get_toc_lowlevel(int fd, cdda_disc_toc_t *info){	struct ioc_toc_header tochdr;	struct ioc_read_toc_single_entry tocentry;	int i;	if (ioctl(fd, CDIOREADTOCHEADER, &tochdr))		return FALSE;	for (i = tochdr.starting_track; i <= tochdr.ending_track; i++)	{				tocentry.address_format = CD_MSF_FORMAT;		tocentry.track = i;		if (ioctl(fd, CDIOREADTOCENTRY, &tocentry))			return FALSE;		info->track[i].minute = tocentry.entry.addr.msf.minute;		info->track[i].second = tocentry.entry.addr.msf.second;		info->track[i].frame = tocentry.entry.addr.msf.frame;		info->track[i].flags.data_track =		    (tocentry.entry.control & 4) == 4;	}	/* Get the leadout track */	tocentry.address_format = CD_MSF_FORMAT;	tocentry.track = 0xAA;	if (ioctl(fd, CDIOREADTOCENTRY, &tocentry))		return FALSE;	info->leadout.minute = tocentry.entry.addr.msf.minute;	info->leadout.second = tocentry.entry.addr.msf.second;	info->leadout.frame = tocentry.entry.addr.msf.frame;		info->first_track = tochdr.starting_track;	info->last_track = tochdr.ending_track;	return TRUE;}#endif#endifstatic void seek(int time){	struct cdda_msf *end, start;	int track = cdda_playing.track;	if (cdda_playing.drive.dae)	{		dae_data.seek = time;		while (dae_data.seek != -1)			xmms_usleep(20000);		return;	}		start.minute = (cdda_playing.cd_toc.track[track].minute * 60 +			cdda_playing.cd_toc.track[track].second + time) / 60;	start.second = (cdda_playing.cd_toc.track[track].second + time) % 60;	start.frame = cdda_playing.cd_toc.track[track].frame;	if (track == cdda_playing.cd_toc.last_track)		end = &cdda_playing.cd_toc.leadout;	else		end = &cdda_playing.cd_toc.track[track + 1];	play_ioctl(&start, end);		if (is_paused)	{		cdda_pause(TRUE);		pause_time = time * 1000;	}}static int get_time_analog(void){	int frame, start_frame, length;	int track = cdda_playing.track;	if (is_paused && pause_time != -1)		return pause_time;	frame = get_current_frame();	if (frame == -1)		return -1;		start_frame = LBA(cdda_playing.cd_toc.track[track]);	length = cdda_calculate_track_length(&cdda_playing.cd_toc, track);	if (frame - start_frame >= length - 20)	/* 20 seems to work better */		return -1;	return ((frame - start_frame) * 1000) / 75;}static int get_time_dae(void){	if (dae_data.audio_error)		return -2;	if (!cdda_playing.playing ||	    (dae_data.eof && !cdda_ip.output->buffer_playing()))		return -1;	return cdda_ip.output->output_time();}static int get_time(void){	if (cdda_playing.fd == -1)		return -1;	if (cdda_playing.drive.dae)		return get_time_dae();	else		return get_time_analog();}static void get_song_info(char *filename, char **title, int *len){	cdda_disc_toc_t toc;	int t;	char *tmp;	struct driveinfo *drive;	*title = NULL;	*len = -1;	if ((drive = cdda_find_drive(filename)) == NULL)		return;	tmp = strrchr(filename, '/');	if (tmp)		tmp++;	else		tmp = filename;		if (!sscanf(tmp, "Track %d.cda", &t))		return;	if (!cdda_get_toc(&toc, drive->device))		return;	if (t < toc.first_track || t > toc.last_track || toc.track[t].flags.data_track)		return;		*len = (cdda_calculate_track_length(&toc, t) * 1000) / 75;	*title = cdda_get_title(&toc, t);}#ifdef HAVE_OSSstatic void oss_get_volume(int *l, int *r, int mixer_line){	int fd, v;	fd = open(DEV_MIXER, O_RDONLY);	if (fd != -1)	{		ioctl(fd, MIXER_READ(mixer_line), &v);		*r = (v & 0xFF00) >> 8;		*l = (v & 0x00FF);		close(fd);	}}static void oss_set_volume(int l, int r, int mixer_line){	int fd, v;	fd = open(DEV_MIXER, O_RDONLY);	if (fd != -1)	{		v = (r << 8) | l;		ioctl(fd, MIXER_WRITE(mixer_line), &v);		close(fd);	}}#elsestatic void oss_get_volume(int *l, int *r, int mixer_line){}static void oss_set_volume(int l, int r, int mixer_line){}#endifstatic void get_volume(int *l, int *r){	if (cdda_playing.drive.dae)	{		if (cdda_ip.output->get_volume)			cdda_ip.output->get_volume(l, r);	}	else if (cdda_playing.drive.mixer == CDDA_MIXER_OSS)		oss_get_volume(l, r, cdda_playing.drive.oss_mixer);	else if(cdda_playing.drive.mixer == CDDA_MIXER_DRIVE)		drive_get_volume(l, r);}static void set_volume(int l, int r){	if (cdda_playing.drive.dae)		cdda_ip.output->set_volume(l, r);	else if (cdda_playing.drive.mixer == CDDA_MIXER_OSS)		oss_set_volume(l, r, cdda_playing.drive.oss_mixer);	else if (cdda_playing.drive.mixer == CDDA_MIXER_DRIVE)		drive_set_volume(l, r);}gboolean cdda_get_toc(cdda_disc_toc_t *info, char *device){	gboolean retv = FALSE;	int fd;	if (is_mounted(device))		return FALSE;	if ((fd = open(device, CDOPENFLAGS)) == -1)		return FALSE;	memset(info, 0, sizeof(cdda_disc_toc_t));	retv = cdda_get_toc_lowlevel(fd, info);	close(fd);	return retv;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -