[comp.sys.next] Real-time recording and playback of sound

CMH117@psuvm.psu.edu (Charles Hannum) (03/28/90)

I've been going crazy for the past three days.  For some reason, the below
program consistently gives me errors, namely:

  Timeout
  Cannot access hardware resource
  Cannot record sound

Now, could someone PLEASE tell me why this fails, and why the reasons for these
error codes aren't listed in the manual?

I'd appreciate email.  If someone is *really* interested I can summarize, or
mail a summary.

Thanks for your help.

- Charles Hannum
  cmh117@haydn.psu.edu        <------ SEND MAIL HERE!!
  cmh117@psuvm.psu.edu


-------8<-------snip-------8<-------snip-------8<-------snip-------8<-------
#import <cthreads.h>
#import <sound/sound.h>
#import <stdio.h>
#import <stdarg.h>


#ifndef NO_DEBUG
#define debug(x)  do { printf x; fflush(stdout); } while(0)
#else
#define debug(x)
#endif


#define BUFFERS 6
#define BUFLEN  4096


char *dst, *src;

SNDSoundStruct  *sound[BUFFERS];

mutex_t         tag_m,
                stuffed_m;
condition_t     stuffed_c;

int     tag     = 10000,
        s_in    = 0,
        n_in    = 0,
        s_out   = 0,
        n_out   = 0,
        s_num   = 0;


void    check(char *where, int err)
{
        if      (err != SND_ERR_NONE)
        {
                fprintf(stderr, "SNDError at %s: %s\n", where,
                                                        SNDSoundError(err));
                exit(7);
        }
}


int     tagme(void)
{
        int     atag;

        mutex_lock(tag_m);
        atag=tag++;
        mutex_unlock(tag_m);

        return(atag);
}


void    c_wait(char *where, condition_t c, mutex_t m)
{
        debug(("wait at %s\n",where));
        condition_wait(c,m);
}

void    c_signal(char *where, condition_t c)
{
        debug(("signal at %s\n",where));
        condition_broadcast(c);
}


int     checkit(SNDSoundStruct *t, int oldtag, int err)
{
        check("checkit",err);
}


int     played(SNDSoundStruct *t, int oldtag, int err)
{
        debug(("played     ot:%3d\n",oldtag));
        check("played",err);

        mutex_lock(stuffed_m);
        --n_out;
        c_signal("played",stuffed_c);
        mutex_unlock(stuffed_m);
}


int     play(void)
{
        check("play(res)",SNDReserve(SND_ACCESS_OUT,0));

        while   (1)
        {
                debug(("play(1)    si:%2d, ni:%2d, so:%2d, no:%2d, sn:%2d\n",
                                        s_in, n_in, s_out, n_out, s_num));

                mutex_lock(stuffed_m)
                while   (((n_out+n_in)>=BUFFERS) | (s_num<=0))
                        c_wait("play",stuffed_c,stuffed_m);
                ++n_out;
                --s_num;
                mutex_unlock(stuffed_m);

                debug(("play(2)    si:%2d, ni:%2d, so:%2d, no:%2d, sn:%2d\n",
                                        s_in, n_in, s_out, n_out, s_num));
                check("play",SNDStartPlaying(sound[s_out],tagme(),0,0,
                                                        checkit,played));
                s_out++;
                if      (s_out>=BUFFERS)
                        s_out=0;

                debug(("play(3)    si:%2d, ni:%2d, so:%2d, no:%2d, sn:%2d\n",
                                        s_in, n_in, s_out, n_out, s_num));
        }
}


int     recorded(SNDSoundStruct *t, int oldtag, int err)
{
        debug(("recorded   ot:%3d\n",oldtag));
        check("recorded",err);

        mutex_lock(stuffed_m);
        --n_in;
        ++s_num;
        c_signal("recorded",stuffed_c);
        mutex_unlock(stuffed_m);
}


int     record(void)
{
        check("record(reserve)", SNDReserve(SND_ACCESS_IN, 0));

        while   (1)
        {
                debug(("record(1)  si:%2d, ni:%2d, so:%2d, no:%2d, sn:%2d\n",
                                        s_in, n_in, s_out, n_out, s_num));

                mutex_lock(stuffed_m);
                while   (((n_in+n_out)>=BUFFERS) | (n_in>=(BUFFERS-2)))
                        c_wait("record",stuffed_c,stuffed_m);
                n_in++;
                mutex_unlock(stuffed_m);

                debug(("record(2)  si:%2d, ni:%2d, so:%2d, no:%2d, sn:%2d\n",
                                        s_in, n_in, s_out, n_out, s_num));
                check("record",SNDStartRecording(sound[s_in],tagme(),
                                                0, 0, checkit,recorded));
                s_in++;
                if      (s_in>=BUFFERS)
                        s_in=0;

                debug(("record(3)  si:%2d, ni:%2d, so:%2d, no:%2d, sn:%2d\n",
                                        s_in, n_in, s_out, n_out, s_num));
        }
}


int     main(int argc, char **argv)
{
        int     i;

        for     (i=0; i<BUFFERS; i++)
                check("main(alloc)", SNDAlloc(&sound[i], BUFLEN,
                                SND_FORMAT_MULAW_8, SND_RATE_CODEC, 1, 0));

        cthread_init();

        tag_m     = mutex_alloc();
        stuffed_m = mutex_alloc();
        stuffed_c = condition_alloc();

        debug(("starting\n"));
        SNDSetHost(NULL);

        cthread_detach(cthread_fork(record));
        cthread_join  (cthread_fork(play));
        cthread_exit(0);
}
-------8<-------snip-------8<-------snip-------8<-------snip-------8<-------