This is SineController.m in view mode; [Download] [Up]
/********************************************************************************* * objects by jf * all the real code lifted from /********************************************************************************* * * PROGRAM: sine.c * * AUTHOR: Leonard Manzara * * THIS PROGRAM GENERATES A SINE WAVE ON THE DSP AND PLAYS IT THROUGH * THE NeXT DAC. BASED HEAVILY ON dsp_example_3. * COMPILE THIS WITH: cc sine.c -ansi -lm -lsys_s -O * THE DSP ASSEMBLY PROGRAM IS: sine.asm * *********************************************************************************/ /* Generated by Interface Builder */ #import <stdlib.h> #import <stdio.h> #import <libc.h> /* for sleep */ #import <appkit/defaults.h> /* NXArgv */ #import <appkit/Slider.h> #import <appkit/Application.h> /* NXApp */ #import <text/pathutil.h> /* so we can strip out path name to find the .lod file when launching*/ #import "SineController.h" @implementation SineController static char tempName[1024]; /* use the appDidInit to setup all of the port communication with the DSP */ - appDidInit:sender { /* INITIALIZE DMA STREAMING VARIABLES */ low_water = 48*1024; high_water = 64*1024; read_width = 2; read_buf_size = 512; /* GET THE DEVICE PORT FOR THE SOUND/DSP DRIVER ON THE LOCAL MACHINE */ k_err = netname_look_up(name_server_port,"","sound",&dev_port); if (k_err != KERN_SUCCESS) { mach_error("netname lookup failure ",k_err); return(0); } /* GET THE OWNER PORT */ k_err = port_allocate(task_self(),&owner_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot allocate owner port ",k_err); return(0); } /* BECOME OWNER OF DSP RESOURCES */ temp_port = owner_port; k_err = snddriver_set_dsp_owner_port(dev_port,owner_port,&temp_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot become owner of dsp resources ",k_err); return(0); } /* GET THE DSP COMMAND PORT */ k_err = snddriver_get_dsp_cmd_port(dev_port,owner_port,&cmd_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot acquire command port ",k_err); return(0); } /* ACQUIRE OWNERSHIP OF THE SOUND OUTPUT DEVICE */ k_err = snddriver_set_sndout_owner_port(dev_port,owner_port,&temp_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot become owner of sound out device ",k_err); return(0); } /* SET UP TO STREAM DATA FROM THE DSP TO THE SOUND DEVICE */ protocol = 0; k_err = snddriver_stream_setup(dev_port,owner_port,SNDDRIVER_STREAM_DSP_TO_SNDOUT_44, read_buf_size,read_width,low_water,high_water, &protocol,&read_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot set up stream from DSP ",k_err); return(0); } /* SET THE DSP PROTOCOL */ k_err = snddriver_dsp_protocol(dev_port,owner_port,protocol); if (k_err != KERN_SUCCESS) { mach_error("Cannot set up DSP protocol ",k_err); return(0); } /* ALLOCATE A PORT FOR REPLIES */ k_err = port_allocate(task_self(),&reply_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot allocate reply port ",k_err); return(0); } /* PARSE THE .LOD ASSEMBLY FILE AND BOOT THE DSP WITH IT */ strcpy(tempName, parentname(NXArgv[0])); strcat(tempName,"/sine.lod"); s_err = SNDReadDSPfile(tempName,&dspStruct,NULL); if (s_err != SND_ERR_NONE) { fprintf(stderr,"Cannot parse DSP load image: %s\n",SNDSoundError(s_err)); return(0); } s_err = SNDBootDSP(dev_port,owner_port,dspStruct); if (s_err != SND_ERR_NONE) { fprintf(stderr,"Cannot boot dsp: %s\n",SNDSoundError(s_err)); return(0); } /* START STREAM FROM THE DSP */ k_err = snddriver_stream_start_reading(read_port,NULL, read_count,0, 0,0,0,0,0,0,reply_port); if (k_err != KERN_SUCCESS) { mach_error("Cannot enqueue read request ",k_err); return(0); } /* SEND INTIAL TABLE VALUE TO DSP */ k_err = snddriver_dspcmd_req_condition(cmd_port,SNDDRIVER_ISR_HF3, SNDDRIVER_ISR_HF3,SNDDRIVER_HIGH_PRIORITY,PORT_NULL); if (k_err != KERN_SUCCESS) { mach_error("Cannot request condition ",k_err); return(0); } reply = 0; k_err = snddriver_dsp_write(cmd_port,&reply,1,4,SNDDRIVER_MED_PRIORITY); if (k_err != KERN_SUCCESS) { mach_error("Cannot write to DSP ",k_err); return(0); } k_err = snddriver_dspcmd_req_condition(cmd_port,SNDDRIVER_ISR_HF3,0, SNDDRIVER_HIGH_PRIORITY,PORT_NULL); if (k_err != KERN_SUCCESS) { mach_error("Cannot request condition ",k_err); return(0); } /* SEND HOST COMMAND TO THE DSP CHIP; VECTOR = P:$0026 CAUSES PROGRAM CONTROL TO JMP TO MAIN, WHERE SOUND SAMPLES ARE SENT NOTE THAT THE HOST COMMAND IS THE VECTOR ADDRESS DIVIDED BY 2 */ k_err = snddriver_dsp_host_cmd(cmd_port,(u_int)0x13,SNDDRIVER_HIGH_PRIORITY); if (k_err != KERN_SUCCESS) { mach_error("Cannot send host command ",k_err); return(0); } return self; } - takeSkipValueFrom:sender { /* SEND INTIAL TABLE VALUE TO DSP */ //k_err = snddriver_dspcmd_req_condition(cmd_port,SNDDRIVER_ISR_HF3, // SNDDRIVER_ISR_HF3,SNDDRIVER_HIGH_PRIORITY,PORT_NULL); //if (k_err != KERN_SUCCESS) { // mach_error("Cannot request condition ",k_err); // return(0); //} reply = [sender intValue]; k_err = snddriver_dsp_write(cmd_port,&reply,1,4,SNDDRIVER_MED_PRIORITY); if (k_err != KERN_SUCCESS) { mach_error("Cannot write to DSP ",k_err); return(0); } //k_err = snddriver_dspcmd_req_condition(cmd_port,SNDDRIVER_ISR_HF3,0, // SNDDRIVER_HIGH_PRIORITY,PORT_NULL); //if (k_err != KERN_SUCCESS) { // mach_error("Cannot request condition ",k_err); // return(0); //} return self; } - stopDSP:sender { /* send a 0 down to avoid the popping on the sound after we quit (DOESN'T work) */ reply = 0; k_err = snddriver_dsp_write(cmd_port,&reply,1,4,SNDDRIVER_MED_PRIORITY); if (k_err != KERN_SUCCESS) { mach_error("Cannot write to DSP ",k_err); return(0); } sleep(1); /* PLAY THE SINE TONE UNTIL PROGRAM TERMINATED. VECTOR = p:$0028 CAUSES PROGRAM CONTROL TO JMP TO RESET, EFFECTIVELY STOPPING SAMPLE OUT */ k_err = snddriver_dsp_host_cmd(cmd_port,(u_int)0x14,SNDDRIVER_HIGH_PRIORITY); if (k_err != KERN_SUCCESS) { mach_error("Cannot send host command ",k_err); return(0); } return self; } - terminate:sender /* tied from menu */ { [self stopDSP:sender]; [NXApp terminate:sender]; return self; } - windowWillClose:sender /* connection in nib says we are window delegate */ { [self stopDSP:sender]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.