Changeset 515 for GPL/branches
- Timestamp:
- Jul 14, 2010, 6:17:29 AM (15 years ago)
- File:
-
- 1 edited
-
GPL/branches/uniaud32-2.1.x/lib32/sound.c (modified) (32 diffs)
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) ((a*pHandle->doublesamplesize)/2)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, //signed 16 bits sample (little endian/Intel)62 /* OSS32_PCM_FORMAT_S16_BE */ SNDRV_PCM_FORMAT_S16_BE, //signed 16 bits sample (big endian/Motorola)63 /* OSS32_PCM_FORMAT_U16_LE */ SNDRV_PCM_FORMAT_U16_LE, //unsigned 16 bits sample (little endian/Intel)64 /* OSS32_PCM_FORMAT_U16_BE */ SNDRV_PCM_FORMAT_U16_BE, //unsigned 16 bits sample (big endian/Motorola)65 /* OSS32_PCM_FORMAT_S24_LE */ SNDRV_PCM_FORMAT_S24_LE, //signed 24 bits sample (little endian/Intel)66 /* OSS32_PCM_FORMAT_S24_BE */ SNDRV_PCM_FORMAT_S24_BE, //signed 24 bits sample (big endian/Motorola)67 /* OSS32_PCM_FORMAT_U24_LE */ SNDRV_PCM_FORMAT_U24_LE, //unsigned 24 bits sample (little endian/Intel)68 /* OSS32_PCM_FORMAT_U24_BE */ SNDRV_PCM_FORMAT_U24_BE, //unsigned 24 bits sample (big endian/Motorola)69 /* OSS32_PCM_FORMAT_S32_LE */ SNDRV_PCM_FORMAT_S32_LE, //signed 32 bits sample (little endian/Intel)70 /* OSS32_PCM_FORMAT_S32_BE */ SNDRV_PCM_FORMAT_S32_BE, //signed 32 bits sample (big endian/Motorola)71 /* OSS32_PCM_FORMAT_U32_LE */ SNDRV_PCM_FORMAT_U32_LE, //unsigned 32 bits sample (little endian/Intel)72 /* OSS32_PCM_FORMAT_U32_BE */ SNDRV_PCM_FORMAT_U32_BE, //unsigned 32 bits sample (big endian/Motorola)73 /* OSS32_PCM_FORMAT_MULAW */ SNDRV_PCM_FORMAT_MU_LAW, //8 bps (compressed 16 bits sample)74 /* OSS32_PCM_FORMAT_ALAW */ SNDRV_PCM_FORMAT_A_LAW, //8 bps (compressed 16 bits sample)75 /* OSS32_PCM_FORMAT_ADPCM */ SNDRV_PCM_FORMAT_IMA_ADPCM, //4 bps (compressed 16 bits sample)76 /* OSS32_PCM_FORMAT_MPEG */ SNDRV_PCM_FORMAT_MPEG, //AC3?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 alsa_fops = fsop;85 alsa_fops = fsop; 85 86 } 86 87 return 0; … … 91 92 { 92 93 if(!strcmp(name, "alsa")) { 93 alsa_fops = NULL;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 if(fops == NULL) return -1;102 103 memcpy(&oss_devices[OSS32_SPECIALID], fops, sizeof(struct file_operations));104 return OSS32_SPECIALID;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 if(fops == NULL) return -1;111 112 memcpy(&oss_devices[OSS32_MIXERID], fops, sizeof(struct file_operations));113 return OSS32_MIXERID;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 if(fops == NULL) return -1;120 121 memcpy(&oss_devices[OSS32_MIDIID], fops, sizeof(struct file_operations));122 return OSS32_MIDIID;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 if(fops == NULL) return -1;129 130 memcpy(&oss_devices[OSS32_DSPID], fops, sizeof(struct file_operations));131 return OSS32_DSPID;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 if(fops == NULL) return -1;138 139 memcpy(&oss_devices[OSS32_SYNTHID], fops, sizeof(struct file_operations));140 return OSS32_SYNTHID;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 memset(&oss_devices[OSS32_SPECIALID], 0, sizeof(struct file_operations));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 memset(&oss_devices[OSS32_MIXERID], 0, sizeof(struct file_operations));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 memset(&oss_devices[OSS32_MIDIID], 0, sizeof(struct file_operations));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 memset(&oss_devices[OSS32_DSPID], 0, sizeof(struct file_operations));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 memset(&oss_devices[OSS32_SYNTHID], 0, sizeof(struct file_operations));171 memset(&oss_devices[OSS32_SYNTHID], 0, sizeof(struct file_operations)); 171 172 } 172 173 //****************************************************************************** … … 174 175 OSSRET UNIXToOSSError(int unixerror) 175 176 { 176 switch(unixerror) {177 case 0:178 return OSSERR_SUCCESS;179 case -ENOMEM:180 return OSSERR_OUT_OF_MEMORY;181 case -ENODEV:182 return OSSERR_NO_DEVICE_AVAILABLE;183 case -ENOTTY:184 case -EINVAL:185 return OSSERR_INVALID_PARAMETER;186 case -EAGAIN:187 return OSSERR_AGAIN;//????188 case -ENXIO:189 return OSSERR_IO_ERROR;190 case -EBUSY:191 return OSSERR_BUSY;192 case -EPERM:193 return OSSERR_ACCESS_DENIED; //??194 case -EPIPE:195 case -EBADFD:196 return OSSERR_ACCESS_DENIED; //??197 default:198 dprintf(("Unknown error %d", (unixerror > 0) ? unixerror : -unixerror));199 return OSSERR_UNKNOWN;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 switch(ALSADataType)208 {209 case SNDRV_PCM_FORMAT_S8:210 return OSS32_CAPS_PCM_FORMAT_S8;//signed 8 bits sample211 case SNDRV_PCM_FORMAT_U8:212 return OSS32_CAPS_PCM_FORMAT_U8;//unsigned 8 bits sample213 case SNDRV_PCM_FORMAT_S16_LE:214 return OSS32_CAPS_PCM_FORMAT_S16_LE;//signed 16 bits sample (little endian/Intel)215 case SNDRV_PCM_FORMAT_S16_BE:216 return OSS32_CAPS_PCM_FORMAT_S16_BE;//signed 16 bits sample (big endian/Motorola)217 case SNDRV_PCM_FORMAT_U16_LE:218 return OSS32_CAPS_PCM_FORMAT_U16_LE;//unsigned 16 bits sample (little endian/Intel)219 case SNDRV_PCM_FORMAT_U16_BE:220 return OSS32_CAPS_PCM_FORMAT_U16_BE;//unsigned 16 bits sample (big endian/Motorola)221 case SNDRV_PCM_FORMAT_S24_LE:222 return OSS32_CAPS_PCM_FORMAT_S24_LE;//signed 24 bits sample (little endian/Intel)223 case SNDRV_PCM_FORMAT_S24_BE:224 return OSS32_CAPS_PCM_FORMAT_S24_BE;//signed 24 bits sample (big endian/Motorola)225 case SNDRV_PCM_FORMAT_U24_LE:226 return OSS32_CAPS_PCM_FORMAT_U24_LE;//unsigned 24 bits sample (little endian/Intel)227 case SNDRV_PCM_FORMAT_U24_BE:228 return OSS32_CAPS_PCM_FORMAT_U24_BE;//unsigned 16 bits sample (big endian/Motorola)229 case SNDRV_PCM_FORMAT_S32_LE:230 return OSS32_CAPS_PCM_FORMAT_S32_LE;//signed 32 bits sample (little endian/Intel)231 case SNDRV_PCM_FORMAT_S32_BE:232 return OSS32_CAPS_PCM_FORMAT_S32_BE;//signed 32 bits sample (big endian/Motorola)233 case SNDRV_PCM_FORMAT_U32_LE:234 return OSS32_CAPS_PCM_FORMAT_U32_LE;//unsigned 32 bits sample (little endian/Intel)235 case SNDRV_PCM_FORMAT_U32_BE:236 return OSS32_CAPS_PCM_FORMAT_U32_BE;//unsigned 32 bits sample (big endian/Motorola)237 case SNDRV_PCM_FORMAT_MU_LAW:238 return OSS32_CAPS_PCM_FORMAT_MULAW;//8 bps (compressed 16 bits sample)239 case SNDRV_PCM_FORMAT_A_LAW:240 return OSS32_CAPS_PCM_FORMAT_ALAW;//8 bps (compressed 16 bits sample)241 case SNDRV_PCM_FORMAT_IMA_ADPCM:242 return OSS32_CAPS_PCM_FORMAT_ADPCM;//4 bps (compressed 16 bits sample)243 case SNDRV_PCM_FORMAT_MPEG:244 return OSS32_CAPS_PCM_FORMAT_MPEG;//AC3?245 default:246 DebugInt3();247 return -1;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 ULONG fuOSSRates = 0;255 256 char szMixerName[64];257 char szDeviceName[128];258 OSS32_QueryNames(OSS32_DEFAULT_DEVICE, szDeviceName,259 sizeof(szDeviceName),szMixerName,260 sizeof(szMixerName), TRUE);261 if (strncmp(szDeviceName,"HDA",3) != 0){262 /* non-HDA audio - support 5512 - 32000 Hz sample rates */263 if(fuRates & SNDRV_PCM_RATE_5512) {264 fuOSSRates |= OSS32_CAPS_PCM_RATE_5512;265 }266 if(fuRates & SNDRV_PCM_RATE_8000) {267 fuOSSRates |= OSS32_CAPS_PCM_RATE_8000;268 }269 if(fuRates & SNDRV_PCM_RATE_11025) {270 fuOSSRates |= OSS32_CAPS_PCM_RATE_11025;271 }272 if(fuRates & SNDRV_PCM_RATE_16000) {273 fuOSSRates |= OSS32_CAPS_PCM_RATE_16000;274 }275 if(fuRates & SNDRV_PCM_RATE_22050) {276 fuOSSRates |= OSS32_CAPS_PCM_RATE_22050;277 }278 if(fuRates & SNDRV_PCM_RATE_32000) {279 fuOSSRates |= OSS32_CAPS_PCM_RATE_32000;280 }281 } else {282 printk("HDA audio detected - don't support 5512 - 32000 Hz audio sample rates\n");283 }284 if(fuRates & SNDRV_PCM_RATE_44100) {285 fuOSSRates |= OSS32_CAPS_PCM_RATE_44100;286 }287 if(fuRates & SNDRV_PCM_RATE_48000) {288 fuOSSRates |= OSS32_CAPS_PCM_RATE_48000;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 if(fuRates & SNDRV_PCM_RATE_64000) {292 fuOSSRates |= OSS32_CAPS_PCM_RATE_64000;293 }294 if(fuRates & SNDRV_PCM_RATE_88200) {295 fuOSSRates |= OSS32_CAPS_PCM_RATE_88200;296 }297 if(fuRates & SNDRV_PCM_RATE_96000) {298 fuOSSRates |= OSS32_CAPS_PCM_RATE_96000;299 }300 if(fuRates & SNDRV_PCM_RATE_176400) {301 fuOSSRates |= OSS32_CAPS_PCM_RATE_176400;302 }303 if(fuRates & SNDRV_PCM_RATE_192000) {304 fuOSSRates |= OSS32_CAPS_PCM_RATE_192000;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 if(fuRates & SNDRV_PCM_RATE_CONTINUOUS) {308 fuOSSRates |= OSS32_CAPS_PCM_RATE_CONTINUOUS;309 }310 311 //TODO:312 if(fuRates & SNDRV_PCM_RATE_KNOT) {313 DebugInt3();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 return fuOSSRates;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 struct snd_pcm_hw_params *params;327 intret, fmt, i;328 ULONGformat_mask;329 struct snd_mask*mask;330 int max_ch;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 dprintf(("OSS32_QueryDevCaps"));334 dprintf(("OSS32_QueryDevCaps")); 334 335 #endif 335 // max_ch = GetMaxChannels(deviceid, OSS32_CAPS_WAVE_PLAYBACK);336 337 //these structures are too big to put on the stack338 pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL);339 if(pcminfo == NULL) {340 DebugInt3();341 printk("OSS32_QueryDevCaps: out of memory\n");342 return OSSERR_OUT_OF_MEMORY;343 }344 params = (struct snd_pcm_hw_params *)(pcminfo+1);345 346 printk("Number of cards: %i",nrCardsDetected);347 printk("dev id: %i",deviceid);348 pDevCaps->nrDevices = 1;//nrCardsDetected;349 // pDevCaps->nrDevices = nrCardsDetected;350 pDevCaps->ulCaps= OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE;351 352 //query wave in & out caps353 for(i=0;i<2;i++)354 {355 PWAVE_CAPS pWaveCaps = (i == 0) ? &pDevCaps->waveOutCaps : &pDevCaps->waveInCaps;356 357 ret = OSS32_WaveOpen(deviceid, (i == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, 0, 0);358 if(ret != OSSERR_SUCCESS)359 {360 printk("OSS32_QueryDevCaps: wave open error %i\n", ret);361 DebugInt3();362 goto fail;363 }364 pHandle = (soundhandle *)streamid;365 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {366 printk("OSS32_QueryDevCaps: invalid stream id \n");367 ret = OSSERR_INVALID_STREAMID;368 goto fail;369 }370 //set operation to non-blocking371 pHandle->file.f_flags = O_NONBLOCK;372 373 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);374 if(ret != 0) {375 printk("OSS32_QueryDevCaps: SNDRV_PCM_IOCTL_INFO error %i\n", ret);376 ret = UNIXToOSSError(ret);377 goto fail;378 }379 if(i == 0) {//only need to do this once380 if(pcminfo->name[0]) {381 strncpy(pDevCaps->szDeviceName, pcminfo->name, sizeof(pDevCaps->szDeviceName));382 }383 else strncpy(pDevCaps->szDeviceName, pcminfo->id, sizeof(pDevCaps->szDeviceName));384 }385 printk("Device name: %s", pDevCaps->szDeviceName);386 pWaveCaps->nrStreams = pcminfo->subdevices_count;387 388 //get all hardware parameters389 _snd_pcm_hw_params_any(params);390 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);391 if(ret != 0) {392 printk("OSS32_QueryDevCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i\n", ret);393 ret = UNIXToOSSError(ret);394 goto fail;395 }396 397 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;398 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;399 pWaveCaps->ulChanFlags= 0;400 if(pWaveCaps->ulMinChannels == 1) {401 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;402 }403 if(pWaveCaps->ulMaxChannels >= 2) {404 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;405 }406 if(pWaveCaps->ulMaxChannels >= 4) {407 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;408 }409 if(pWaveCaps->ulMaxChannels >= 6) {410 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;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 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK);417 418 pWaveCaps->ulRateFlags= mask->bits[0];419 420 pWaveCaps->ulRateFlags= ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);421 422 pWaveCaps->ulDataFormats = 0;423 424 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);425 format_mask = mask->bits[0];426 for(fmt=0;fmt<32;fmt++)427 {428 if(format_mask & (1 << fmt))429 {430 int f = ALSAToOSSDataType(fmt);431 if (f >= 0)432 pWaveCaps->ulDataFormats |= f;433 }434 }435 436 OSS32_WaveClose(streamid);437 streamid = 0;438 439 }440 441 //Check support for MPU401, FM & Wavetable MIDI442 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_MPU401_MIDIOUT, &streamid) == OSSERR_SUCCESS)443 {444 pDevCaps->ulCaps |= OSS32_CAPS_MPU401_PLAYBACK;445 OSS32_MidiClose(streamid);446 streamid = 0;447 }448 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_MPU401_MIDIIN, &streamid) == OSSERR_SUCCESS)449 {450 pDevCaps->ulCaps |= OSS32_CAPS_MPU401_CAPTURE;451 OSS32_MidiClose(streamid);452 streamid = 0;453 }454 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_FM_MIDIOUT, &streamid) == OSSERR_SUCCESS)455 {456 pDevCaps->ulCaps |= OSS32_CAPS_FMSYNTH_PLAYBACK;457 OSS32_MidiClose(streamid);458 streamid = 0;459 }460 if(OSS32_MidiOpen(deviceid, OSS32_STREAM_WAVETABLE_MIDIOUT, &streamid) == OSSERR_SUCCESS)461 {462 pDevCaps->ulCaps |= OSS32_CAPS_WAVETABLE_PLAYBACK;463 OSS32_MidiClose(streamid);464 streamid = 0;465 }466 467 if(OSS32_MixQueryName(deviceid, &pDevCaps->szMixerName, sizeof(pDevCaps->szMixerName)) != OSSERR_SUCCESS) {468 DebugInt3();469 printk("OSS32_QueryDevCaps: OSS32_MixQueryName error\n");470 goto fail;471 }472 printk("OSS32_QueryDevCaps: devname: [%s]\n", pDevCaps->szDeviceName);473 kfree(pcminfo);474 streamid = 0;475 476 477 return OSSERR_SUCCESS;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 printk("OSS32_QueryDevCaps failed\n");481 DebugInt3();482 if(streamid) OSS32_WaveClose(streamid);483 if(pcminfo) kfree(pcminfo);484 485 return ret;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 soundhandle *pHandle;492 intret,i;493 494 if (pStreamId)495 *pStreamId = 0;496 else497 {498 printk("ERROR: invalid stream id pointer passed\n");499 return OSSERR_OUT_OF_MEMORY;500 }501 502 if(alsa_fops == NULL) {503 DebugInt3();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 dprintf(("OSS32_WaveOpen: no devices"));506 dprintf(("OSS32_WaveOpen: no devices")); 506 507 #endif 507 printk("OSS32_WaveOpen: no devices\n");508 509 return OSSERR_NO_DEVICE_AVAILABLE;510 }511 512 // printk("dev id: %i\n",deviceid);513 514 pHandle = kmalloc(sizeof(soundhandle), GFP_KERNEL);515 if(pHandle == NULL) {516 DebugInt3();517 printk("OSS32_WaveOpen: out of memory\n");518 return OSSERR_OUT_OF_MEMORY;519 }520 memset(pHandle, 0, sizeof(soundhandle));521 522 //set operation to non-blocking523 pHandle->file.f_flags = O_NONBLOCK;524 525 //setup pointers in file structure (used internally by ALSA)526 pHandle->file.f_dentry= &pHandle->d_entry;527 pHandle->file.f_dentry->d_inode = &pHandle->inode;528 529 switch(streamtype) {530 case OSS32_STREAM_WAVEOUT:531 pHandle->file.f_mode = FMODE_WRITE;532 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_PCM_PLAYBACK) + pcm;533 break;534 case OSS32_STREAM_WAVEIN:535 pHandle->file.f_mode = FMODE_READ;536 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_PCM_CAPTURE) + pcm;537 break;538 default:539 DebugInt3();540 kfree(pHandle);541 printk("OSS32_WaveOpen: invalid parameter\n");542 return OSSERR_INVALID_PARAMETER;543 }544 545 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);546 printk("OSS32_WaveOpen. ret: %i\n", ret);547 /* check if PCM already opened (stupid uniaud16.sys doesnt closes it) */548 if (ret == -16)549 {550 for (i=0; i < 8*256; i++)551 {552 if (opened_handles[i].handle != 0)553 {554 ret = 0;555 if (pStreamId)556 *pStreamId = (ULONG)opened_handles[i].handle;557 opened_handles[i].reuse = 1; /* try to reuse */558 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)559 {560 if (!opened_handles[i].reuse)561 {562 //opened_handles[i].handle = 0;563 kfree(opened_handles[i].handle); //free handle data564 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);565 printk("OSS32_WaveOpen. Reopen ret: %i\n", ret);566 }567 else568 {569 kfree(pHandle);570 pHandle = opened_handles[i].handle;571 }572 break;573 }574 }575 }576 }577 else if (ret == 0)578 {579 for (i=0; i < 8*256; i++)580 {581 if (opened_handles[i].handle == 0)582 {583 opened_handles[i].handle = pHandle;584 opened_handles[i].FileId = fileid;585 break;586 }587 }588 }589 590 if(ret) {591 kfree(pHandle);592 DebugInt3();593 printk("OSS32_WaveOpen: open error: %i\n",ret);594 return UNIXToOSSError(ret);595 }596 pHandle->magic = MAGIC_WAVE_ALSA32;597 if (pStreamId)598 *pStreamId = (ULONG)pHandle;599 // filling opened handles table600 printk("OSS32_WaveOpen. streamid %X\n",(ULONG)pHandle);601 return OSSERR_SUCCESS;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 soundhandle *pHandle = (soundhandle *)streamid;609 intret = 0, i;610 611 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {612 DebugInt3();613 printk("OSS32_WaveClose. invalid streamid %X\n",(ULONG)pHandle);614 return OSSERR_INVALID_STREAMID;615 }616 617 //set operation to non-blocking618 pHandle->file.f_flags = O_NONBLOCK;619 620 for (i=0; i < 8*256; i++)621 {622 if (opened_handles[i].handle == pHandle)623 {624 printk("Found phandle for closing: %x reuse flag: %i\n", pHandle, opened_handles[i].reuse);625 if (!opened_handles[i].reuse)626 {627 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);628 opened_handles[i].handle = 0;629 kfree(pHandle); //free handle data630 OSS32_CloseUNI16(); /* say to UNIAUD16 that we closing now */631 } else632 {633 /* prepare for reuse */634 pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_RESET, 0);635 pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);636 }637 break;638 }639 }640 641 if (i >= 8*256)642 {643 //all already closed644 printk("phandle %x not found\n", pHandle);645 // return OSSERR_SUCCESS;646 }647 648 649 if(ret) {650 printk("Error closing wave. rc = %i\n", ret);651 DebugInt3();652 return UNIXToOSSError(ret);653 }654 printk("OSS32_WaveClose. streamid %X\n",(ULONG)pHandle);655 return OSSERR_SUCCESS;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 soundhandle *pHandle = (soundhandle *)streamid;662 intret;662 soundhandle *pHandle = (soundhandle *)streamid; 663 int ret; 663 664 664 665 #ifdef DEBUG 665 dprintf(("OSS32_WavePrepare"));666 dprintf(("OSS32_WavePrepare")); 666 667 #endif 667 668 668 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {669 DebugInt3();669 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 670 DebugInt3(); 670 671 //#ifdef DEBUG 671 printk("vladest: OSS32_WavePrepare: invalid streamID\n");672 printk("vladest: OSS32_WavePrepare: invalid streamID\n"); 672 673 //#endif 673 674 674 return OSSERR_INVALID_STREAMID;675 }676 //set operation to non-blocking677 pHandle->file.f_flags = O_NONBLOCK;678 679 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);680 if (ret)681 printk("Wave prepare ret = %i, streamid %X\n",ret,(ULONG)pHandle);682 683 return UNIXToOSSError(ret);;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 soundhandle *pHandle = (soundhandle *)streamid;690 intret;691 692 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {693 DebugInt3();694 return OSSERR_INVALID_STREAMID;695 }696 //set operation to non-blocking697 pHandle->file.f_flags = O_NONBLOCK;698 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0);699 if (ret)700 printk("Wave start ret = %i, streamid %X\n",ret,(ULONG)pHandle);701 702 return UNIXToOSSError(ret);;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 soundhandle *pHandle = (soundhandle *)streamid;709 intret;710 711 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {712 DebugInt3();713 return OSSERR_INVALID_STREAMID;714 }715 //set operation to non-blocking716 pHandle->file.f_flags = O_NONBLOCK;717 718 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);719 if (ret)720 printk("Wave stop ret = %i. streamid %X\n",ret,(ULONG)pHandle);721 722 return UNIXToOSSError(ret);;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 soundhandle *pHandle = (soundhandle *)streamid;729 intret;730 731 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {732 DebugInt3();733 return OSSERR_INVALID_STREAMID;734 }735 //set operation to non-blocking736 pHandle->file.f_flags = O_NONBLOCK;737 738 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, 0);739 if (ret)740 printk("Wave pause ret = %i, streamid %X\n",ret,(ULONG)pHandle);741 742 return UNIXToOSSError(ret);;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 soundhandle *pHandle = (soundhandle *)streamid;749 intret;750 751 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {752 DebugInt3();753 return OSSERR_INVALID_STREAMID;754 }755 //set operation to non-blocking756 pHandle->file.f_flags = O_NONBLOCK;757 758 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, 1);759 if (ret)760 printk("Wave resume ret = %i, streamid %X\n",ret,(ULONG)pHandle);761 762 return UNIXToOSSError(ret);;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 /* ATTENTION: these values depend on the definition in pcm.h! */767 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,768 64000, 88200, 96000, 176400, 192000767 /* 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 struct snd_pcm_hw_params params;777 struct snd_pcm_sw_params swparams;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 ULONG ulMinRate, ulMaxRate;785 786 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {787 788 DebugInt3();789 return OSSERR_INVALID_STREAMID;790 }791 if(pHwParams == NULL) {792 793 DebugInt3();794 return OSSERR_INVALID_PARAMETER;795 }796 if(pHwParams->ulDataType >= OSS32_PCM_MAX_FORMATS) {797 798 DebugInt3();799 return OSSERR_INVALID_PARAMETER;800 }801 if ((int)pHwParams->ulNumChannels <= 0) {802 printk("OSS32_WaveSetHwParams error. Invalid number of channels: %i\n", pHwParams->ulNumChannels);803 DebugInt3();804 return OSSERR_INVALID_PARAMETER;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 //set operation to non-blocking808 pHandle->file.f_flags = O_NONBLOCK;809 810 //size of two samples (adpcm sample can be as small as 4 bits (mono), so take two)811 samplesize = snd_pcm_format_size(OSSToALSADataType[pHwParams->ulDataType], 1);812 pHandle->doublesamplesize = samplesize * 2;813 pHandle->doublesamplesize *= pHwParams->ulNumChannels;814 periodbytes = pHwParams->ulPeriodSize;815 periodsize= bytes_to_samples(periodbytes);816 // checking number of channels817 818 dprintf(("channels: %ld, period size: %lx",pHwParams->ulNumChannels, periodbytes));819 820 _snd_pcm_hw_params_any(¶ms);821 do {822 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_ACCESS,823 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);824 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS,825 pHwParams->ulNumChannels, 0);826 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));827 if (ret == 0) break;828 pHwParams->ulNumChannels--;829 } while(ret < 0 && pHwParams->ulNumChannels > 1);830 831 dprintf(("channels selected: %d",pHwParams->ulNumChannels));832 833 //get all hardware parameters834 _snd_pcm_hw_params_any(¶ms);835 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_ACCESS,836 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);837 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT,838 OSSToALSADataType[pHwParams->ulDataType], 0);839 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));840 if(ret != 0) {841 dprintf(("invalid format %lx\n", OSSToALSADataType[pHwParams->ulDataType]));842 return UNIXToOSSError(ret);843 }844 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,845 pHwParams->ulBitsPerSample, 0);846 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));847 if(ret != 0) {848 dprintf(("invalid number of sample bits %d\n", pHwParams->ulBitsPerSample));849 return UNIXToOSSError(ret);850 }851 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS,852 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0);853 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));854 if(ret != 0) {855 dprintf(("invalid number of frame bits %d\n", pHwParams->ulBitsPerSample*pHwParams->ulNumChannels));856 return UNIXToOSSError(ret);857 }858 859 //_snd_pcm_hw_params_any(¶ms);860 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,861 pHwParams->ulBitsPerSample, 0);862 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS,863 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0);864 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT,865 OSSToALSADataType[pHwParams->ulDataType], 0);866 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS,867 pHwParams->ulNumChannels, 0);868 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE,869 pHwParams->ulSampleRate, 0);870 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));871 if(ret != 0) {872 dprintf(("32_WSetHwPms (first pass) error %d bps:%d fmt: %d ch: %d sr: %d\n",873 ret,874 pHwParams->ulBitsPerSample,875 OSSToALSADataType[pHwParams->ulDataType],876 pHwParams->ulNumChannels,877 pHwParams->ulSampleRate));878 //printk("OSS32_WaveSetHwParams invalid sample rate %i\n", pHwParams->ulSampleRate);879 //printk("will set to nearest\n");880 _snd_pcm_hw_params_any(¶ms);881 for (i=0; i<(sizeof(rates)/sizeof(unsigned))-1;i++)882 {883 if (pHwParams->ulSampleRate >= rates[i] &&884 pHwParams->ulSampleRate <= rates[i+1])885 {886 pHwParams->ulSampleRate = rates[i];887 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE,888 pHwParams->ulSampleRate, 0);889 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));890 if(ret == 0)891 {892 _snd_pcm_hw_params_any(¶ms);893 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,894 pHwParams->ulBitsPerSample, 0);895 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS,896 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0);897 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT,898 OSSToALSADataType[pHwParams->ulDataType], 0);899 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS,900 pHwParams->ulNumChannels, 0);901 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE,902 pHwParams->ulSampleRate, 0);903 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)__Stack32ToFlat(¶ms));904 goto __next;905 }906 }907 }908 DebugInt3();909 return UNIXToOSSError(ret);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 //check period size against lower and upper boundaries914 minperiodbytes = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->min;915 maxperiodbytes = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->max;916 if(periodbytes < minperiodbytes) {917 periodbytes = minperiodbytes;918 }919 else920 if(periodbytes > maxperiodbytes) {921 periodbytes = maxperiodbytes;922 }923 924 minperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min;925 maxperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->max;926 if(periodsize < minperiodsize) {927 periodsize = minperiodsize;928 }929 else930 if(periodsize > maxperiodsize) {931 periodsize = maxperiodsize;932 }933 934 if(samples_to_bytes(periodsize) < periodbytes) {935 periodbytes = samples_to_bytes(periodsize);936 }937 else938 if(bytes_to_samples(periodbytes) < periodsize) {939 periodsize = bytes_to_samples(periodbytes);940 }941 942 //make sure period size is a whole fraction of the buffer size943 bufsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->max;944 if(periodsize) {945 nrperiods = bufsize/periodbytes;946 }947 else {948 dprintf(("32_WSHwPrms error. Invalid periodsize (=0). closing file\n"));949 DebugInt3();950 return OSSERR_INVALID_PARAMETER;951 }952 //check nr of periods against lower and upper boundaries953 minnrperiods = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIODS)->min;954 maxnrperiods = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIODS)->max;955 if(nrperiods < minnrperiods) {956 nrperiods = minnrperiods;957 }958 else959 if(nrperiods > maxnrperiods) {960 nrperiods = maxnrperiods;961 }962 //an odd nr of periods is not always a good thing (CMedia -> clicks during 8 bps playback),963 //so we make sure it's an even number.964 if(nrperiods == 1) {965 dprintf(("32_WSHwPrms error. Invalid Num periods(=1). closing file\n"));966 DebugInt3();967 return OSSERR_INVALID_PARAMETER;968 }969 nrperiods &= ~1;970 971 //initialize parameter block & set sample rate, nr of channels and sample format, nr of periods,972 //period size and buffer size973 974 _snd_pcm_hw_params_any(¶ms);975 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_ACCESS,976 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);977 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,978 pHwParams->ulBitsPerSample, 0);979 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS,980 pHwParams->ulBitsPerSample*pHwParams->ulNumChannels, 0);981 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_FORMAT,982 OSSToALSADataType[pHwParams->ulDataType], 0);983 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS,984 pHwParams->ulNumChannels, 0);985 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE,986 pHwParams->ulSampleRate, 0);987 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,988 periodsize, 0);989 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,990 periodbytes, 0);991 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIODS,992 nrperiods, 0);993 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,994 periodsize*nrperiods, 0);995 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,996 periodbytes*nrperiods, 0);997 998 999 dprintf(("HWP: SR rate %ld, BPS %ld, CH %ld, PRSZ %lx, periods %lx",1000 pHwParams->ulSampleRate, pHwParams->ulBitsPerSample, pHwParams->ulNumChannels, periodsize, nrperiods));1001 1002 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)__Stack32ToFlat(¶ms));1003 if (ret == -77 && fTryAgain == FALSE)1004 {1005 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);1006 fTryAgain = TRUE;1007 dprintf((" Error -77 from first IOCTL HW Parms"));1008 goto tryagain;1009 }1010 1011 if(ret) {1012 if(fTryAgain == FALSE) {1013 minperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min;1014 maxperiodsize = hw_param_interval((¶ms), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->max;1015 dprintf(("Period size min=%lx max=%lx", minperiodsize, maxperiodsize));1016 if(minperiodsize > maxperiodsize) {1017 //ALSA doesn't like the period size; try suggested one1018 periodsize= maxperiodsize;1019 periodbytes = samples_to_bytes(periodsize);1020 dprintf((" Peroid size error IOCTL HW Parms"));1021 fTryAgain = TRUE;1022 goto tryagain;1023 }1024 }1025 dprintf(("Error %ld second time.. Bailing", ret));1026 return UNIXToOSSError(ret);1027 }1028 1029 //set silence threshold (all sizes in frames) (only needed for playback)1030 if(pHandle->file.f_mode == FMODE_WRITE)1031 {1032 swparams.avail_min= periodsize;1033 swparams.period_step= 1;1034 if(nrperiods <= 2) {1035 swparams.silence_size = (periodsize/2);1036 }1037 else {1038 swparams.silence_size = periodsize;1039 }1040 swparams.silence_threshold = swparams.silence_size;1041 swparams.sleep_min= 0;1042 swparams.start_threshold = 1;1043 swparams.stop_threshold = periodsize*nrperiods;1044 swparams.tstamp_mode= SNDRV_PCM_TSTAMP_NONE;1045 swparams.xfer_align= periodsize;1046 1047 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)__Stack32ToFlat(&swparams));1048 }1049 1050 total = 0;1051 per_bytes = periodbytes;1052 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1053 if ( ((status.state != SNDRV_PCM_STATE_PREPARED) &&1054 (status.state != SNDRV_PCM_STATE_SETUP) &&1055 (status.state != SNDRV_PCM_STATE_RUNNING) &&1056 (status.state != SNDRV_PCM_STATE_DRAINING))) {1057 dprintf(("Device is not in proper state: %lx. Calling prepare\n", status.state));1058 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);1059 }1060 return UNIXToOSSError(ret);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 ULONG xchg( ULONG *p, ULONG x);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 // return OSSERR_SUCCESS;1080 1081 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {1082 DebugInt3();1083 return OSSERR_INVALID_STREAMID;1084 }1085 if(pTransferred == NULL || buffer == 0 || size == 0) {1086 DebugInt3();1087 return OSSERR_INVALID_PARAMETER;1088 }1089 1090 //set operation to non-blocking1091 pHandle->file.f_flags = O_NONBLOCK;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; // We have any global error, don't try more1166 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 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {1211 DebugInt3();1212 return OSSERR_INVALID_STREAMID;1213 }1214 if(pPosition == NULL) {1215 DebugInt3();1216 return OSSERR_INVALID_PARAMETER;1217 }1218 1219 //set operation to non-blocking1220 pHandle->file.f_flags = O_NONBLOCK;1221 1222 //Get the status of the stream1223 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1224 1225 if(ret) {1226 DebugInt3();1227 return UNIXToOSSError(ret);1228 }1229 1230 dprintf2(("OSS32_WaveGetPosition: hardware %x application %x", samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr)));1231 *pPosition = samples_to_bytes(status.hw_ptr); //return new hardware position1232 return OSSERR_SUCCESS;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 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {1243 DebugInt3();1244 return OSSERR_INVALID_STREAMID;1245 }1246 if(pBytesAvail == NULL) {1247 DebugInt3();1248 return OSSERR_INVALID_PARAMETER;1249 }1250 1251 //set operation to non-blocking1252 pHandle->file.f_flags = O_NONBLOCK;1253 1254 //Get the nr of bytes left in the audio buffer1255 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1256 1257 if(ret) {1258 DebugInt3();1259 return UNIXToOSSError(ret);1260 }1261 ret = samples_to_bytes(status.avail);1262 1263 *pBytesAvail = ret;1264 return OSSERR_SUCCESS;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 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {1275 DebugInt3();1276 return OSSERR_INVALID_STREAMID;1277 }1278 if(pPosition == NULL) {1279 DebugInt3();1280 return OSSERR_INVALID_PARAMETER;1281 }1282 1283 //set operation to non-blocking1284 pHandle->file.f_flags = O_NONBLOCK;1285 1286 //Get the status of the stream1287 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1288 1289 if(ret) {1290 DebugInt3();1291 return UNIXToOSSError(ret);1292 }1293 1294 *pPosition = samples_to_bytes(status.appl_ptr); //return new hardware position1295 return OSSERR_SUCCESS;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 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {1306 DebugInt3();1307 return OSSERR_INVALID_STREAMID;1308 }1309 if(pStatus == NULL) {1310 DebugInt3();1311 return OSSERR_INVALID_PARAMETER;1312 }1313 1314 //set operation to non-blocking1315 pHandle->file.f_flags = O_NONBLOCK;1316 1317 //Get the status of the stream1318 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status));1319 1320 if(ret) {1321 DebugInt3();1322 return UNIXToOSSError(ret);1323 }1324 1325 *pStatus = status.state;1326 return OSSERR_SUCCESS;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 soundhandle *pHandle = (soundhandle *)streamid;1333 intret;1334 intleftvol, rightvol;1335 struct snd_pcm_volume pcm_volume;1336 1337 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {1338 DebugInt3();1339 return OSSERR_INVALID_STREAMID;1340 }1341 //set operation to non-blocking1342 pHandle->file.f_flags = O_NONBLOCK;1343 1344 leftvol = GET_VOLUME_L(volume);1345 rightvol = GET_VOLUME_R(volume);1346 1347 pcm_volume.nrchannels = 4;1348 pcm_volume.volume[SNDRV_PCM_VOL_FRONT_LEFT] = leftvol;1349 pcm_volume.volume[SNDRV_PCM_VOL_FRONT_RIGHT] = rightvol;1350 pcm_volume.volume[SNDRV_PCM_VOL_REAR_LEFT]= leftvol;1351 pcm_volume.volume[SNDRV_PCM_VOL_REAR_RIGHT] = rightvol;1352 1353 dprintf(("OSS32_WaveSetVolume %x to (%d,%d)", streamid, leftvol, rightvol));1354 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SETVOLUME, (ULONG)__Stack32ToFlat(&pcm_volume));1355 return UNIXToOSSError(ret);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.
