ftp.nice.ch/peanuts/GeneralData/Documents/dsp/DSPTutorial.tar.gz#/DSPTutorial/Examples/04_Through_DSP/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.

// An example of how to play a sound through the DSP. We pass the sample using
// a non DMA protocol, which may cause drop outs to occur, especially if the
// sound file is 44100 stereo.
// To improve it, we can set-up more buffers in the driver (16 instead of just
// 4), at the cost of real time (there will be a longer delay between the time
// the first samples were sent and the time you'll hear them.)
// If the sound is mono, we pass a host command to the DSP to tell it to 
// duplicate every sample, since the stream to the DACs has to be stereo.



#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 2048

static void read_completed(void *arg, int ta)
{
    fprintf(stderr,"playing completed \n");
    exit(0);
}

static void read_started(void *arg, int tag)
{
    fprintf(stderr,"Playing Started \n");
}




void main (int argc, char *argv[])
{
    int i;
    static port_t dev_port, owner_port;
    static port_t reply_port, write_port,cmd_port;
    kern_return_t k_err;
    snddriver_handlers_t handlers = { 0, 0, 
    read_started,read_completed,0,0,0, 0, 0};
    msg_header_t *reply_msg;
    SNDSoundStruct *sound;
    SNDSoundStruct *dspStruct;
    short *location;
    int low_water = 48*1024;
    int high_water = 64*1024;
    int WRITE_TAG = 1;
    int length,protocol;
    int low_SR = 0;
    int stereo = 0;

    
    if(argc == 1) { printf("I need a 16bit linear sound file...\n");
    exit(1);}
    

    k_err = SNDAcquire(SND_ACCESS_OUT|SND_ACCESS_DSP,0,0,0,
    		NULL_NEGOTIATION_FUN,0,&dev_port,&owner_port); 
    Error(k_err,"SND acquisition  ");
    
    k_err = port_allocate(task_self(),&reply_port);
    k_err = snddriver_get_dsp_cmd_port(dev_port,owner_port,&cmd_port);

// To give us more headroom, we can force the driver to set-up more buffers.
    
    k_err = snddriver_set_sndout_bufcount(dev_port,owner_port,16);
    Error(k_err,"Buff count  ");

    k_err = SNDReadSoundfile(argv[1], &sound);
    Error(k_err,argv[1]);
    
    low_SR = (sound->samplingRate == SND_RATE_LOW);
    stereo = (sound->channelCount == 2);
    printf("Playing at %d Hz %s\n",((low_SR)?22050:44100),((stereo)?
    	"stereo":"mono"));

    k_err = SNDGetDataPointer(sound,(char**)&location,&length,&i);
    Error(k_err,"Data Pointer");

    protocol = SNDDRIVER_DSP_PROTO_RAW;
    k_err = snddriver_stream_setup(dev_port, owner_port,((low_SR) ?
			SNDDRIVER_STREAM_THROUGH_DSP_TO_SNDOUT_22:
			SNDDRIVER_STREAM_THROUGH_DSP_TO_SNDOUT_44),
			DMASIZE, 2, 
			low_water, high_water,
			&protocol, &write_port);
    Error(k_err,"Stream  ");

    k_err = snddriver_dsp_protocol(dev_port, owner_port, protocol);
    Error(k_err,"Protocol");

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

    k_err = SNDBootDSP(dev_port, owner_port, dspStruct);
    Error(k_err,"DSP BOOT");

    if(!stereo)
    k_err = snddriver_dsp_host_cmd(cmd_port,20,SNDDRIVER_LOW_PRIORITY);

    k_err = snddriver_stream_start_writing(write_port,location,
	    length, WRITE_TAG,0,0,1,1,0,0,0,0, reply_port);
    Error(k_err,"Write Command  ");
    
    reply_msg = (msg_header_t *)malloc(MSG_SIZE_MAX);
    while (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);
	if(!k_err) snddriver_reply_handler(reply_msg,&handlers);
	}
}



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