Changeset 515 for GPL/branches
- Timestamp:
- Jul 14, 2010, 6:17:29 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/branches/uniaud32-2.1.x/lib32/sound.c
r504 r515 37 37 #include <stdlib.h> 38 38 #include <proto.h> 39 //#include <dbgos2.h> 39 40 #include "soundoss.h" 40 41 41 42 #undef samples_to_bytes 42 43 #undef bytes_to_samples 43 #define samples_to_bytes(a) 44 #define samples_to_bytes(a) ((a*pHandle->doublesamplesize)/2) 44 45 #define bytes_to_samples(a) (pHandle->doublesamplesize ? ((a*2)/pHandle->doublesamplesize) : a) 45 46 int GetMaxChannels(ULONG deviceid, int type); … … 57 58 //OSS32 to ALSA datatype conversion table 58 59 static int OSSToALSADataType[OSS32_PCM_MAX_FORMATS] = { 59 /* OSS32_PCM_FORMAT_S8 */ SNDRV_PCM_FORMAT_S8,//signed 8 bits sample60 /* OSS32_PCM_FORMAT_U8 */ SNDRV_PCM_FORMAT_U8,//unsigned 8 bits sample61 /* OSS32_PCM_FORMAT_S16_LE */ SNDRV_PCM_FORMAT_S16_LE, 62 /* OSS32_PCM_FORMAT_S16_BE */ SNDRV_PCM_FORMAT_S16_BE, 63 /* OSS32_PCM_FORMAT_U16_LE */ SNDRV_PCM_FORMAT_U16_LE, 64 /* OSS32_PCM_FORMAT_U16_BE */ SNDRV_PCM_FORMAT_U16_BE, 65 /* OSS32_PCM_FORMAT_S24_LE */ SNDRV_PCM_FORMAT_S24_LE, 66 /* OSS32_PCM_FORMAT_S24_BE */ SNDRV_PCM_FORMAT_S24_BE, 67 /* OSS32_PCM_FORMAT_U24_LE */ SNDRV_PCM_FORMAT_U24_LE, 68 /* OSS32_PCM_FORMAT_U24_BE */ SNDRV_PCM_FORMAT_U24_BE, 69 /* OSS32_PCM_FORMAT_S32_LE */ SNDRV_PCM_FORMAT_S32_LE, 70 /* OSS32_PCM_FORMAT_S32_BE */ SNDRV_PCM_FORMAT_S32_BE, 71 /* OSS32_PCM_FORMAT_U32_LE */ SNDRV_PCM_FORMAT_U32_LE, 72 /* OSS32_PCM_FORMAT_U32_BE */ SNDRV_PCM_FORMAT_U32_BE, 73 /* OSS32_PCM_FORMAT_MULAW */ SNDRV_PCM_FORMAT_MU_LAW, 74 /* OSS32_PCM_FORMAT_ALAW */ SNDRV_PCM_FORMAT_A_LAW, 75 /* OSS32_PCM_FORMAT_ADPCM */ SNDRV_PCM_FORMAT_IMA_ADPCM, 76 /* OSS32_PCM_FORMAT_MPEG */ SNDRV_PCM_FORMAT_MPEG, 60 /* OSS32_PCM_FORMAT_S8 */ SNDRV_PCM_FORMAT_S8, //signed 8 bits sample 61 /* OSS32_PCM_FORMAT_U8 */ SNDRV_PCM_FORMAT_U8, //unsigned 8 bits sample 62 /* OSS32_PCM_FORMAT_S16_LE */ SNDRV_PCM_FORMAT_S16_LE, //signed 16 bits sample (little endian/Intel) 63 /* OSS32_PCM_FORMAT_S16_BE */ SNDRV_PCM_FORMAT_S16_BE, //signed 16 bits sample (big endian/Motorola) 64 /* OSS32_PCM_FORMAT_U16_LE */ SNDRV_PCM_FORMAT_U16_LE, //unsigned 16 bits sample (little endian/Intel) 65 /* OSS32_PCM_FORMAT_U16_BE */ SNDRV_PCM_FORMAT_U16_BE, //unsigned 16 bits sample (big endian/Motorola) 66 /* OSS32_PCM_FORMAT_S24_LE */ SNDRV_PCM_FORMAT_S24_LE, //signed 24 bits sample (little endian/Intel) 67 /* OSS32_PCM_FORMAT_S24_BE */ SNDRV_PCM_FORMAT_S24_BE, //signed 24 bits sample (big endian/Motorola) 68 /* OSS32_PCM_FORMAT_U24_LE */ SNDRV_PCM_FORMAT_U24_LE, //unsigned 24 bits sample (little endian/Intel) 69 /* OSS32_PCM_FORMAT_U24_BE */ SNDRV_PCM_FORMAT_U24_BE, //unsigned 24 bits sample (big endian/Motorola) 70 /* OSS32_PCM_FORMAT_S32_LE */ SNDRV_PCM_FORMAT_S32_LE, //signed 32 bits sample (little endian/Intel) 71 /* OSS32_PCM_FORMAT_S32_BE */ SNDRV_PCM_FORMAT_S32_BE, //signed 32 bits sample (big endian/Motorola) 72 /* OSS32_PCM_FORMAT_U32_LE */ SNDRV_PCM_FORMAT_U32_LE, //unsigned 32 bits sample (little endian/Intel) 73 /* OSS32_PCM_FORMAT_U32_BE */ SNDRV_PCM_FORMAT_U32_BE, //unsigned 32 bits sample (big endian/Motorola) 74 /* OSS32_PCM_FORMAT_MULAW */ SNDRV_PCM_FORMAT_MU_LAW, //8 bps (compressed 16 bits sample) 75 /* OSS32_PCM_FORMAT_ALAW */ SNDRV_PCM_FORMAT_A_LAW, //8 bps (compressed 16 bits sample) 76 /* OSS32_PCM_FORMAT_ADPCM */ SNDRV_PCM_FORMAT_IMA_ADPCM, //4 bps (compressed 16 bits sample) 77 /* OSS32_PCM_FORMAT_MPEG */ SNDRV_PCM_FORMAT_MPEG, //AC3? 77 78 }; 78 79 … … 82 83 { 83 84 if(!strcmp(name, "alsa")) { 84 85 alsa_fops = fsop; 85 86 } 86 87 return 0; … … 91 92 { 92 93 if(!strcmp(name, "alsa")) { 93 94 alsa_fops = NULL; 94 95 } 95 96 return 0; … … 99 100 int register_sound_special(struct file_operations *fops, int unit) 100 101 { 101 102 103 104 102 if(fops == NULL) return -1; 103 104 memcpy(&oss_devices[OSS32_SPECIALID], fops, sizeof(struct file_operations)); 105 return OSS32_SPECIALID; 105 106 } 106 107 //****************************************************************************** … … 108 109 int register_sound_mixer(struct file_operations *fops, int dev) 109 110 { 110 111 112 113 111 if(fops == NULL) return -1; 112 113 memcpy(&oss_devices[OSS32_MIXERID], fops, sizeof(struct file_operations)); 114 return OSS32_MIXERID; 114 115 } 115 116 //****************************************************************************** … … 117 118 int register_sound_midi(struct file_operations *fops, int dev) 118 119 { 119 120 121 122 120 if(fops == NULL) return -1; 121 122 memcpy(&oss_devices[OSS32_MIDIID], fops, sizeof(struct file_operations)); 123 return OSS32_MIDIID; 123 124 } 124 125 //****************************************************************************** … … 126 127 int register_sound_dsp(struct file_operations *fops, int dev) 127 128 { 128 129 130 131 129 if(fops == NULL) return -1; 130 131 memcpy(&oss_devices[OSS32_DSPID], fops, sizeof(struct file_operations)); 132 return OSS32_DSPID; 132 133 } 133 134 //****************************************************************************** … … 135 136 int register_sound_synth(struct file_operations *fops, int dev) 136 137 { 137 138 139 140 138 if(fops == NULL) return -1; 139 140 memcpy(&oss_devices[OSS32_SYNTHID], fops, sizeof(struct file_operations)); 141 return OSS32_SYNTHID; 141 142 } 142 143 //****************************************************************************** … … 144 145 void unregister_sound_special(int unit) 145 146 { 146 147 memset(&oss_devices[OSS32_SPECIALID], 0, sizeof(struct file_operations)); 147 148 } 148 149 //****************************************************************************** … … 150 151 void unregister_sound_mixer(int unit) 151 152 { 152 153 memset(&oss_devices[OSS32_MIXERID], 0, sizeof(struct file_operations)); 153 154 } 154 155 //****************************************************************************** … … 156 157 void unregister_sound_midi(int unit) 157 158 { 158 159 memset(&oss_devices[OSS32_MIDIID], 0, sizeof(struct file_operations)); 159 160 } 160 161 //****************************************************************************** … … 162 163 void unregister_sound_dsp(int unit) 163 164 { 164 165 memset(&oss_devices[OSS32_DSPID], 0, sizeof(struct file_operations)); 165 166 } 166 167 //****************************************************************************** … … 168 169 void unregister_sound_synth(int unit) 169 170 { 170 171 memset(&oss_devices[OSS32_SYNTHID], 0, sizeof(struct file_operations)); 171 172 } 172 173 //****************************************************************************** … … 174 175 OSSRET UNIXToOSSError(int unixerror) 175 176 { 176 177 178 179 180 181 182 183 184 185 186 187 return OSSERR_AGAIN;//????188 189 190 191 192 193 194 195 196 197 198 199 200 177 switch(unixerror) { 178 case 0: 179 return OSSERR_SUCCESS; 180 case -ENOMEM: 181 return OSSERR_OUT_OF_MEMORY; 182 case -ENODEV: 183 return OSSERR_NO_DEVICE_AVAILABLE; 184 case -ENOTTY: 185 case -EINVAL: 186 return OSSERR_INVALID_PARAMETER; 187 case -EAGAIN: 188 return OSSERR_AGAIN; //???? 189 case -ENXIO: 190 return OSSERR_IO_ERROR; 191 case -EBUSY: 192 return OSSERR_BUSY; 193 case -EPERM: 194 return OSSERR_ACCESS_DENIED; //?? 195 case -EPIPE: 196 case -EBADFD: 197 return OSSERR_ACCESS_DENIED; //?? 198 default: 199 dprintf(("Unknown error %d", (unixerror > 0) ? unixerror : -unixerror)); 200 return OSSERR_UNKNOWN; 201 } 201 202 } 202 203 //****************************************************************************** … … 205 206 int ALSAToOSSDataType(ULONG ALSADataType) 206 207 { 207 208 209 210 return OSS32_CAPS_PCM_FORMAT_S8;//signed 8 bits sample211 212 return OSS32_CAPS_PCM_FORMAT_U8;//unsigned 8 bits sample213 214 return OSS32_CAPS_PCM_FORMAT_S16_LE;//signed 16 bits sample (little endian/Intel)215 216 return OSS32_CAPS_PCM_FORMAT_S16_BE;//signed 16 bits sample (big endian/Motorola)217 218 return OSS32_CAPS_PCM_FORMAT_U16_LE;//unsigned 16 bits sample (little endian/Intel)219 220 return OSS32_CAPS_PCM_FORMAT_U16_BE;//unsigned 16 bits sample (big endian/Motorola)221 222 return OSS32_CAPS_PCM_FORMAT_S24_LE;//signed 24 bits sample (little endian/Intel)223 224 return OSS32_CAPS_PCM_FORMAT_S24_BE;//signed 24 bits sample (big endian/Motorola)225 226 return OSS32_CAPS_PCM_FORMAT_U24_LE;//unsigned 24 bits sample (little endian/Intel)227 228 return OSS32_CAPS_PCM_FORMAT_U24_BE;//unsigned 16 bits sample (big endian/Motorola)229 230 return OSS32_CAPS_PCM_FORMAT_S32_LE;//signed 32 bits sample (little endian/Intel)231 232 return OSS32_CAPS_PCM_FORMAT_S32_BE;//signed 32 bits sample (big endian/Motorola)233 234 return OSS32_CAPS_PCM_FORMAT_U32_LE;//unsigned 32 bits sample (little endian/Intel)235 236 return OSS32_CAPS_PCM_FORMAT_U32_BE;//unsigned 32 bits sample (big endian/Motorola)237 238 return OSS32_CAPS_PCM_FORMAT_MULAW;//8 bps (compressed 16 bits sample)239 240 return OSS32_CAPS_PCM_FORMAT_ALAW;//8 bps (compressed 16 bits sample)241 242 return OSS32_CAPS_PCM_FORMAT_ADPCM;//4 bps (compressed 16 bits sample)243 244 return OSS32_CAPS_PCM_FORMAT_MPEG;//AC3?245 246 247 248 208 switch(ALSADataType) 209 { 210 case SNDRV_PCM_FORMAT_S8: 211 return OSS32_CAPS_PCM_FORMAT_S8; //signed 8 bits sample 212 case SNDRV_PCM_FORMAT_U8: 213 return OSS32_CAPS_PCM_FORMAT_U8; //unsigned 8 bits sample 214 case SNDRV_PCM_FORMAT_S16_LE: 215 return OSS32_CAPS_PCM_FORMAT_S16_LE; //signed 16 bits sample (little endian/Intel) 216 case SNDRV_PCM_FORMAT_S16_BE: 217 return OSS32_CAPS_PCM_FORMAT_S16_BE; //signed 16 bits sample (big endian/Motorola) 218 case SNDRV_PCM_FORMAT_U16_LE: 219 return OSS32_CAPS_PCM_FORMAT_U16_LE; //unsigned 16 bits sample (little endian/Intel) 220 case SNDRV_PCM_FORMAT_U16_BE: 221 return OSS32_CAPS_PCM_FORMAT_U16_BE; //unsigned 16 bits sample (big endian/Motorola) 222 case SNDRV_PCM_FORMAT_S24_LE: 223 return OSS32_CAPS_PCM_FORMAT_S24_LE; //signed 24 bits sample (little endian/Intel) 224 case SNDRV_PCM_FORMAT_S24_BE: 225 return OSS32_CAPS_PCM_FORMAT_S24_BE; //signed 24 bits sample (big endian/Motorola) 226 case SNDRV_PCM_FORMAT_U24_LE: 227 return OSS32_CAPS_PCM_FORMAT_U24_LE; //unsigned 24 bits sample (little endian/Intel) 228 case SNDRV_PCM_FORMAT_U24_BE: 229 return OSS32_CAPS_PCM_FORMAT_U24_BE; //unsigned 16 bits sample (big endian/Motorola) 230 case SNDRV_PCM_FORMAT_S32_LE: 231 return OSS32_CAPS_PCM_FORMAT_S32_LE; //signed 32 bits sample (little endian/Intel) 232 case SNDRV_PCM_FORMAT_S32_BE: 233 return OSS32_CAPS_PCM_FORMAT_S32_BE; //signed 32 bits sample (big endian/Motorola) 234 case SNDRV_PCM_FORMAT_U32_LE: 235 return OSS32_CAPS_PCM_FORMAT_U32_LE; //unsigned 32 bits sample (little endian/Intel) 236 case SNDRV_PCM_FORMAT_U32_BE: 237 return OSS32_CAPS_PCM_FORMAT_U32_BE; //unsigned 32 bits sample (big endian/Motorola) 238 case SNDRV_PCM_FORMAT_MU_LAW: 239 return OSS32_CAPS_PCM_FORMAT_MULAW; //8 bps (compressed 16 bits sample) 240 case SNDRV_PCM_FORMAT_A_LAW: 241 return OSS32_CAPS_PCM_FORMAT_ALAW; //8 bps (compressed 16 bits sample) 242 case SNDRV_PCM_FORMAT_IMA_ADPCM: 243 return OSS32_CAPS_PCM_FORMAT_ADPCM; //4 bps (compressed 16 bits sample) 244 case SNDRV_PCM_FORMAT_MPEG: 245 return OSS32_CAPS_PCM_FORMAT_MPEG; //AC3? 246 default: 247 DebugInt3(); 248 return -1; 249 } 249 250 } 250 251 //****************************************************************************** … … 252 253 ULONG ALSAToOSSRateFlags(ULONG fuRates) 253 254 { 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 255 ULONG fuOSSRates = 0; 256 257 char szMixerName[64]; 258 char szDeviceName[128]; 259 OSS32_QueryNames(OSS32_DEFAULT_DEVICE, szDeviceName, 260 sizeof(szDeviceName),szMixerName, 261 sizeof(szMixerName), TRUE); 262 if (strncmp(szDeviceName,"HDA",3) != 0){ 263 /* non-HDA audio - support 5512 - 32000 Hz sample rates */ 264 if(fuRates & SNDRV_PCM_RATE_5512) { 265 fuOSSRates |= OSS32_CAPS_PCM_RATE_5512; 266 } 267 if(fuRates & SNDRV_PCM_RATE_8000) { 268 fuOSSRates |= OSS32_CAPS_PCM_RATE_8000; 269 } 270 if(fuRates & SNDRV_PCM_RATE_11025) { 271 fuOSSRates |= OSS32_CAPS_PCM_RATE_11025; 272 } 273 if(fuRates & SNDRV_PCM_RATE_16000) { 274 fuOSSRates |= OSS32_CAPS_PCM_RATE_16000; 275 } 276 if(fuRates & SNDRV_PCM_RATE_22050) { 277 fuOSSRates |= OSS32_CAPS_PCM_RATE_22050; 278 } 279 if(fuRates & SNDRV_PCM_RATE_32000) { 280 fuOSSRates |= OSS32_CAPS_PCM_RATE_32000; 281 } 282 } else { 283 printk("HDA audio detected - don't support 5512 - 32000 Hz audio sample rates\n"); 284 } 285 if(fuRates & SNDRV_PCM_RATE_44100) { 286 fuOSSRates |= OSS32_CAPS_PCM_RATE_44100; 287 } 288 if(fuRates & SNDRV_PCM_RATE_48000) { 289 fuOSSRates |= OSS32_CAPS_PCM_RATE_48000; 290 } 290 291 #if 0 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 292 if(fuRates & SNDRV_PCM_RATE_64000) { 293 fuOSSRates |= OSS32_CAPS_PCM_RATE_64000; 294 } 295 if(fuRates & SNDRV_PCM_RATE_88200) { 296 fuOSSRates |= OSS32_CAPS_PCM_RATE_88200; 297 } 298 if(fuRates & SNDRV_PCM_RATE_96000) { 299 fuOSSRates |= OSS32_CAPS_PCM_RATE_96000; 300 } 301 if(fuRates & SNDRV_PCM_RATE_176400) { 302 fuOSSRates |= OSS32_CAPS_PCM_RATE_176400; 303 } 304 if(fuRates & SNDRV_PCM_RATE_192000) { 305 fuOSSRates |= OSS32_CAPS_PCM_RATE_192000; 306 } 306 307 #endif 307 308 309 310 311 312 313 314 308 if(fuRates & SNDRV_PCM_RATE_CONTINUOUS) { 309 fuOSSRates |= OSS32_CAPS_PCM_RATE_CONTINUOUS; 310 } 311 312 //TODO: 313 if(fuRates & SNDRV_PCM_RATE_KNOT) { 314 DebugInt3(); 315 } 315 316 //#define OSS32_CAPS_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */ 316 317 317 318 return fuOSSRates; 318 319 } 319 320 //****************************************************************************** … … 321 322 OSSRET OSS32_QueryDevCaps(ULONG deviceid, POSS32_DEVCAPS pDevCaps) 322 323 { 323 OSSSTREAMIDstreamid = 0;324 soundhandle*pHandle;325 struct snd_pcm_info*pcminfo = NULL;326 327 intret, fmt, i;328 ULONGformat_mask;329 struct snd_mask*mask;330 324 OSSSTREAMID streamid = 0; 325 soundhandle *pHandle; 326 struct snd_pcm_info *pcminfo = NULL; 327 struct snd_pcm_hw_params *params; 328 int ret, fmt, i; 329 ULONG format_mask; 330 struct snd_mask *mask; 331 int max_ch; 331 332 332 333 #ifdef DEBUG 333 334 dprintf(("OSS32_QueryDevCaps")); 334 335 #endif 335 // 336 337 338 339 340 341 342 343 344 345 346 347 348 349 // 350 pDevCaps->ulCaps= OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE;351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 pWaveCaps->ulChanFlags= 0;400 401 402 403 404 405 406 407 408 409 410 411 412 413 pWaveCaps->ulMinRate= hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;414 pWaveCaps->ulMaxRate= hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max;415 416 417 418 pWaveCaps->ulRateFlags= mask->bits[0];419 420 pWaveCaps->ulRateFlags= ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 336 // max_ch = GetMaxChannels(deviceid, OSS32_CAPS_WAVE_PLAYBACK); 337 338 //these structures are too big to put on the stack 339 pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL); 340 if(pcminfo == NULL) { 341 DebugInt3(); 342 printk("OSS32_QueryDevCaps: out of memory\n"); 343 return OSSERR_OUT_OF_MEMORY; 344 } 345 params = (struct snd_pcm_hw_params *)(pcminfo+1); 346 347 printk("Number of cards: %i",nrCardsDetected); 348 printk("dev id: %i",deviceid); 349 pDevCaps->nrDevices = 1;//nrCardsDetected; 350 // pDevCaps->nrDevices = nrCardsDetected; 351 pDevCaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE; 352 353 //query wave in & out caps 354 for(i=0;i<2;i++) 355 { 356 PWAVE_CAPS pWaveCaps = (i == 0) ? &pDevCaps->waveOutCaps : &pDevCaps->waveInCaps; 357 358 ret = OSS32_WaveOpen(deviceid, (i == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, 0, 0); 359 if(ret != OSSERR_SUCCESS) 360 { 361 printk("OSS32_QueryDevCaps: wave open error %i\n", ret); 362 DebugInt3(); 363 goto fail; 364 } 365 pHandle = (soundhandle *)streamid; 366 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 367 printk("OSS32_QueryDevCaps: invalid stream id \n"); 368 ret = OSSERR_INVALID_STREAMID; 369 goto fail; 370 } 371 //set operation to non-blocking 372 pHandle->file.f_flags = O_NONBLOCK; 373 374 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo); 375 if(ret != 0) { 376 printk("OSS32_QueryDevCaps: SNDRV_PCM_IOCTL_INFO error %i\n", ret); 377 ret = UNIXToOSSError(ret); 378 goto fail; 379 } 380 if(i == 0) {//only need to do this once 381 if(pcminfo->name[0]) { 382 strncpy(pDevCaps->szDeviceName, pcminfo->name, sizeof(pDevCaps->szDeviceName)); 383 } 384 else strncpy(pDevCaps->szDeviceName, pcminfo->id, sizeof(pDevCaps->szDeviceName)); 385 } 386 printk("Device name: %s", pDevCaps->szDeviceName); 387 pWaveCaps->nrStreams = pcminfo->subdevices_count; 388 389 //get all hardware parameters 390 _snd_pcm_hw_params_any(params); 391 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params); 392 if(ret != 0) { 393 printk("OSS32_QueryDevCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i\n", ret); 394 ret = UNIXToOSSError(ret); 395 goto fail; 396 } 397 398 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min; 399 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max; 400 pWaveCaps->ulChanFlags = 0; 401 if(pWaveCaps->ulMinChannels == 1) { 402 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO; 403 } 404 if(pWaveCaps->ulMaxChannels >= 2) { 405 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO; 406 } 407 if(pWaveCaps->ulMaxChannels >= 4) { 408 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD; 409 } 410 if(pWaveCaps->ulMaxChannels >= 6) { 411 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1; 412 } 413 414 pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min; 415 pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max; 416 417 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK); 418 419 pWaveCaps->ulRateFlags = mask->bits[0]; 420 421 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags); 422 423 pWaveCaps->ulDataFormats = 0; 424 425 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 426 format_mask = mask->bits[0]; 427 for(fmt=0;fmt<32;fmt++) 428 { 429 if(format_mask & (1 << fmt)) 430 { 431 int f = ALSAToOSSDataType(fmt); 432 if (f >= 0) 433 pWaveCaps->ulDataFormats |= f; 434 } 435 } 436 437 OSS32_WaveClose(streamid); 438 streamid = 0; 439 440 } 441 442 //Check support for MPU401, FM & Wavetable MIDI 443 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_MPU401_MIDIOUT, &streamid) == OSSERR_SUCCESS) 444 { 445 pDevCaps->ulCaps |= OSS32_CAPS_MPU401_PLAYBACK; 446 OSS32_MidiClose(streamid); 447 streamid = 0; 448 } 449 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_MPU401_MIDIIN, &streamid) == OSSERR_SUCCESS) 450 { 451 pDevCaps->ulCaps |= OSS32_CAPS_MPU401_CAPTURE; 452 OSS32_MidiClose(streamid); 453 streamid = 0; 454 } 455 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_FM_MIDIOUT, &streamid) == OSSERR_SUCCESS) 456 { 457 pDevCaps->ulCaps |= OSS32_CAPS_FMSYNTH_PLAYBACK; 458 OSS32_MidiClose(streamid); 459 streamid = 0; 460 } 461 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_WAVETABLE_MIDIOUT, &streamid) == OSSERR_SUCCESS) 462 { 463 pDevCaps->ulCaps |= OSS32_CAPS_WAVETABLE_PLAYBACK; 464 OSS32_MidiClose(streamid); 465 streamid = 0; 466 } 467 468 if(OSS32_MixQueryName(deviceid, &pDevCaps->szMixerName, sizeof(pDevCaps->szMixerName)) != OSSERR_SUCCESS) { 469 DebugInt3(); 470 printk("OSS32_QueryDevCaps: OSS32_MixQueryName error\n"); 471 goto fail; 472 } 473 printk("OSS32_QueryDevCaps: devname: [%s]\n", pDevCaps->szDeviceName); 474 kfree(pcminfo); 475 streamid = 0; 476 477 478 return OSSERR_SUCCESS; 478 479 479 480 fail: 480 481 482 483 484 485 481 printk("OSS32_QueryDevCaps failed\n"); 482 DebugInt3(); 483 if(streamid) OSS32_WaveClose(streamid); 484 if(pcminfo) kfree(pcminfo); 485 486 return ret; 486 487 } 487 488 //****************************************************************************** … … 489 490 OSSRET OSS32_WaveOpen(ULONG deviceid, ULONG streamtype, OSSSTREAMID *pStreamId, int pcm, USHORT fileid) 490 491 { 491 492 intret,i;493 494 495 496 497 498 499 500 501 502 503 492 soundhandle *pHandle; 493 int ret,i; 494 495 if (pStreamId) 496 *pStreamId = 0; 497 else 498 { 499 printk("ERROR: invalid stream id pointer passed\n"); 500 return OSSERR_OUT_OF_MEMORY; 501 } 502 503 if(alsa_fops == NULL) { 504 DebugInt3(); 504 505 #ifdef DEBUG 505 506 dprintf(("OSS32_WaveOpen: no devices")); 506 507 #endif 507 508 509 510 511 512 // 513 514 515 516 517 518 519 520 521 522 523 524 525 526 pHandle->file.f_dentry= &pHandle->d_entry;527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 508 printk("OSS32_WaveOpen: no devices\n"); 509 510 return OSSERR_NO_DEVICE_AVAILABLE; 511 } 512 513 // printk("dev id: %i\n",deviceid); 514 515 pHandle = kmalloc(sizeof(soundhandle), GFP_KERNEL); 516 if(pHandle == NULL) { 517 DebugInt3(); 518 printk("OSS32_WaveOpen: out of memory\n"); 519 return OSSERR_OUT_OF_MEMORY; 520 } 521 memset(pHandle, 0, sizeof(soundhandle)); 522 523 //set operation to non-blocking 524 pHandle->file.f_flags = O_NONBLOCK; 525 526 //setup pointers in file structure (used internally by ALSA) 527 pHandle->file.f_dentry = &pHandle->d_entry; 528 pHandle->file.f_dentry->d_inode = &pHandle->inode; 529 530 switch(streamtype) { 531 case OSS32_STREAM_WAVEOUT: 532 pHandle->file.f_mode = FMODE_WRITE; 533 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_PCM_PLAYBACK) + pcm; 534 break; 535 case OSS32_STREAM_WAVEIN: 536 pHandle->file.f_mode = FMODE_READ; 537 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_PCM_CAPTURE) + pcm; 538 break; 539 default: 540 DebugInt3(); 541 kfree(pHandle); 542 printk("OSS32_WaveOpen: invalid parameter\n"); 543 return OSSERR_INVALID_PARAMETER; 544 } 545 546 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 547 printk("OSS32_WaveOpen. ret: %i\n", ret); 548 /* check if PCM already opened (stupid uniaud16.sys doesnt closes it) */ 549 if (ret == -16) 550 { 551 for (i=0; i < 8*256; i++) 552 { 553 if (opened_handles[i].handle != 0) 554 { 555 ret = 0; 556 if (pStreamId) 557 *pStreamId = (ULONG)opened_handles[i].handle; 558 opened_handles[i].reuse = 1; /* try to reuse */ 559 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0) 560 { 561 if (!opened_handles[i].reuse) 562 { 563 //opened_handles[i].handle = 0; 564 kfree(opened_handles[i].handle); //free handle data 565 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 566 printk("OSS32_WaveOpen. Reopen ret: %i\n", ret); 567 } 568 else 569 { 570 kfree(pHandle); 571 pHandle = opened_handles[i].handle; 572 } 573 break; 574 } 575 } 576 } 577 } 578 else if (ret == 0) 579 { 580 for (i=0; i < 8*256; i++) 581 { 582 if (opened_handles[i].handle == 0) 583 { 584 opened_handles[i].handle = pHandle; 585 opened_handles[i].FileId = fileid; 586 break; 587 } 588 } 589 } 590 591 if(ret) { 592 kfree(pHandle); 593 DebugInt3(); 594 printk("OSS32_WaveOpen: open error: %i\n",ret); 595 return UNIXToOSSError(ret); 596 } 597 pHandle->magic = MAGIC_WAVE_ALSA32; 598 if (pStreamId) 599 *pStreamId = (ULONG)pHandle; 600 // filling opened handles table 601 printk("OSS32_WaveOpen. streamid %X\n",(ULONG)pHandle); 602 return OSSERR_SUCCESS; 602 603 } 603 604 //****************************************************************************** … … 606 607 OSSRET OSS32_WaveClose(OSSSTREAMID streamid) 607 608 { 608 609 intret = 0, i;610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 // 646 647 648 649 650 651 652 653 654 655 609 soundhandle *pHandle = (soundhandle *)streamid; 610 int ret = 0, i; 611 612 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 613 DebugInt3(); 614 printk("OSS32_WaveClose. invalid streamid %X\n",(ULONG)pHandle); 615 return OSSERR_INVALID_STREAMID; 616 } 617 618 //set operation to non-blocking 619 pHandle->file.f_flags = O_NONBLOCK; 620 621 for (i=0; i < 8*256; i++) 622 { 623 if (opened_handles[i].handle == pHandle) 624 { 625 printk("Found phandle for closing: %x reuse flag: %i\n", pHandle, opened_handles[i].reuse); 626 if (!opened_handles[i].reuse) 627 { 628 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 629 opened_handles[i].handle = 0; 630 kfree(pHandle); //free handle data 631 OSS32_CloseUNI16(); /* say to UNIAUD16 that we closing now */ 632 } else 633 { 634 /* prepare for reuse */ 635 pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_RESET, 0); 636 pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 637 } 638 break; 639 } 640 } 641 642 if (i >= 8*256) 643 { 644 //all already closed 645 printk("phandle %x not found\n", pHandle); 646 // return OSSERR_SUCCESS; 647 } 648 649 650 if(ret) { 651 printk("Error closing wave. rc = %i\n", ret); 652 DebugInt3(); 653 return UNIXToOSSError(ret); 654 } 655 printk("OSS32_WaveClose. streamid %X\n",(ULONG)pHandle); 656 return OSSERR_SUCCESS; 656 657 } 657 658 //****************************************************************************** … … 659 660 OSSRET OSS32_WavePrepare(OSSSTREAMID streamid) 660 661 { 661 662 intret;662 soundhandle *pHandle = (soundhandle *)streamid; 663 int ret; 663 664 664 665 #ifdef DEBUG 665 666 dprintf(("OSS32_WavePrepare")); 666 667 #endif 667 668 668 669 669 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 670 DebugInt3(); 670 671 //#ifdef DEBUG 671 672 printk("vladest: OSS32_WavePrepare: invalid streamID\n"); 672 673 //#endif 673 674 674 675 676 677 678 679 680 681 682 683 675 return OSSERR_INVALID_STREAMID; 676 } 677 //set operation to non-blocking 678 pHandle->file.f_flags = O_NONBLOCK; 679 680 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 681 if (ret) 682 printk("Wave prepare ret = %i, streamid %X\n",ret,(ULONG)pHandle); 683 684 return UNIXToOSSError(ret);; 684 685 } 685 686 //****************************************************************************** … … 687 688 OSSRET OSS32_WaveStart(OSSSTREAMID streamid) 688 689 { 689 690 intret;691 692 693 694 695 696 697 698 699 700 701 702 690 soundhandle *pHandle = (soundhandle *)streamid; 691 int ret; 692 693 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 694 DebugInt3(); 695 return OSSERR_INVALID_STREAMID; 696 } 697 //set operation to non-blocking 698 pHandle->file.f_flags = O_NONBLOCK; 699 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0); 700 if (ret) 701 printk("Wave start ret = %i, streamid %X\n",ret,(ULONG)pHandle); 702 703 return UNIXToOSSError(ret);; 703 704 } 704 705 //****************************************************************************** … … 706 707 OSSRET OSS32_WaveStop(OSSSTREAMID streamid) 707 708 { 708 709 intret;710 711 712 713 714 715 716 717 718 719 720 721 722 709 soundhandle *pHandle = (soundhandle *)streamid; 710 int ret; 711 712 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 713 DebugInt3(); 714 return OSSERR_INVALID_STREAMID; 715 } 716 //set operation to non-blocking 717 pHandle->file.f_flags = O_NONBLOCK; 718 719 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0); 720 if (ret) 721 printk("Wave stop ret = %i. streamid %X\n",ret,(ULONG)pHandle); 722 723 return UNIXToOSSError(ret);; 723 724 } 724 725 //****************************************************************************** … … 726 727 OSSRET OSS32_WavePause(OSSSTREAMID streamid) 727 728 { 728 729 intret;730 731 732 733 734 735 736 737 738 739 740 741 742 729 soundhandle *pHandle = (soundhandle *)streamid; 730 int ret; 731 732 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 733 DebugInt3(); 734 return OSSERR_INVALID_STREAMID; 735 } 736 //set operation to non-blocking 737 pHandle->file.f_flags = O_NONBLOCK; 738 739 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, 0); 740 if (ret) 741 printk("Wave pause ret = %i, streamid %X\n",ret,(ULONG)pHandle); 742 743 return UNIXToOSSError(ret);; 743 744 } 744 745 //****************************************************************************** … … 746 747 OSSRET OSS32_WaveResume(OSSSTREAMID streamid) 747 748 { 748 749 intret;750 751 752 753 754 755 756 757 758 759 760 761 762 749 soundhandle *pHandle = (soundhandle *)streamid; 750 int ret; 751 752 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 753 DebugInt3(); 754 return OSSERR_INVALID_STREAMID; 755 } 756 //set operation to non-blocking 757 pHandle->file.f_flags = O_NONBLOCK; 758 759 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, 1); 760 if (ret) 761 printk("Wave resume ret = %i, streamid %X\n",ret,(ULONG)pHandle); 762 763 return UNIXToOSSError(ret);; 763 764 } 764 765 765 766 static unsigned rates[] = { 766 767 768 767 /* ATTENTION: these values depend on the definition in pcm.h! */ 768 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 769 64000, 88200, 96000, 176400, 192000 769 770 }; 770 771 … … 773 774 OSSRET OSS32_WaveSetHwParams(OSSSTREAMID streamid, OSS32_HWPARAMS *pHwParams) 774 775 { 775 soundhandle*pHandle = (soundhandle *)streamid;776 777 778 struct snd_pcm_statusstatus;779 780 intret, nrperiods, minnrperiods, maxnrperiods, samplesize,i;781 ULONGbufsize, periodsize, minperiodsize, maxperiodsize;782 ULONGperiodbytes, minperiodbytes, maxperiodbytes;783 BOOLfTryAgain = FALSE;784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 776 soundhandle *pHandle = (soundhandle *)streamid; 777 struct snd_pcm_hw_params params; 778 struct snd_pcm_sw_params swparams; 779 struct snd_pcm_status status; 780 781 int ret, nrperiods, minnrperiods, maxnrperiods, samplesize,i; 782 ULONG bufsize, periodsize, minperiodsize, maxperiodsize; 783 ULONG periodbytes, minperiodbytes, maxperiodbytes; 784 BOOL fTryAgain = FALSE; 785 ULONG ulMinRate, ulMaxRate; 786 787 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 788 789 DebugInt3(); 790 return OSSERR_INVALID_STREAMID; 791 } 792 if(pHwParams == NULL) { 793 794 DebugInt3(); 795 return OSSERR_INVALID_PARAMETER; 796 } 797 if(pHwParams->ulDataType >= OSS32_PCM_MAX_FORMATS) { 798 799 DebugInt3(); 800 return OSSERR_INVALID_PARAMETER; 801 } 802 if ((int)pHwParams->ulNumChannels <= 0) { 803 printk("OSS32_WaveSetHwParams error. Invalid number of channels: %i\n", pHwParams->ulNumChannels); 804 DebugInt3(); 805 return OSSERR_INVALID_PARAMETER; 806 } 806 807 tryagain: 807 808 809 810 811 812 813 814 815 periodsize= bytes_to_samples(periodbytes);816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 //printk("will set to nearest\n");880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 808 //set operation to non-blocking 809 pHandle->file.f_flags = O_NONBLOCK; 810 811 //size of two samples (adpcm sample can be as small as 4 bits (mono), so take two) 812 samplesize = snd_pcm_format_size(OSSToALSADataType[pHwParams->ulDataType], 1); 813 pHandle->doublesamplesize = samplesize * 2; 814 pHandle->doublesamplesize *= pHwParams->ulNumChannels; 815 periodbytes = pHwParams->ulPeriodSize; 816 periodsize = bytes_to_samples(periodbytes); 817 // checking number of channels 818 819 dprintf(("channels: %ld, period size: %lx",pHwParams->ulNumChannels, periodbytes)); 820 821 _snd_pcm_hw_params_any(¶ms); 822 do { 823 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_ACCESS, 824 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0); 825 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS, 826 pHwParams->ulNumChannels, 0); 827 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 828 if (ret == 0) break; 829 pHwParams->ulNumChannels--; 830 } while(ret < 0 && pHwParams->ulNumChannels > 1); 831 832 dprintf(("channels selected: %d",pHwParams->ulNumChannels)); 833 834 //get all hardware parameters 835 _snd_pcm_hw_params_any(¶ms); 836 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_ACCESS, 837 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0); 838 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT, 839 OSSToALSADataType[pHwParams->ulDataType], 0); 840 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 841 if(ret != 0) { 842 dprintf(("invalid format %lx\n", OSSToALSADataType[pHwParams->ulDataType])); 843 return UNIXToOSSError(ret); 844 } 845 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 846 pHwParams->ulBitsPerSample, 0); 847 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 848 if(ret != 0) { 849 dprintf(("invalid number of sample bits %d\n", pHwParams->ulBitsPerSample)); 850 return UNIXToOSSError(ret); 851 } 852 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS, 853 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0); 854 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 855 if(ret != 0) { 856 dprintf(("invalid number of frame bits %d\n", pHwParams->ulBitsPerSample*pHwParams->ulNumChannels)); 857 return UNIXToOSSError(ret); 858 } 859 860 //_snd_pcm_hw_params_any(¶ms); 861 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 862 pHwParams->ulBitsPerSample, 0); 863 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS, 864 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0); 865 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT, 866 OSSToALSADataType[pHwParams->ulDataType], 0); 867 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS, 868 pHwParams->ulNumChannels, 0); 869 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE, 870 pHwParams->ulSampleRate, 0); 871 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 872 if(ret != 0) { 873 dprintf(("32_WSetHwPms (first pass) error %d bps:%d fmt: %d ch: %d sr: %d\n", 874 ret, 875 pHwParams->ulBitsPerSample, 876 OSSToALSADataType[pHwParams->ulDataType], 877 pHwParams->ulNumChannels, 878 pHwParams->ulSampleRate)); 879 //printk("OSS32_WaveSetHwParams invalid sample rate %i\n", pHwParams->ulSampleRate); 880 // printk("will set to nearest\n"); 881 _snd_pcm_hw_params_any(¶ms); 882 for (i=0; i<(sizeof(rates)/sizeof(unsigned))-1;i++) 883 { 884 if (pHwParams->ulSampleRate >= rates[i] && 885 pHwParams->ulSampleRate <= rates[i+1]) 886 { 887 pHwParams->ulSampleRate = rates[i]; 888 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE, 889 pHwParams->ulSampleRate, 0); 890 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 891 if(ret == 0) 892 { 893 _snd_pcm_hw_params_any(¶ms); 894 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 895 pHwParams->ulBitsPerSample, 0); 896 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS, 897 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0); 898 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT, 899 OSSToALSADataType[pHwParams->ulDataType], 0); 900 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS, 901 pHwParams->ulNumChannels, 0); 902 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE, 903 pHwParams->ulSampleRate, 0); 904 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms)); 905 goto __next; 906 } 907 } 908 } 909 DebugInt3(); 910 return UNIXToOSSError(ret); 911 } 911 912 __next: 912 913 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 periodsize= maxperiodsize;1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 swparams.avail_min= periodsize;1033 swparams.period_step= 1;1034 1035 1036 1037 1038 1039 1040 1041 swparams.sleep_min= 0;1042 1043 1044 swparams.tstamp_mode= SNDRV_PCM_TSTAMP_NONE;1045 swparams.xfer_align= periodsize;1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 914 //check period size against lower and upper boundaries 915 minperiodbytes = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->min; 916 maxperiodbytes = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->max; 917 if(periodbytes < minperiodbytes) { 918 periodbytes = minperiodbytes; 919 } 920 else 921 if(periodbytes > maxperiodbytes) { 922 periodbytes = maxperiodbytes; 923 } 924 925 minperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min; 926 maxperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->max; 927 if(periodsize < minperiodsize) { 928 periodsize = minperiodsize; 929 } 930 else 931 if(periodsize > maxperiodsize) { 932 periodsize = maxperiodsize; 933 } 934 935 if(samples_to_bytes(periodsize) < periodbytes) { 936 periodbytes = samples_to_bytes(periodsize); 937 } 938 else 939 if(bytes_to_samples(periodbytes) < periodsize) { 940 periodsize = bytes_to_samples(periodbytes); 941 } 942 943 //make sure period size is a whole fraction of the buffer size 944 bufsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->max; 945 if(periodsize) { 946 nrperiods = bufsize/periodbytes; 947 } 948 else { 949 dprintf(("32_WSHwPrms error. Invalid periodsize (=0). closing file\n")); 950 DebugInt3(); 951 return OSSERR_INVALID_PARAMETER; 952 } 953 //check nr of periods against lower and upper boundaries 954 minnrperiods = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIODS)->min; 955 maxnrperiods = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIODS)->max; 956 if(nrperiods < minnrperiods) { 957 nrperiods = minnrperiods; 958 } 959 else 960 if(nrperiods > maxnrperiods) { 961 nrperiods = maxnrperiods; 962 } 963 //an odd nr of periods is not always a good thing (CMedia -> clicks during 8 bps playback), 964 //so we make sure it's an even number. 965 if(nrperiods == 1) { 966 dprintf(("32_WSHwPrms error. Invalid Num periods(=1). closing file\n")); 967 DebugInt3(); 968 return OSSERR_INVALID_PARAMETER; 969 } 970 nrperiods &= ~1; 971 972 //initialize parameter block & set sample rate, nr of channels and sample format, nr of periods, 973 //period size and buffer size 974 975 _snd_pcm_hw_params_any(¶ms); 976 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_ACCESS, 977 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0); 978 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 979 pHwParams->ulBitsPerSample, 0); 980 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS, 981 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0); 982 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT, 983 OSSToALSADataType[pHwParams->ulDataType], 0); 984 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS, 985 pHwParams->ulNumChannels, 0); 986 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE, 987 pHwParams->ulSampleRate, 0); 988 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 989 periodsize, 0); 990 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 991 periodbytes, 0); 992 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIODS, 993 nrperiods, 0); 994 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 995 periodsize*nrperiods, 0); 996 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 997 periodbytes*nrperiods, 0); 998 999 1000 dprintf(("HWP: SR rate %ld, BPS %ld, CH %ld, PRSZ %lx, periods %lx", 1001 pHwParams->ulSampleRate, pHwParams->ulBitsPerSample, pHwParams->ulNumChannels, periodsize, nrperiods)); 1002 1003 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)__Stack32ToFlat(¶ms)); 1004 if (ret == -77 && fTryAgain == FALSE) 1005 { 1006 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1007 fTryAgain = TRUE; 1008 dprintf((" Error -77 from first IOCTL HW Parms")); 1009 goto tryagain; 1010 } 1011 1012 if(ret) { 1013 if(fTryAgain == FALSE) { 1014 minperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min; 1015 maxperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->max; 1016 dprintf(("Period size min=%lx max=%lx", minperiodsize, maxperiodsize)); 1017 if(minperiodsize > maxperiodsize) { 1018 //ALSA doesn't like the period size; try suggested one 1019 periodsize = maxperiodsize; 1020 periodbytes = samples_to_bytes(periodsize); 1021 dprintf((" Peroid size error IOCTL HW Parms")); 1022 fTryAgain = TRUE; 1023 goto tryagain; 1024 } 1025 } 1026 dprintf(("Error %ld second time.. Bailing", ret)); 1027 return UNIXToOSSError(ret); 1028 } 1029 1030 //set silence threshold (all sizes in frames) (only needed for playback) 1031 if(pHandle->file.f_mode == FMODE_WRITE) 1032 { 1033 swparams.avail_min = periodsize; 1034 swparams.period_step = 1; 1035 if(nrperiods <= 2) { 1036 swparams.silence_size = (periodsize/2); 1037 } 1038 else { 1039 swparams.silence_size = periodsize; 1040 } 1041 swparams.silence_threshold = swparams.silence_size; 1042 swparams.sleep_min = 0; 1043 swparams.start_threshold = 1; 1044 swparams.stop_threshold = periodsize*nrperiods; 1045 swparams.tstamp_mode = SNDRV_PCM_TSTAMP_NONE; 1046 swparams.xfer_align = periodsize; 1047 1048 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)__Stack32ToFlat(&swparams)); 1049 } 1050 1051 total = 0; 1052 per_bytes = periodbytes; 1053 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1054 if ( ((status.state != SNDRV_PCM_STATE_PREPARED) && 1055 (status.state != SNDRV_PCM_STATE_SETUP) && 1056 (status.state != SNDRV_PCM_STATE_RUNNING) && 1057 (status.state != SNDRV_PCM_STATE_DRAINING))) { 1058 dprintf(("Device is not in proper state: %lx. Calling prepare\n", status.state)); 1059 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1060 } 1061 return UNIXToOSSError(ret); 1061 1062 } 1062 1063 … … 1065 1066 ULONG CountWv=0; 1066 1067 ULONG LockAdd=0; 1067 extern 1068 extern ULONG xchg( ULONG *p, ULONG x); 1068 1069 #pragma aux xchg = "xchg [esi],eax" parm [ESI][EAX] value [EAX]; 1069 1070 //****************************************************************************** 1070 OSSRET OSS32_WaveAddBuffer(OSSSTREAMID streamid, ULONG buffer, ULONG size, ULONG *pTransferred, int pcm)1071 { 1072 soundhandle*pHandle = (soundhandle *)streamid;1073 struct snd_pcm_statusstatus;1074 int ret, align, size1, ret1;1075 LONG transferred;1076 ULONG position,i,j;1077 char*buf;1078 1079 // 1080 1081 1082 1083 1084 1085 if(pTransferred == NULL || buffer == 0 || size == 0) {1086 1087 1088 1089 1090 1091 1071 OSSRET OSS32_WaveAddBuffer(OSSSTREAMID streamid, ULONG ulBuffer, ULONG ulReqSize, ULONG *pulTransferred, int pcm) 1072 { 1073 soundhandle *pHandle = (soundhandle *)streamid; 1074 struct snd_pcm_status status; 1075 int iRet, align, iRet1; 1076 LONG ulTransferred; 1077 ULONG ulPosition, ulI, ulJ, ulSize; 1078 char *buf; 1079 1080 // return OSSERR_SUCCESS; 1081 1082 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 1083 DebugInt3(); 1084 return OSSERR_INVALID_STREAMID; 1085 } 1086 if(pulTransferred == NULL || ulBuffer == 0 || ulReqSize == 0) { 1087 DebugInt3(); 1088 return OSSERR_INVALID_PARAMETER; 1089 } 1090 1091 //set operation to non-blocking 1092 pHandle->file.f_flags = O_NONBLOCK; 1092 1093 1093 1094 /* get the status of the circular dma buffer */ 1094 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1095 1096 if( ret) {1097 DebugInt3(); 1098 return UNIXToOSSError( ret);1095 iRet = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1096 1097 if(iRet) { 1098 DebugInt3(); 1099 return UNIXToOSSError(iRet); 1099 1100 } 1100 1101 1101 1102 CountWv++; 1102 transferred = 0;1103 *pTransferred = 0;1104 ret = -11; 1105 switch(SNDRV_MINOR_DEVICE(MINOR(pHandle->inode.i_rdev-pcm))) 1106 { 1107 case SNDRV_MINOR_PCM_PLAYBACK: 1108 1103 ulTransferred = 0; 1104 *pulTransferred = 0; 1105 switch(SNDRV_MINOR_DEVICE(MINOR(pHandle->inode.i_rdev-pcm))) 1106 { 1107 case SNDRV_MINOR_PCM_PLAYBACK: 1108 1109 #if 1 1109 1110 //first check how much room is left in the circular dma buffer 1110 1111 //this is done to make sure we don't block inside ALSA while trying to write 1111 1112 //more data than fits in the internal dma buffer. 1112 size1 = size; 1113 size = min(size, samples_to_bytes(status.avail)); 1114 1115 #ifdef DEBUG 1113 ulSize = min(ulReqSize, samples_to_bytes(status.avail)); 1114 1115 if (ulSize == 0) { 1116 rprintf(("OSS32_WaveAddBuffer: no room left in hardware buffer!!\n")); 1117 rprintf(("state=%x avail=%x ReqSize=%x\n", status.state, status.avail, ulReqSize)); 1118 *pulTransferred = 0; 1119 return OSSERR_BUFFER_FULL; 1120 } 1121 1122 if (status.state == SNDRV_PCM_STATE_XRUN) { 1123 rprintf(("Internal Error: Xrun\n")); 1124 } 1125 1126 iRet = pHandle->file.f_op->write(&pHandle->file, (char *)ulBuffer, ulReqSize, &pHandle->file.f_pos); 1127 1128 if (iRet < 0 ) break; 1129 ulTransferred = iRet; 1130 #else 1131 //first check how much room is left in the circular dma buffer 1132 //this is done to make sure we don't block inside ALSA while trying to write 1133 //more data than fits in the internal dma buffer. 1134 ulSize = ulReqSize; 1135 ulReqSize = min(ulReqSize, samples_to_bytes(status.avail)); 1136 1116 1137 //printk("OSS32_WaveAddBuffer N:%d hw=%x app=%x avail=%x req size=%x size=%x\n", 1117 // CountWv, samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), size1, size); 1118 #endif 1119 1120 if (size == 0) { 1121 #ifdef DEBUG_PK 1122 printk("OSS32_WaveAddBuffer: no room left in hardware buffer!!\n"); 1123 printk("state = %i\n",status.state); 1124 printk("avail = %i\n",status.avail); 1125 printk("size req = %i\n",size1); 1126 #endif 1127 *pTransferred = 0; 1128 return OSSERR_BUFFER_FULL; 1129 } 1138 // CountWv, samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), ulSize, ulReqSize); 1139 1140 if (ulReqSize == 0) { 1141 rprintf(("OSS32_WaveAddBuffer: no room left in hardware buffer!!\n")); 1142 rprintf(("state=%x avail=%x SizeReq=%x\n", status.state, status.avail, ulSize)); 1143 *pulTransferred = 0; 1144 return OSSERR_BUFFER_FULL; 1145 } 1130 1146 1131 1147 // size should be aligned to channels number * samplesize //PS+++ what is it and why?!?!?! 1132 j = 10; // 10 try if error 1133 while (size && j && ret) 1148 ulJ = 10; // 10 try if error 1149 iRet = -11; 1150 while (ulReqSize && ulJ && iRet) 1134 1151 { 1135 1152 for (i=0; i < 1000; i++) 1136 1153 { 1137 ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1154 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1138 1155 // If here any state and have free buffer to any byte 1139 1156 if ((status.state != SNDRV_PCM_STATE_XRUN ) && samples_to_bytes(status.avail) ) break; 1157 if (status.state == SNDRV_PCM_STATE_XRUN) { 1158 rprintf(("Internal Error: Xrun\n")); 1159 } 1140 1160 if (i > 998) { 1141 1161 // printk("timeout stat %x avail:%d hw:%d app:%d\n",status.state,samples_to_bytes(status.avail),samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr)); 1142 ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);1162 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1143 1163 } 1144 1164 } 1145 1165 1146 if ( ret1 < 0) {1147 // printk("Status Error ret1:%i trans: %i need %d tot:%d\n",ret1,transferred, size,size1);1148 break; 1166 if (iRet1 < 0) { 1167 // printk("Status Error iRet1:%i trans: %i need %d tot:%d\n",iRet1,ulTransferred, ulReqSize,ulSize); 1168 break; // We have any global error, don't try more 1149 1169 } 1150 1170 1151 ret = pHandle->file.f_op->write(&pHandle->file, (char *)buffer, size, &pHandle->file.f_pos);1152 1153 if ( ret < 0 ) { // We have any error, don't try more1154 j--;1155 if ( ret != -11 )1156 ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);1157 // printk("Error ret:%i ret1:%i trans: %d need %d tot:%d\n", ret,ret1,transferred, size,size1);1171 iRet = pHandle->file.f_op->write(&pHandle->file, (char *)ulBuffer, ulReqSize, &pHandle->file.f_pos); 1172 1173 if (iRet < 0 ) { // We have any error, don't try more 1174 ulJ--; 1175 if ( iRet != -11 ) 1176 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1177 // printk("Error ret:%i ret1:%i trans: %d need %d tot:%d\n",iRet,iRet1,ulTransferred, ulReqSize,ulSize); 1158 1178 continue; 1159 1179 } 1160 if ( ret == 0) continue;1161 transferred += ret;1162 // printk("written: now: %d, trans: %d need %d tot:%d\n", ret, transferred, size,size1);1163 buffer += ret;1164 if ( size > ret)1165 size -= ret;1180 if (iRet == 0) continue; 1181 ulTransferred += iRet; 1182 // printk("written: now: %d, trans: %d need %d tot:%d\n", iRet, ulTransferred, ulReqSize,ulSize); 1183 ulBuffer += iRet; 1184 if (ulReqSize > iRet) 1185 ulReqSize -= iRet; 1166 1186 else 1167 size = 0;1168 } 1169 break; 1170 case SNDRV_MINOR_PCM_CAPTURE: 1171 #ifdef DEBUG 1187 ulReqSize = 0; 1188 } 1189 #endif 1190 break; 1191 case SNDRV_MINOR_PCM_CAPTURE: 1172 1192 //printk("OSS32_WaveAddBuffer N:%d state=%x hw=%x app=%x avail=%x size=%x\n", 1173 // CountWv, status.state, samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), size); 1174 #endif 1193 // CountWv, status.state, samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr), samples_to_bytes(status.avail), ulReqSize); 1175 1194 // Need to handle overrun condition when reading 1176 1195 // if (status.state == SNDRV_PCM_STATE_XRUN) { 1177 // *pTransferred = 0;1196 // *pulTransferred = 0; 1178 1197 // return OSSERR_BUFFER_FULL; 1179 1198 // } 1180 transferred = pHandle->file.f_op->read(&pHandle->file, (char *)buffer, size, &pHandle->file.f_pos);1181 if ( transferred< 0) {1182 *pTransferred = 0;1199 iRet = pHandle->file.f_op->read(&pHandle->file, (char *)ulBuffer, ulReqSize, &pHandle->file.f_pos); 1200 if (iRet < 0) { 1201 *pulTransferred = 0; 1183 1202 return OSSERR_BUFFER_FULL; 1184 1203 } 1185 break; 1186 default: 1187 DebugInt3(); 1188 return OSSERR_INVALID_PARAMETER; 1189 } 1190 1191 total += transferred; 1192 *pTransferred = transferred; 1193 prev_size = transferred; 1194 // if (*pTransferred < size1) 1195 // { 1196 // printk("warning: transferred [%d] less than requested [%d]\n", *pTransferred, size1); 1197 // ret1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1198 // } 1199 1200 return OSSERR_SUCCESS; 1204 ulTransferred = iRet; 1205 break; 1206 default: 1207 DebugInt3(); 1208 return OSSERR_INVALID_PARAMETER; 1209 } 1210 1211 total += ulTransferred; 1212 *pulTransferred = ulTransferred; 1213 prev_size = ulTransferred; 1214 // if (*pulTransferred < ulSize) 1215 // { 1216 // printk("warning: ulTransferred [%d] less than requested [%d]\n", *pulTransferred, ulSize); 1217 // iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1218 // } 1219 1220 return OSSERR_SUCCESS; 1201 1221 } 1202 1222 //****************************************************************************** … … 1204 1224 OSSRET OSS32_WaveGetPosition(ULONG streamid, ULONG *pPosition) 1205 1225 { 1206 soundhandle*pHandle = (soundhandle *)streamid;1207 struct snd_pcm_statusstatus;1208 intret;1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1226 soundhandle *pHandle = (soundhandle *)streamid; 1227 struct snd_pcm_status status; 1228 int ret; 1229 1230 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 1231 DebugInt3(); 1232 return OSSERR_INVALID_STREAMID; 1233 } 1234 if(pPosition == NULL) { 1235 DebugInt3(); 1236 return OSSERR_INVALID_PARAMETER; 1237 } 1238 1239 //set operation to non-blocking 1240 pHandle->file.f_flags = O_NONBLOCK; 1241 1242 //Get the status of the stream 1243 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1244 1245 if(ret) { 1246 DebugInt3(); 1247 return UNIXToOSSError(ret); 1248 } 1249 1250 dprintf2(("OSS32_WaveGetPosition: hardware %x application %x", samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr))); 1251 *pPosition = samples_to_bytes(status.hw_ptr); //return new hardware position 1252 return OSSERR_SUCCESS; 1233 1253 } 1234 1254 //****************************************************************************** … … 1236 1256 OSSRET OSS32_WaveGetSpace(ULONG streamid, ULONG *pBytesAvail) 1237 1257 { 1238 soundhandle*pHandle = (soundhandle *)streamid;1239 struct snd_pcm_statusstatus;1240 intret;1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1258 soundhandle *pHandle = (soundhandle *)streamid; 1259 struct snd_pcm_status status; 1260 int ret; 1261 1262 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 1263 DebugInt3(); 1264 return OSSERR_INVALID_STREAMID; 1265 } 1266 if(pBytesAvail == NULL) { 1267 DebugInt3(); 1268 return OSSERR_INVALID_PARAMETER; 1269 } 1270 1271 //set operation to non-blocking 1272 pHandle->file.f_flags = O_NONBLOCK; 1273 1274 //Get the nr of bytes left in the audio buffer 1275 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1276 1277 if(ret) { 1278 DebugInt3(); 1279 return UNIXToOSSError(ret); 1280 } 1281 ret = samples_to_bytes(status.avail); 1282 1283 *pBytesAvail = ret; 1284 return OSSERR_SUCCESS; 1265 1285 } 1266 1286 //****************************************************************************** … … 1268 1288 OSSRET OSS32_WaveGetHwPtr(ULONG streamid, ULONG *pPosition) 1269 1289 { 1270 soundhandle*pHandle = (soundhandle *)streamid;1271 struct snd_pcm_statusstatus;1272 intret;1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1290 soundhandle *pHandle = (soundhandle *)streamid; 1291 struct snd_pcm_status status; 1292 int ret; 1293 1294 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 1295 DebugInt3(); 1296 return OSSERR_INVALID_STREAMID; 1297 } 1298 if(pPosition == NULL) { 1299 DebugInt3(); 1300 return OSSERR_INVALID_PARAMETER; 1301 } 1302 1303 //set operation to non-blocking 1304 pHandle->file.f_flags = O_NONBLOCK; 1305 1306 //Get the status of the stream 1307 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1308 1309 if(ret) { 1310 DebugInt3(); 1311 return UNIXToOSSError(ret); 1312 } 1313 1314 *pPosition = samples_to_bytes(status.appl_ptr); //return new hardware position 1315 return OSSERR_SUCCESS; 1296 1316 } 1297 1317 //****************************************************************************** … … 1299 1319 OSSRET OSS32_WaveGetStatus(ULONG streamid, ULONG *pStatus) 1300 1320 { 1301 soundhandle*pHandle = (soundhandle *)streamid;1302 struct snd_pcm_statusstatus;1303 intret;1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1321 soundhandle *pHandle = (soundhandle *)streamid; 1322 struct snd_pcm_status status; 1323 int ret; 1324 1325 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 1326 DebugInt3(); 1327 return OSSERR_INVALID_STREAMID; 1328 } 1329 if(pStatus == NULL) { 1330 DebugInt3(); 1331 return OSSERR_INVALID_PARAMETER; 1332 } 1333 1334 //set operation to non-blocking 1335 pHandle->file.f_flags = O_NONBLOCK; 1336 1337 //Get the status of the stream 1338 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1339 1340 if(ret) { 1341 DebugInt3(); 1342 return UNIXToOSSError(ret); 1343 } 1344 1345 *pStatus = status.state; 1346 return OSSERR_SUCCESS; 1327 1347 } 1328 1348 //****************************************************************************** … … 1330 1350 OSSRET OSS32_WaveSetVolume(OSSSTREAMID streamid, ULONG volume) 1331 1351 { 1332 1333 intret;1334 intleftvol, rightvol;1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 pcm_volume.volume[SNDRV_PCM_VOL_REAR_LEFT]= leftvol;1351 1352 1353 1354 1355 1356 } 1357 //****************************************************************************** 1358 1352 soundhandle *pHandle = (soundhandle *)streamid; 1353 int ret; 1354 int leftvol, rightvol; 1355 struct snd_pcm_volume pcm_volume; 1356 1357 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 1358 DebugInt3(); 1359 return OSSERR_INVALID_STREAMID; 1360 } 1361 //set operation to non-blocking 1362 pHandle->file.f_flags = O_NONBLOCK; 1363 1364 leftvol = GET_VOLUME_L(volume); 1365 rightvol = GET_VOLUME_R(volume); 1366 1367 pcm_volume.nrchannels = 4; 1368 pcm_volume.volume[SNDRV_PCM_VOL_FRONT_LEFT] = leftvol; 1369 pcm_volume.volume[SNDRV_PCM_VOL_FRONT_RIGHT] = rightvol; 1370 pcm_volume.volume[SNDRV_PCM_VOL_REAR_LEFT] = leftvol; 1371 pcm_volume.volume[SNDRV_PCM_VOL_REAR_RIGHT] = rightvol; 1372 1373 dprintf(("OSS32_WaveSetVolume %x to (%d,%d)", streamid, leftvol, rightvol)); 1374 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SETVOLUME, (ULONG)__Stack32ToFlat(&pcm_volume)); 1375 return UNIXToOSSError(ret); 1376 } 1377 //****************************************************************************** 1378
Note:
See TracChangeset
for help on using the changeset viewer.