1/* 2 * Driver for the NeXT / Apple soundkit objects for use on OpenStep 3 * systems. Based on the older sound drivers, converted into the new 4 * style framework by taking a long hard look at esound.c. 5 * 6 * -bat. 06/09/2000 7 */ 8 9#import <stdio.h> 10#import <stdlib.h> 11#import <unistd.h> 12#import <SoundKit/SoundKit.h> 13 14#import "sysdep/sysdep_dsp.h" 15#import "sysdep/sysdep_dsp_priv.h" 16#import "sysdep/plugin_manager.h" 17 18/* 19 * Destroy function - we release the playStream and free up 20 * the dsp structure. 21 */ 22 23static void 24soundkit_dsp_destroy(struct sysdep_dsp_struct *dsp) 25{ 26 NXPlayStream *playStream = (NXPlayStream*)dsp->_priv; 27 28 [playStream release]; 29 30 free(dsp); 31} 32 33/* 34 * Write a block of data to the sound object. We take pains to make sure it 35 * in the correct format by copying it around the place quite a lot - this 36 * makes 8 bit sound rather slow as we cannot write it to the device 37 * directly due to an intel bug. 38 */ 39 40static int 41soundkit_dsp_write(struct sysdep_dsp_struct *dsp, 42 unsigned char *data, int count) 43{ 44 static int theTag = 1; 45 static long buff_size = 0; 46 static unsigned char *out_buff = NULL; 47 48 BOOL isStereo = (dsp->hw_info.type & SYSDEP_DSP_STEREO) ? YES : NO; 49 NXPlayStream *playStream = (NXPlayStream*)dsp->_priv; 50 long bytes = sizeof(short) * count * (isStereo ? 2 : 1); 51 52 /* do a malloc if necessary */ 53 if(bytes > buff_size) { 54 if(out_buff) 55 free(out_buff); 56 out_buff = malloc(bytes); 57 if(!out_buff) 58 return 0; 59 buff_size = bytes; 60 } 61 62 /* do the byte swap and write the block */ 63 SNDSwapHostToSound(out_buff, data, count, 64 isStereo ? 2: 1, SND_FORMAT_LINEAR_16); 65 [playStream playBuffer:out_buff size:bytes tag:theTag++]; 66 67 return count; 68} 69 70/* 71 * Creation function. 72 */ 73 74static void* 75soundkit_dsp_create(const void *flags) 76{ 77 NXPlayStream *playStream = nil; 78 NXSoundOut *soundOut = nil; 79 NXSoundParameters *soundParams = nil; 80 SNDSoundStruct *soundStruct = NULL; 81 char *soundHost = getenv("SOUNDHOST"); 82 id priv = nil; 83 struct sysdep_dsp_struct *dsp = NULL; 84 const struct sysdep_dsp_create_params *params = flags; 85 86 /* allocate the dsp struct */ 87 if (!(dsp = calloc(1, sizeof(struct sysdep_dsp_struct)))) 88 { 89 perror("error malloc failed for struct sysdep_dsp_struct\n"); 90 return NULL; 91 } 92 93 /* create sound object (possibly remotely) */ 94 if(soundHost) { 95 soundOut = [[NXSoundOut alloc] 96 initOnHost:[NSString stringWithCString:soundHost]]; 97 if(!soundOut) { 98 fprintf(stderr, 99 "could not initialise sound object on %s\n", 100 soundHost); 101 return NULL; 102 } else 103 fprintf(stderr, "info: soundkit: send sound to %s\n", 104 soundHost); 105 } else 106 soundOut = [NXSoundOut new]; 107 108 if(!soundOut) { 109 fprintf(stderr,"could not initialise sound object\n"); 110 return NULL; 111 } 112 113 /* create a parameters object - always 16 bit please ! */ 114 dsp->hw_info.type |= SYSDEP_DSP_16BIT; 115 if(params->type & SYSDEP_DSP_STEREO) { 116 SNDAlloc(&soundStruct, 0, SND_FORMAT_LINEAR_16, 117 params->samplerate, 2, 0); 118 dsp->hw_info.type |= SYSDEP_DSP_STEREO; 119 } else { 120 SNDAlloc(&soundStruct, 0, SND_FORMAT_LINEAR_16, 121 params->samplerate, 1, 0); 122 } 123 soundParams = [[NXSoundParameters alloc] 124 initFromSoundStruct:soundStruct]; 125 if(!soundParams) { 126 fprintf(stderr,"could not create sound parameters\n"); 127 return NULL; 128 } 129 130 /* print the info */ 131 fprintf(stderr, "info: soundkit: %s sound at %d hz\n", 132 (dsp->hw_info.type & SYSDEP_DSP_STEREO) ? 133 "stereo" : "mono", params->samplerate); 134 135 /* create the stream object */ 136 playStream = [[NXPlayStream alloc] 137 initOnDevice:soundOut withParameters:soundParams]; 138 if(!playStream) { 139 fprintf(stderr,"could not create play stream\n"); 140 return NULL; 141 } 142 143 /* fill in the functions and some data */ 144 dsp->_priv = playStream; 145 dsp->write = soundkit_dsp_write; 146 dsp->destroy = soundkit_dsp_destroy; 147 dsp->hw_info.type = params->type; 148 dsp->hw_info.samplerate = params->samplerate; 149 150 /* activate and return */ 151 152 [playStream activate]; 153 return dsp; 154} 155 156/* 157 * The public variables structure 158 */ 159 160const struct plugin_struct sysdep_dsp_soundkit = { 161 "soundkit", 162 "sysdep_dsp", 163 "NeXT SoundKit plugin", 164 NULL, /* no options */ 165 NULL, /* no init */ 166 NULL, /* no exit */ 167 soundkit_dsp_create, 168 3 /* high priority */ 169}; 170