9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] tiny patch to acd
@ 2001-12-19 16:37 rog
  0 siblings, 0 replies; 2+ messages in thread
From: rog @ 2001-12-19 16:37 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 895 bytes --]

if the track names are long, cddb splits its track/title lines;
e.g.
cddb DTITLE=Buddy MacMaster, fiddle, and 14 accompanists on piano / The Judique Fly
cddb DTITLE=er
cddb TTITLE0=Donald Angus Beaton Set (Joey Beaton, acc):  Dan R's Fav, Willie Frase
cddb TTITLE0=r's, Francis Beaton's, Derrick Beaton's

this caused some very odd looking track listings, not surprisingly.

the attached cddb.c fixes that (but i didn't want to delve too deeply
into how/when track title strings were allocated, so you might find
the way i've done it a little conservative and/or restrictive.

while on the subject, i've been thinking of adding the ability to edit
the track titles in acme and do a Put which would either automatically
submit to cddb (if possible) or store them locally to be retrieved the
next time.  the reason: i've got lots of CDs which cddb has never heard of.

  rog.


[-- Attachment #2: Type: message/rfc822, Size: 3865 bytes --]


/* see CDDBPROTO */
static ulong
cddb_sum(int n)
{
	int ret;
	ret = 0;
	while(n > 0) {
		ret += n%10;
		n /= 10;
	}
	return ret;
}

static ulong
diskid(Toc *t)
{
	int i, n, tmp;
	Msf *ms, *me;

	n = 0;
	for(i=0; i < t->ntrack; i++)
		n += cddb_sum(t->track[i].start.m*60+t->track[i].start.s);

	ms = &t->track[0].start;
	me = &t->track[t->ntrack].start;
	tmp = (me->m*60+me->s) - (ms->m*60+ms->s);

	/*
	 * the spec says n%0xFF rather than n&0xFF.  it's unclear which is correct.
	 * most CDs are in the database under both entries.
	 */
	return ((n & 0xFF) << 24 | (tmp << 8) | t->ntrack);
}

static void
append(char **d, char *s)
{
	char *r;
	if (*d == nil)
		*d = estrdup(s);
	else {
		r = emalloc(strlen(*d) + strlen(s) + 1);
		strcpy(r, *d);
		strcat(r, s);
		free(*d);
		*d = r;
	}
}

static int
cddbfilltoc(Toc *t)
{
	int fd;
	int i;
	char *p, *q;
	Biobuf bin;
	Msf *m;
	char *f[10];
	int nf;
	char *id, *categ;
	char gottrack[MTRACK];
	int gottitle;

	fd = dial("tcp!freedb.freedb.org!888", 0, 0, 0);
	if(fd < 0) {
		fprint(2, "cannot dial: %r\n");
		return -1;
	}
	Binit(&bin, fd, OREAD);

	if((p=Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2) {
	died:
		close(fd);
		Bterm(&bin);
		fprint(2, "error talking to server\n");
		if(p) {
			p[Blinelen(&bin)-1] = 0;
			fprint(2, "server says: %s\n", p);
		}
		return -1;
	}

	fprint(fd, "cddb hello gre plan9 9cd 1.0\r\n");
	if((p = Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2)
		goto died;

	fprint(fd, "cddb query %8.8lux %d", diskid(t), t->ntrack);
	DPRINT(2, "cddb query %8.8lux %d", diskid(t), t->ntrack);
	for(i=0; i<t->ntrack; i++) {
		m = &t->track[i].start;
		fprint(fd, " %d", (m->m*60+m->s)*75+m->f);
		DPRINT(2, " %d", (m->m*60+m->s)*75+m->f);
	}
	m = &t->track[t->ntrack-1].end;
	fprint(fd, " %d\r\n", m->m*60+m->s);
	DPRINT(2, " %d\r\n", m->m*60+m->s);

	if((p = Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2)
		goto died;
	p[Blinelen(&bin)-1] = 0;
	DPRINT(2, "cddb: %s\n", p);
	nf = tokenize(p, f, nelem(f));
	if(nf < 1)
		goto died;

	switch(atoi(f[0])) {
	case 200:	/* exact match */
		if(nf < 3)
			goto died;
		categ = f[1];
		id = f[2];
		break;
	case 211:	/* close matches */
		if((p = Brdline(&bin, '\n')) == nil)
			goto died;
		if(p[0] == '.')	/* no close matches? */
			goto died;
		p[Blinelen(&bin)-1] = '\0';

		/* accept first match */
		nf = tokenize(p, f, nelem(f));
		if(nf < 2)
			goto died;
		categ = f[0];
		id = f[1];

		/* snarf rest of buffer */
		while(p[0] != '.') {
			if((p = Brdline(&bin, '\n')) == nil)
				goto died;
			p[Blinelen(&bin)-1] = '\0';
			DPRINT(2, "cddb: %s\n", p);
		}
		break;
	case 202: /* no match */
	default:
		goto died;
	}

	/* fetch results for this cd */
	fprint(fd, "cddb read %s %s\r\n", categ, id);

	memset(gottrack, 0, sizeof(gottrack));
	gottitle = 0;
	do {
		if((p = Brdline(&bin, '\n')) == nil)
			goto died;
		q = p+Blinelen(&bin)-1;
		while(isspace(*q))
			*q-- = 0;
DPRINT(2, "cddb %s\n", p);
		if(strncmp(p, "DTITLE=", 7) == 0) {
			if (gottitle)
				append(&t->title, p + 7);
			else
				t->title = estrdup(p+7);
			gottitle = 1;
		} else if(strncmp(p, "TTITLE", 6) == 0 && isdigit(p[6])) {
			i = atoi(p+6);
			if(i < t->ntrack) {
				p += 6;
				while(isdigit(*p))
					p++;
				if(*p == '=')
					p++;

				if (gottrack[i])
					append(&t->track[i].title, p);
				else
					t->track[i].title = estrdup(p);
				gottrack[i] = 1;
			}
		}
	} while(*p != '.');

	fprint(fd, "quit\r\n");
	close(fd);
	Bterm(&bin);

	return 0;
}

void
cddbproc(void *v)
{
	Drive *d;
	Toc t;

	threadsetname("cddbproc");
	d = v;
	while(recv(d->cdbreq, &t))
		if(cddbfilltoc(&t) == 0)
			send(d->cdbreply, &t);
}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [9fans] tiny patch to acd
@ 2001-12-19 17:34 rog
  0 siblings, 0 replies; 2+ messages in thread
From: rog @ 2001-12-19 17:34 UTC (permalink / raw)
  To: 9fans

oops, that was meant for Russ.
sorry.



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-12-19 17:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-19 16:37 [9fans] tiny patch to acd rog
2001-12-19 17:34 rog

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).