This is sine.c in view mode; [Download] [Up]
/*********************************************************************************
*
* 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
*
*********************************************************************************/
#import <sound/sound.h>
#import <sound/sounddriver.h>
#import <mach.h>
#import <stdlib.h>
#import <stdio.h>
static int read_count;
main()
{
int s_err;
kern_return_t k_err;
port_t dev_port, owner_port, cmd_port, temp_port, stream_port, read_port, reply_port;
SNDSoundStruct *dspStruct;
int reply, read_buf_size, read_width, low_water, high_water, protocol;
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
/* PARSE THE .LOD ASSEMBLY FILE AND BOOT THE DSP WITH IT */
s_err = SNDReadDSPfile("sine.lod",&dspStruct,NULL);
if (s_err != SND_ERR_NONE) {
fprintf(stderr,"Cannot parse DSP load image: %s\n",SNDSoundError(s_err));
exit(1);
}
s_err = SNDBootDSP(dev_port,owner_port,dspStruct);
if (s_err != SND_ERR_NONE) {
fprintf(stderr,"Cannot boot dsp: %s\n",SNDSoundError(s_err));
exit(1);
}
/* 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);
exit(1);
}
/* 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);
exit(1);
}
printf("Enter table value: ");
scanf("%d",&reply);
getchar();
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);
exit(1);
}
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);
exit(1);
}
/* SEND HOST COMMAND TO THE DSP CHIP; VECTOR = P:$0026
CAUSES PROGRAM CONTROL TO JMP TO MAIN, WHERE SOUND SAMPLES ARE SENT OUT.
NOTE THAT THE HOST COMMAND IS THE VECTOR ADDRESS DIVIDED BY 2 */
printf("Push return to start sine wave:");
reply = getchar();
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);
exit(1);
}
/* PLAY THE SINE TONE UNTIL RETURN PUSHED AGAIN. VECTOR = p:$0028
CAUSES PROGRAM CONTROL TO JMP TO RESET, EFFECTIVELY STOPPING SAMPLE OUT */
printf("Push return to stop sine wave:");
reply = getchar();
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);
exit(1);
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.