🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: es.comp.os.linux.programacion
Article #13627

Re: reproductor de CD "pofessional"

#13627
From: Manuel López Moreno
Date: Mon, 12 Feb 2001 11:20
316 lines
8580 bytes
	Tal d�a Fri, 9 Feb 2001 18:17:18 -0000,
	Francisco Cuenya Folgar <francisco.cuenya@wanadoo.es> nos relat�:

>     Lo de capturar la salida del CD deber�a conocer las llamadas a sistema o
> librer�as que controlen el CD para implementarlo no? Alguien sabe cu�les son
> estas librer�as o llamadas y d�nde puedo encontrar info sobre ellas? Gracias

Est� todo en <linux/cdrom.h>

Ah� va un programilla que escrib� para probar las ioctl's. No te
f�es demasiado del control de errores. Hay cosas que no acaban de
funcionar.

Para compilar: $ gcc -Wall -Wstrict-prototypes cdr.c -o cdr

- cdr.c --8<----------------------------------------

/*
 * Utilidad:	Diversas funciones del CD-ROM.
 * Fecha:	Martes, 16 de Julio de 1996
 * Revisi�n:	Jueves, 9 de Julio de 1998
 * Autor:	Manuel L�pez Moreno <luname@mx2.redestb.es>
 *
 * Sintaxis:	cdr [e|s|p|r] [argumentos]
 *
 * Argumentos:	Eject:	e
 *		Stop:	s
 *		Play:	p	<lba0> <lba1>
 *		Read:	r	<lba> <nfr>
 */

#include <fcntl.h>		// open()
#include <unistd.h>		// write()
#include <sys/ioctl.h>		// ioctl()
#include <stdio.h>		// printf()
#include <stdlib.h>		// atoi()
#include <sys/types.h>		// u_char, linux/cdrom.h
#include <linux/cdrom.h>	// CDROM...

//----- Constantes

#define	DEVICE		"/dev/cdrom"
#define	MAXTOCENT	96

enum
{
	EJECT = 1, STOP, TOCHDR, TOCENT, PLAY, PAUSE, RESUME,
	MEM, READ, SUBCHNL, FADE, CLOSE
};

static char* Msj[] =
{
	"Fallo al abrir",
	"Fallo al expulsar bandeja",
	"Fallo al parar el motor",
	"Fallo al leer TOC Header",
	"Fallo al leer TOC Entry",
	"Fallo al reproducir",
	"Fallo al parar (pause)",
	"Fallo al continuar (resume)",
	"Error de obtenci�n de memoria",
	"Fallo al leer audio",
	"Fallo al leer status",
	"Fallo al modificar volumen",
	"Fallo al cerrar bandeja"
};

//----- Prototipos

static int	GetTOC		(int drive);
static void	DisplayTOC	(void);
static int	Play		(int drive, int lba0, int lba1);
static int	Read		(int drive, int lba, int nfr);
static int	SubChannel	(int drive);
static int	Fade		(int drive, int sw);
static void	lba2msf		(int lba, unsigned char msf[]);

//----- Variables Globales

static struct cdrom_tocentry	TocEntry[MAXTOCENT];
static u_char			NTracks;

//------------------------------------------------------------

int main (int argc, char* argv[])
{
	int	drive;
	int	io = -1;
	int	com;
	int	lba0, lba1;
	int	trk = (argc > 2 ? atoi(argv[2]) : 1);
	int	ind = (argc > 3 ? atoi(argv[3]) : 0);
	int	nfr = (argc > 3 ? atoi(argv[3]) : CD_FRAMES);
	int	sw  = (argc > 2 ? atoi(argv[2]) : 0); 

	if ((drive = open(DEVICE, 0)) < 0)
	{
		perror(Msj[0]);
		return 1;
	}

	if ((com = GetTOC(drive)) != 0)
		puts(Msj[com]); 

	lba0 =  (argc > 2 ? atoi(argv[2]) : TocEntry[0].cdte_addr.lba);
	lba1 =  (argc > 3 ? atoi(argv[3]) : TocEntry[NTracks].cdte_addr.lba);

	if (argc == 1)
		DisplayTOC();
	else if (argc > 1)
	{
		switch (*argv[1])
		{
		case 'e': io = ioctl(drive, CDROMEJECT); com = EJECT;
			break;
		case 't': io = ioctl(drive, CDROMCLOSETRAY); com = CLOSE;
			break;
		case 's': io = ioctl(drive, CDROMSTOP); com = STOP;
			break;
		case 'p': io = com = Play(drive, lba0, lba1);
			break; 
		case 'P': io = ioctl(drive, CDROMPAUSE); com = PAUSE;
			break;
		case 'S': io = ioctl(drive, CDROMRESUME); com = RESUME;
			break;
		case 'r': io = com = Read(drive, lba0, nfr);
			break; 
		case 'c': io = com = SubChannel(drive);
			break;
		case 'f': io = com = Fade(drive, sw);
		}

		if (io != 0)
		{
			perror(Msj[com]);
			return 1;
		}
	}

	return 0;
}

//------------------------------------------------------------

int GetTOC (int drive)
{
	struct cdrom_tochdr		TocHdr;
	struct cdrom_tocentry*		pTE;
	int				i;

	if (ioctl(drive, CDROMREADTOCHDR, &TocHdr) < 0)
		return TOCHDR;

	NTracks = TocHdr.cdth_trk1;

	for (i = 1, pTE = TocEntry; i <= NTracks; i++, pTE++)
	{
		pTE->cdte_track = i;
		pTE->cdte_format = CDROM_LBA;

		if (ioctl(drive, CDROMREADTOCENTRY, pTE) < 0)
			return TOCENT;
	}

	pTE->cdte_track = CDROM_LEADOUT;
	pTE->cdte_format = CDROM_MSF;

	if (ioctl(drive, CDROMREADTOCENTRY, pTE) < 0)
		return TOCENT;

	return 0;
}

//------------------------------------------------------------

void DisplayTOC (void)
{
	struct cdrom_tocentry*	pTE;
	int			i;
	u_char			msf[3];

	printf("\nDuraci�n Total: %02d:%02d:%02d (%d pista%c)\n\n",
		TocEntry[NTracks].cdte_addr.msf.minute,
		TocEntry[NTracks].cdte_addr.msf.second,
		TocEntry[NTracks].cdte_addr.msf.frame,
		NTracks, (NTracks == 1 ? 0 : 's'));

	printf("Pista  adr ctrl mode  mm:ss:ff       LBA\n"
		"-----  --- ---- ----  --------  --------\n" );

	for (i = 0, pTE = TocEntry; i < NTracks; i++, pTE++)
	{
		lba2msf(pTE->cdte_addr.lba, msf);

		printf("%5d  %3d %4d %4d  %02d:%02d:%02d  %8d\n",
			pTE->cdte_track,
			pTE->cdte_adr,
			pTE->cdte_ctrl,
			pTE->cdte_datamode,
			msf[0], msf[1], msf[2],
			pTE->cdte_addr.lba);
	}
}

//------------------------------------------------------------

int Play (int drive, int lba0, int lba1)
{
	struct cdrom_msf	msf;

	lba2msf(lba0, (u_char*) &msf.cdmsf_min0);
	lba2msf(lba1, (u_char*) &msf.cdmsf_min1);

	if (ioctl(drive, CDROMPLAYMSF, &msf) < 0)
		return PLAY;

	return 0;
}

//------------------------------------------------------------

int Read (int drive, int lba, int nfr)
{
	struct cdrom_read_audio	RA;
	int			nbytes = nfr * CD_FRAMESIZE_RAW;

	RA.addr_format = CDROM_LBA;
	RA.addr.lba = lba;
	RA.nframes = nfr;

	if ((RA.buf = (u_char*) malloc(nbytes)) == NULL)
		return MEM;

	if (ioctl(drive, CDROMREADAUDIO, &RA) < 0)
		return READ;

	write(1, &RA.buf, nbytes);

	return 0;
}

//------------------------------------------------------------

int SubChannel (int drive)
{
	struct cdrom_subchnl	subc;

	subc.cdsc_format = CDROM_MSF;

	if (ioctl(drive, CDROMSUBCHNL, &subc) < 0)
		return SUBCHNL;

	printf("Status %02X, Pista %03d, "
		"Indice %03d MSF %02d:%02d:%02d (%1X %1X)\n",
		subc.cdsc_audiostatus,
		subc.cdsc_trk,
		subc.cdsc_ind,
		subc.cdsc_reladdr.msf.minute,
		subc.cdsc_reladdr.msf.second,
		subc.cdsc_reladdr.msf.frame,
		subc.cdsc_adr,
		subc.cdsc_ctrl);

	return 0;
}

//------------------------------------------------------------

int Fade (int drive, int sw)
{
	// Habr� que inicializar v, digo yo :-/
	int			v;
	struct cdrom_volctrl	vol = { 0 };

	if (sw > 0)
	{
		vol.channel0 = vol.channel1 = 0;
		sw = +1;
	}
	else if (sw < 0)
	{
		vol.channel0 = vol.channel1 = 255;
		sw = -1;
	}

	printf("Volumen inicial: %d\n", v);

	while (v += sw)
	{
		vol.channel0 = vol.channel1 = v;
		if (ioctl(drive, CDROMVOLCTRL, &vol) < 0)
			return FADE;
	}

	printf("Volumen final: %d\n", v);

	return 0;
}

//------------------------------------------------------------

void lba2msf (int lba, unsigned char msf[])
{
	lba += CD_MSF_OFFSET;
	msf[0] = lba / (CD_SECS * CD_FRAMES);
	lba %= CD_SECS * CD_FRAMES;
	msf[1] = lba / CD_FRAMES;
	msf[2] = lba % CD_FRAMES;
}

----------8<----------------------------------------

-- 
Manuel L�pez Moreno	PGP key ID: 0xC6C9455E

Visita: Web de es.comp.os.linux.* <http://www.escomposlinux.org>
Technical Details
Message-ID: <slrn98fhdl.lr.luname@mantium.luname.net>
Path: arc1-ca.pugleaf.net!supernews.google.com!sn-xit-03!supernews.com!nntp.cs.ubc.ca!skynet.be!fr.clara.net!heighliner.fr.clara.net!opentransit.net!newsfeed.comtenidos.com!m2newsfeed.uni2.es!m2newsread.uni2.es.POSTED!not-for-mail
References: <95k2uu$kh6$1@m2newsreader01.wanadoo.es> <95nddf$n8c$1@m2wpersoisp01.wanadoo.es> <G7gg6.4027$T9.51249236@news.jazztel.es> <slrn983lh6.1og.gorka@conan.hondarribia.penguinpowered.com> <961834$jfv$1@m2wpersoisp01.wanadoo.es>

Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII
X-Google-Thread: f86c8,b79667b5118ecabf
X-Google-Attributes: gidf86c8,public
X-Google-ArrivalTime: 2001-02-12 03:22:06 PST
Path: arc1-ca.pugleaf.net!supernews.google.com!sn-xit-03!supernews.com!nntp.cs.ubc.ca!skynet.be!fr.clara.net!heighliner.fr.clara.net!opentransit.net!newsfeed.comtenidos.com!m2newsfeed.uni2.es!m2newsread.uni2.es.POSTED!not-for-mail
From: luname@linuxfan.com (Manuel López Moreno)
Newsgroups: es.comp.os.linux.programacion
Subject: Re: reproductor de CD "pofessional"
References: <95k2uu$kh6$1@m2newsreader01.wanadoo.es> <95nddf$n8c$1@m2wpersoisp01.wanadoo.es> <G7gg6.4027$T9.51249236@news.jazztel.es> <slrn983lh6.1og.gorka@conan.hondarribia.penguinpowered.com> <961834$jfv$1@m2wpersoisp01.wanadoo.es>
Message-ID: <slrn98fhdl.lr.luname@mantium.luname.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
User-Agent: slrn/0.9.6.2 (Linux)
Lines: 316
Date: Mon, 12 Feb 2001 11:20:29 GMT
NNTP-Posting-Host: 62.36.169.113
X-Complaints-To: abuse@wanadoo.es
X-Trace: m2newsread.uni2.es 981976829 62.36.169.113 (Mon, 12 Feb 2001 12:20:29 MET)
NNTP-Posting-Date: Mon, 12 Feb 2001 12:20:29 MET
Organization: Servidor Usenet News de Uni2/Wanadoo