Rich,

On Mon, 4 Jun 2001, Rich Payne <[EMAIL PROTECTED]> wrote:
> 
> Well, it works OK here using XMMS instead of real, I just setup xmms to
> play and did a "rec test.wav" and sure enough the test.wav contained the
> audio, I don't have realplayer on this machine...but in theory :)

Hey that is pretty neat!

It doesn't seem to work for me here (the rec fails due to device busy).
I think this is because I am not running Enlightenment Sound Daemon (esd).
You are running esd, right?

Below is a hack I wrote that interposes on the open(2), close(2), and
write(2) system calls and tees the /dev/dsp output to a regular file.
It at least works with capturing RealPlayer output on my system.
sox(1) can then be used to replay or reformat the raw output.

I enclose it below since this LD_PRELOAD method is a general and rather
useful trick that can be used to interpose and "tweak" *any* function
call.  Many applications ;-)

Karl

----------------------------------------------------------------------------
/*
 * open.c:   interpose open() calls to /dev/dsp and tee the resulting dsp
 *           write()'s to a regular file.
 *
 * compile:  cc -shared -o open.so open.c
 *
 * run:      LD_PRELOAD=./open.so <cmd> <args>
 *           (e.g. <cmd> is "realplay")
 *
 * playback: sox -r 20000 -w -s -t raw /tmp/dsp.out.2 -t ossdsp /dev/dsp
 *
 *           The raw output file, "/tmp/dsp.out.2" here, is noted on stderr.
 *           The sampling rate, "20000" here, is noted on stderr, or otherwise
 *           you can attempt trial & error to guess the sampling rate.
 *           Use -c 2 for stereo. Use sox to convert to different formats.
 *           See sox(1) for more info.
 */

#include <stdio.h>
#include <fcntlbits.h>
#include <sys/soundcard.h>

#define SOX "playback: sox -r %d -w -s -t raw %s -t ossdsp /dev/dsp\n"

extern int     __open(const char *pathname, int flags, unsigned short mode); 
extern int     __close (int fd);
extern ssize_t __write (int fd, __const __ptr_t buf, size_t n);

int tee_fd, dsp_fd, dsp_written, cnt = 0;
char outfile[100];

int open(const char *pathname, int flags, unsigned short mode) {
        int fd, fd2;
        fd = __open(pathname, flags, mode);

        if (!strcmp("/dev/dsp", pathname) && fd > 0 ) {
                sprintf(outfile, "/tmp/dsp.out.%d", ++cnt);
                dsp_written = 0;
                dsp_fd = 0;
                tee_fd = 0;
                fd2 = __open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 00644);
                if ( fd2 > 0 ) {
                        dsp_fd = fd;
                        tee_fd = fd2;
                        fprintf(stderr,"teeing audio dsp_fd %d to fd %d "
                                "aka %s ...\n", dsp_fd, fd2, outfile);
                }
        }
        return fd;
}

int close(int fd) {
        if ( fd == dsp_fd && tee_fd > 1 ) {
                __close(tee_fd);
                fprintf(stderr, "closing tee_fd: %d aka %s\n", tee_fd, outfile);
                tee_fd = 0;
        }
        return(__close(fd));
}

ssize_t write (int fd, __const __ptr_t buf, size_t n) {
        if ( fd == dsp_fd && tee_fd > 1 ) {
                if ( ! dsp_written ) {
                        int speed = 0; 
                        if ( ioctl(fd, SNDCTL_DSP_SPEED, &speed) == 0 ) {
                                fprintf(stderr, "speed for dsp_fd %d is: %d\n",
                                        fd, speed);
                                fprintf(stderr, SOX, speed, outfile);
                        }
                        dsp_written = 1;
                }
                __write(tee_fd, buf, n);
        }
        return(__write(fd, buf, n));
}


**********************************************************
To unsubscribe from this list, send mail to
[EMAIL PROTECTED] with the following text in the
*body* (*not* the subject line) of the letter:
unsubscribe gnhlug
**********************************************************

Reply via email to