ftp.nice.ch/peanuts/GeneralData/Documents/dsp/DSPTutorial.tar.gz#/DSPTutorial/Examples/08_Codec_convert/perso_b.c

This is perso_b.c in view mode; [Download] [Up]

//Written by J. Laroche at the Center for Music Experiment at UCSD, San Diego //California. December 1990.

// A simple example recording from the CODEC microphone, and sending the data
// to the DSP where they are processed, and returned to the DACs...
// Note that the stream to the DSP is NON DMA.


#import <sound/sound.h>
#import <sound/sounddriver.h>
#import <mach.h>
#import <stdio.h>

#define Error(A,B) if((A)) {fprintf(stderr,"%s %s\n",B, SNDSoundError((A)));\
mach_error(B,(A)); }

#define DMASIZE 4096

static int done;
static char *read_data;
static int read_count;


static void read_completed(void *arg, int tag, void *p, int nbytes)
// This gets called when the entire result array has been read from SNDIN.
{
    printf("Recording done... \n");
	read_data = (char *)p;
	read_count = nbytes;
	done = 1;
}

static void read_started(void *arg, int tag)
// This gets called when the driver starts reading SNDIN.
{
    printf("Starting recording... \n");
}

static void write_completed(void *arg, int tag)
// This gets called when the driver has passed all the values to the DSP.
{
    printf("Playing done... \n");
    done = 1;
}



void main (int argc, char *argv[])
{
    static port_t dev_port, owner_port, cmd_port;
    static port_t reply_port, read_port, dsp_port;
    int i, protocol;
    kern_return_t k_err;
    snddriver_handlers_t handlers = { 0, 0, 
    		read_started, write_completed, 0, 0, 0, 0, read_completed};
    msg_header_t *reply_msg;
    SNDSoundStruct *dspStruct;
    int low_water = 48*1024;
    int high_water = 64*1024;
    int flag = 0;


    if(argc > 1 && argv[1][0] == 'o') flag = 1;
    if(argc > 1 && argv[1][0] == 'f') flag = 2;
    

    k_err = SNDAcquire(SND_ACCESS_DSP|SND_ACCESS_IN|SND_ACCESS_OUT,0,0,0,
    	NULL_NEGOTIATION_FUN,0,&dev_port,&owner_port); 
    Error(k_err,"SND and DSP acquisition  ");
    
    k_err = snddriver_get_dsp_cmd_port(dev_port,owner_port,&cmd_port);
    Error(k_err,"Cmd port acquisition  ");
    
    protocol = SNDDRIVER_DSP_PROTO_RAW;
    k_err = snddriver_stream_setup(dev_port, owner_port,
    				 SNDDRIVER_STREAM_FROM_SNDIN,
				 DMASIZE, 1, 
				 low_water, high_water,
				 &protocol, &read_port);
    Error(k_err,"Stream set_up");
    k_err = snddriver_stream_setup(dev_port, owner_port,
    				 SNDDRIVER_STREAM_THROUGH_DSP_TO_SNDOUT_44,
				 DMASIZE, 1, 
				 low_water, high_water,
				 &protocol, &dsp_port);
    Error(k_err,"To DSP set_up");
    
    k_err = snddriver_dsp_protocol(dev_port, owner_port, protocol);
    Error(k_err,"Protocol set-up  ");
    
    k_err = port_allocate(task_self(),&reply_port);
    k_err = snddriver_stream_start_reading(read_port,0,32000,1,
					 	1,0,0,0,0,1, reply_port);
    Error(k_err,"Starting reading  ");

    k_err = SNDReadDSPfile("perso_b.lod", &dspStruct, NULL);
    Error(k_err,"Reading .lod file  ");

    k_err = SNDBootDSP(dev_port, owner_port, dspStruct);
    Error(k_err,"Booting DSP  ");
    printf("DSP booted\n");



    reply_msg = (msg_header_t *)malloc(MSG_SIZE_MAX);
    done = 0;

    while (done != 1) 
	{
	    reply_msg->msg_size = MSG_SIZE_MAX;
	    reply_msg->msg_local_port = reply_port;
	    k_err = msg_receive(reply_msg, MSG_OPTION_NONE, 0);
	    k_err = snddriver_reply_handler(reply_msg,&handlers);
	}
    
    //
    // print elements of result if requested...
    //
    switch(flag)
    {
	case 2 : for (i=0; i<16000; i++)
	    printf("output[%d] = %x %d \n",i,read_data[i],read_data[i]); break;
	case 1 : write(1,read_data,16000*sizeof(char));	break; 
    }
    
    k_err = snddriver_stream_start_writing(dsp_port, read_data, 32000,1,
					 0,0,0,1,0,0,0,0, reply_port);
    Error(k_err,"Starting writing  ");

    done = 0;
    while (done != 1) 
	{
	    reply_msg->msg_size = MSG_SIZE_MAX;
	    reply_msg->msg_local_port = reply_port;
	    k_err = msg_receive(reply_msg, MSG_OPTION_NONE, 0);
	    k_err = snddriver_reply_handler(reply_msg,&handlers);
	}
    
    //
    // Data received in the read_handler should be deallocated
    //
    vm_deallocate(task_self(),(pointer_t)read_data,read_count);
}


These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.