From owner-freebsd-arch@FreeBSD.ORG Fri Aug 31 11:58:18 2007 Return-Path: Delivered-To: arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 33B4516A420; Fri, 31 Aug 2007 11:58:18 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe12.swip.net [212.247.155.97]) by mx1.freebsd.org (Postfix) with ESMTP id 7ADF513C45A; Fri, 31 Aug 2007 11:58:17 +0000 (UTC) (envelope-from hselasky@c2i.net) X-Cloudmark-Score: 0.000000 [] Received: from [194.248.135.20] (account mc467741@c2i.net HELO laptop.lan) by mailfe12.swip.net (CommuniGate Pro SMTP 5.1.10) with ESMTPA id 425111561; Fri, 31 Aug 2007 12:57:21 +0200 From: Hans Petter Selasky To: freebsd-arch@freebsd.org Date: Fri, 31 Aug 2007 12:57:30 +0200 User-Agent: KMail/1.9.7 References: <8412.1188553371@critter.freebsd.dk> In-Reply-To: <8412.1188553371@critter.freebsd.dk> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200708311257.31627.hselasky@c2i.net> Cc: arch@freebsd.org, Poul-Henning Kamp Subject: Re: Proof of concept: soundcard as console device X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Aug 2007 11:58:18 -0000 Hi, This is really creative. Maybe you should add a simple N-tap FIR filter so that you limit the bandwidth used and don't destroy the soundcard :-) BTW: Why can't you use an USB serial adapter connected to the PC ? --HPS On Friday 31 August 2007, Poul-Henning Kamp wrote: > Yesterday while I was futzing with my new laptop and ACPI suspend/resume, > I once again found myself cursing the nutjob who took away our serial > ports. > > Then my mind wandered around a bit and suddenly it struck me: all > modern hardware have built in AC97 sound hardware, and it offers a > channel with a pretty decent bandwidth. > > This morning I ran a simple experiment, from userland, but the > result show clearly that the idea is workable. > > The transmission format I used: send a negative transient to start > a character and after N samples, send a positive transient, where > N is the ASCII value of the character + a small constant. > > I have attached my proof-of-concept code, which uses the two stereo > channels as a differential wire (not sure if this is a actually > good idea). > > In my first attempt, I was able to transmit around 320 characters > per second with something that looks like 1% error rate. > > What's left to do: > > * optimize transmission schema. > > This can be done with two computers, a jack-jack cable > and a bit of C-coding. > > The difference in sample rate between the two machines > causes off-by-one errors. I don't know of a peak detector > which interpolates can resolve this, of if we need use > oversampling in the receiver. > > The two pulses can have two different polarities each, > so we can transmit two bits just that way, this could speed > up transmission by a factor of four, if we can find a way > to synchronize properly. > > The two stereo channels can be used independently, offering > a doubling in speed. > > * write a kernel console driver which talks to the sound hardware > without using interrupts. > > I don't know what the hardware interface to a sound card > looks like, but I suspect this might be fairly easy. > > Even if the connection is one-way, kernel-hackers like me will worship > any person who completes this task. > > Have at it... > > Poul-Henning > > ----------------------------------------------------------------------- > /* proof of concept transmission code */ > #include > #include > #include > #include > > #define OFF 5 > > static short int buf[2*128 + 2 * OFF]; > > int > main(int argc __unused, char **argv __unused) > { > int fd_dsp; > int i, j, k, c; > > fd_dsp = open("/dev/dsp0.1", O_RDWR); > if (fd_dsp < 0) > err(1, "open /dev/dsp"); > > i = ioctl(fd_dsp, SNDCTL_DSP_RESET, &j); > assert(i == 0); > > j = 2; > i = ioctl(fd_dsp, SNDCTL_DSP_CHANNELS, &j); > assert(i == 0); > > j = 44100; > i = ioctl(fd_dsp, SNDCTL_DSP_SPEED, &j); > assert(i == 0); > > j = 16; > i = ioctl(fd_dsp, SNDCTL_DSP_SETFMT, &j); > assert(i == 0); > > > while (1) { > c = getchar(); > if (c == EOF) > break; > buf[OFF] = 32000; > buf[OFF + 1] = -32000; > > buf[OFF + 2 * c] = -32000; > buf[OFF + 2 * c + 1] = 32000; > > i = write(fd_dsp, buf, sizeof buf); > assert(i == sizeof buf); > > buf[OFF + 2 * c] = 0; > buf[OFF + 1 + 2 * c] = 0; > } > > exit (0); > } > ----------------------------------------------------------------------- > /* proof of concept reception code */ > #include > #include > > static int > sample(FILE *f, const char *p) > { > short l, r; > int i, s; > > i = fread(&l, sizeof l, 1, stdin); > assert(i == 1); > i = fread(&r, sizeof l, 1, stdin); > assert(i == 1); > s = l; > s -= r; > if (0 && p != NULL) > printf("%6d %s\n", s, p); > return (s); > } > > static void > find_neg_peak(FILE *f) > { > int s, sl; > > while (1) { > s = sample(stdin, "v"); > if (s < -10000) > break; > } > sl = s; > while (1) { > s = sample(stdin, "N"); > if (s > sl) > return; > sl = s; > } > } > > static int > find_pos_peak(FILE *f) > { > int s, sl, k; > > k = 0; > while (1) { > k++; > s = sample(stdin, "^"); > if (s > 10000) > break; > } > sl = s; > while (1) { > k++; > s = sample(stdin, "P"); > if (s < sl) > return (k); > sl = s; > } > } > > > int > main(int argc __unused, char **argv) > { > short l, r; > int i, k, p, s, sl; > > k = 0; > p = 0; > while (1) { > find_neg_peak(stdin); > k = find_pos_peak(stdin); > if (k == 10) > printf("\\n\n"); > else if (k >= ' ' && k <= '~') > printf("%c", k); > else > printf("\\x%02x", k); > } > exit (0); > } > -----------------------------------------------------------------------