- Timestamp:
- Apr 20, 2001, 3:22:38 PM (24 years ago)
- Location:
- trunk/src/dsound
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/dsound/dart.cpp
r5285 r5553 1 /* $Id: dart.cpp,v 1. 4 2001-03-06 20:11:16 mikeExp $ */1 /* $Id: dart.cpp,v 1.5 2001-04-20 13:22:37 phaller Exp $ */ 2 2 /* 3 3 * Dart Interface.. … … 51 51 ) 52 52 { 53 lLastBuff++; 54 if (lLastBuff == ulNumDartBuffs){ 55 lLastBuff = 0; 56 } 57 58 if( fIsPlaying == FALSE /*&& lLastBuff == 0*/ ){ 59 mciSendCommand(usDeviceID, MCI_STOP, MCI_WAIT, NULL, 0); 60 return TRUE; 61 } 53 // wrap last buffer index 54 lLastBuff++; 55 if (lLastBuff >= ulNumDartBuffs) 56 { 57 lLastBuff = 0; 58 } 59 60 if( fIsPlaying == FALSE /*&& lLastBuff == 0*/ ) 61 { 62 mciSendCommand(usDeviceID, MCI_STOP, MCI_WAIT, NULL, 0); 63 return TRUE; 64 } 62 65 63 66 /* Now mix sound from all playing secondary SoundBuffers into the primary buffer */ … … 370 373 long Dart_Play(USHORT usDeviceID, void *vpMixSetup, void *vpMixBuffer, long playing) 371 374 { 372 ULONG rc; 373 MCI_MIXSETUP_PARMS *MixSetup; 374 MCI_MIX_BUFFER *MixBuffer; 375 376 MixSetup = (MCI_MIXSETUP_PARMS*)vpMixSetup; 377 MixBuffer = (MCI_MIX_BUFFER*)vpMixBuffer; 378 379 dprintf(("DSOUND-DART: Dart_Play")); 380 381 if (playing == TRUE) { 382 rc = mciSendCommand(usDeviceID, MCI_RESUME, MCI_WAIT, NULL, 0); 383 if (rc != MCIERR_SUCCESS) { 384 dprintf(("DSOUND-DART: MCI_RESUME %d", rc)); 385 return DSERR_GENERIC; 386 } 387 } else { //if (playing==FALSE) 388 dprintf(("DSOUND-DART: Playback started!!!!")); 389 390 /* Mix the first buffer before playing */ 375 ULONG rc; 376 MCI_MIXSETUP_PARMS *MixSetup; 377 MCI_MIX_BUFFER *MixBuffer; 378 379 MixSetup = (MCI_MIXSETUP_PARMS*)vpMixSetup; 380 MixBuffer = (MCI_MIX_BUFFER*)vpMixBuffer; 381 382 dprintf(("DSOUND-DART: Dart_Play")); 383 384 if (playing == TRUE) 385 { 386 rc = mciSendCommand(usDeviceID, MCI_RESUME, MCI_WAIT, NULL, 0); 387 if (rc != MCIERR_SUCCESS) 388 { 389 dprintf(("DSOUND-DART: MCI_RESUME %d", rc)); 390 return DSERR_GENERIC; 391 } 392 } 393 else 394 { //if (playing==FALSE) 395 dprintf(("DSOUND-DART: Playback started!!!!")); 396 397 // verify if buffers have actually been allocated 398 // PH 2001-04-20 Power DVD 3 seens to come in here 399 // with ulNumDartBuffs == 0 and also pmixWrite==NULL. 400 // However pmixEvent is != NULL. So I assume (!) 401 // this might fix the cause. 402 // 403 // Does fix the crash actually. I suspect DART cannot 404 // deliver mixing functions for the requested sound format: 405 // 16-Bit, 4-channel?, 48kHz. 406 if( (MixSetup->pmixWrite != NULL) && 407 (MixSetup->ulNumBuffers > 0) ) 408 { 409 410 /* Mix the first buffer before playing */ 391 411 MixCallback(BUFFER_SIZE/ulNumDartBuffs); 392 412 memcpy(MixBuffer[lLastBuff].pBuffer, &pDSoundBuff[lLastBuff*(BUFFER_SIZE/ulNumDartBuffs)], BUFFER_SIZE/ulNumDartBuffs); … … 398 418 SetFS(sel); 399 419 fIsPlaying = TRUE; 400 } 401 402 return DS_OK; 403 } 420 } 421 } 422 423 return DS_OK; 424 } -
trunk/src/dsound/dsmixer.cpp
r5285 r5553 1 /* $Id: dsmixer.cpp,v 1. 4 2001-03-06 20:11:17 mikeExp $ */1 /* $Id: dsmixer.cpp,v 1.5 2001-04-20 13:22:38 phaller Exp $ */ 2 2 /* 3 3 * DirectSound Software Mixer … … 28 28 #include <misc.h> 29 29 30 signed long mixbuf[2300*2]; /* enough for 50 ms at 44100Hz stereo */ 31 32 void MixCallback(ULONG cbMix) { 33 // Check for priority level here; for DSSCL_WRITEPRIMARY just play directly 34 // from the primary buffer; for all others mix the secondary buffers 35 if (OS2IDirectSoundBuffer::primary->parentDS->GetCoopLevel() != DSSCL_WRITEPRIMARY) 36 MixFunc(OS2IDirectSoundBuffer::dsbroot, OS2IDirectSoundBuffer::primary, cbMix); 37 else { 38 } 30 //@@@ signed long mixbuf[2300*2]; /* enough for 50 ms at 44100Hz stereo */ 31 32 33 // The internal mixer buffer for sample calculations 34 // It's allocated on demand by MixFunc. 35 static signed long* mixbuf = NULL; // pointer to the mixer data buffer 36 static ulMixerBufferSize = 0; // current size of the mixer buffer 37 38 39 void MixCallback(ULONG cbMix) 40 { 41 // Check for priority level here; for DSSCL_WRITEPRIMARY just play directly 42 // from the primary buffer; for all others mix the secondary buffers 43 if (OS2IDirectSoundBuffer::primary->parentDS->GetCoopLevel() != DSSCL_WRITEPRIMARY) 44 MixFunc(OS2IDirectSoundBuffer::dsbroot, OS2IDirectSoundBuffer::primary, cbMix); 45 else 46 { 47 } 39 48 } 49 40 50 41 51 void MixOneBuffer(OS2IDirectSoundBuffer *inBuf, int tomix, int outrate) 42 52 { 43 unsigned char *data8b; 44 signed short *data16b; 45 int inpos, spd, i, j, sample, len, bytespersample, vol1, vol2; 46 int oldpos; 47 48 bytespersample = inBuf->lpfxFormat->wBitsPerSample * 49 inBuf->lpfxFormat->nChannels / 8; 50 inpos = inBuf->playpos / bytespersample * 1024 + inBuf->frac; 51 spd = 1024 * inBuf->frequency / outrate; 52 if (inBuf->pan <= 0) 53 vol1 = inBuf->volume; 54 else 55 vol1 = inBuf->volume * (256 - inBuf->pan) / 256; 56 if (inBuf->pan >= 0) 57 vol2 = inBuf->volume; 58 else 59 vol2 = inBuf->volume * (256 + inBuf->pan) / 256; 60 61 len = inBuf->bufferdesc.dwBufferBytes / bytespersample * 1024; 62 if ((inBuf->lpfxFormat->nChannels == 2) && (inBuf->lpfxFormat->wBitsPerSample == 16)) { 63 data16b = (signed short *) inBuf->lpBuffer; 64 for (i = 0; i < tomix; i++) { 65 j = inpos / 1024 * 2; 66 mixbuf[i*2] += data16b[j] * vol1 / 256; 67 mixbuf[i*2+1] += data16b[j+1] * vol2 / 256; 68 inpos += spd; 69 if (inpos >= len) { 70 if (inBuf->fLoop) inpos -= len; 71 else { 72 inBuf->fPlaying = FALSE; 73 if (inBuf->notify != NULL) 74 inBuf->notify->CheckStop(); 75 break; 76 } 77 } 78 } 79 } 80 if ((inBuf->lpfxFormat->nChannels == 1) && (inBuf->lpfxFormat->wBitsPerSample == 16)) { 81 data16b = (signed short *) inBuf->lpBuffer; 82 for (i = 0; i < tomix; i++) { 83 j = inpos / 1024; 84 sample = data16b[j]; 85 mixbuf[i*2] += sample * vol1 / 256; 86 mixbuf[i*2+1] += sample * vol2 / 256; 87 inpos += spd; 88 if (inpos >= len) { 89 if (inBuf->fLoop) inpos -= len; 90 else { 91 inBuf->fPlaying = FALSE; 92 if (inBuf->notify != NULL) 93 inBuf->notify->CheckStop(); 94 break; 95 } 96 } 97 } 98 } 99 if ((inBuf->lpfxFormat->nChannels == 2) && (inBuf->lpfxFormat->wBitsPerSample == 8)) { 100 data8b = (unsigned char *) inBuf->lpBuffer; 101 for (i = 0; i < tomix; i++) { 102 j = inpos / 1024 * 2; 103 sample = ((int) data8b[j] - 128) * vol1; 104 mixbuf[i*2] += sample; 105 sample = ((int) data8b[j+1] - 128) * vol2; 106 mixbuf[i*2+1] += sample; 107 inpos += spd; 108 if (inpos >= len) { 109 if (inBuf->fLoop) inpos -= len; 110 else { 111 inBuf->fPlaying = FALSE; 112 if (inBuf->notify != NULL) 113 inBuf->notify->CheckStop(); 114 break; 115 } 116 } 117 } 118 } 119 if ((inBuf->lpfxFormat->nChannels == 1) && (inBuf->lpfxFormat->wBitsPerSample == 8)) { 120 data8b = (unsigned char *) inBuf->lpBuffer; 121 for (i = 0; i < tomix; i++) { 122 j = inpos / 1024; 123 sample = (int) data8b[j] - 128; 124 mixbuf[i*2] += sample * vol1; 125 mixbuf[i*2+1] += sample * vol2; 126 inpos += spd; 127 if (inpos >= len) { 128 if (inBuf->fLoop) inpos -= len; 129 else { 130 inBuf->fPlaying = FALSE; 131 if (inBuf->notify != NULL) 132 inBuf->notify->CheckStop(); 133 break; 134 } 135 } 136 } 137 } 138 oldpos = inBuf->playpos; 139 inBuf->playpos = inpos / 1024 * bytespersample; 140 inBuf->frac = inpos % 1024; 141 142 // Check if any notifications are to be signaled 143 if (inBuf->notify != NULL) 144 inBuf->notify->CheckPos(oldpos, inBuf->playpos); 145 146 // keep the write cursor about 15ms ahead of the play cursor 147 inBuf->writepos = inBuf->playpos + inBuf->frequency * bytespersample / 67; 148 inBuf->writepos %= inBuf->bufferdesc.dwBufferBytes; 53 unsigned char *data8b; 54 signed short *data16b; 55 int inpos, spd, i, j, sample, len, bytespersample, vol1, vol2; 56 int oldpos; 57 58 bytespersample = inBuf->lpfxFormat->wBitsPerSample * 59 inBuf->lpfxFormat->nChannels / 8; 60 inpos = inBuf->playpos / bytespersample * 1024 + inBuf->frac; 61 spd = 1024 * inBuf->frequency / outrate; 62 if (inBuf->pan <= 0) 63 vol1 = inBuf->volume; 64 else 65 vol1 = inBuf->volume * (256 - inBuf->pan) / 256; 66 if (inBuf->pan >= 0) 67 vol2 = inBuf->volume; 68 else 69 vol2 = inBuf->volume * (256 + inBuf->pan) / 256; 70 71 len = inBuf->bufferdesc.dwBufferBytes / bytespersample * 1024; 72 if ((inBuf->lpfxFormat->nChannels == 2) && 73 (inBuf->lpfxFormat->wBitsPerSample == 16)) 74 { 75 data16b = (signed short *) inBuf->lpBuffer; 76 for (i = 0; i < tomix; i++) 77 { 78 j = inpos / 1024 * 2; 79 mixbuf[i*2] += data16b[j] * vol1 / 256; 80 mixbuf[i*2+1] += data16b[j+1] * vol2 / 256; 81 inpos += spd; 82 if (inpos >= len) 83 { 84 if (inBuf->fLoop) inpos -= len; 85 else 86 { 87 inBuf->fPlaying = FALSE; 88 if (inBuf->notify != NULL) 89 inBuf->notify->CheckStop(); 90 91 break; 92 } 93 } 94 } 95 } 96 97 if ((inBuf->lpfxFormat->nChannels == 1) && 98 (inBuf->lpfxFormat->wBitsPerSample == 16)) 99 { 100 data16b = (signed short *) inBuf->lpBuffer; 101 for (i = 0; i < tomix; i++) 102 { 103 j = inpos / 1024; 104 sample = data16b[j]; 105 mixbuf[i*2] += sample * vol1 / 256; 106 mixbuf[i*2+1] += sample * vol2 / 256; 107 inpos += spd; 108 if (inpos >= len) 109 { 110 if (inBuf->fLoop) inpos -= len; 111 else 112 { 113 inBuf->fPlaying = FALSE; 114 if (inBuf->notify != NULL) 115 inBuf->notify->CheckStop(); 116 117 break; 118 } 119 } 120 } 121 } 122 123 if ((inBuf->lpfxFormat->nChannels == 2) && 124 (inBuf->lpfxFormat->wBitsPerSample == 8)) 125 { 126 data8b = (unsigned char *) inBuf->lpBuffer; 127 for (i = 0; i < tomix; i++) 128 { 129 j = inpos / 1024 * 2; 130 sample = ((int) data8b[j] - 128) * vol1; 131 mixbuf[i*2] += sample; 132 sample = ((int) data8b[j+1] - 128) * vol2; 133 mixbuf[i*2+1] += sample; 134 inpos += spd; 135 if (inpos >= len) 136 { 137 if (inBuf->fLoop) inpos -= len; 138 else 139 { 140 inBuf->fPlaying = FALSE; 141 if (inBuf->notify != NULL) 142 inBuf->notify->CheckStop(); 143 144 break; 145 } 146 } 147 } 148 } 149 150 if ((inBuf->lpfxFormat->nChannels == 1) && 151 (inBuf->lpfxFormat->wBitsPerSample == 8)) 152 { 153 data8b = (unsigned char *) inBuf->lpBuffer; 154 for (i = 0; i < tomix; i++) 155 { 156 j = inpos / 1024; 157 sample = (int) data8b[j] - 128; 158 mixbuf[i*2] += sample * vol1; 159 mixbuf[i*2+1] += sample * vol2; 160 inpos += spd; 161 if (inpos >= len) 162 { 163 if (inBuf->fLoop) inpos -= len; 164 else 165 { 166 inBuf->fPlaying = FALSE; 167 if (inBuf->notify != NULL) 168 inBuf->notify->CheckStop(); 169 170 break; 171 } 172 } 173 } 174 } 175 176 oldpos = inBuf->playpos; 177 inBuf->playpos = inpos / 1024 * bytespersample; 178 inBuf->frac = inpos % 1024; 179 180 // Check if any notifications are to be signaled 181 if (inBuf->notify != NULL) 182 inBuf->notify->CheckPos(oldpos, inBuf->playpos); 183 184 // keep the write cursor about 15ms ahead of the play cursor 185 inBuf->writepos = inBuf->playpos + inBuf->frequency * bytespersample / 67; 186 inBuf->writepos %= inBuf->bufferdesc.dwBufferBytes; 149 187 } 150 188 151 void MixFunc (OS2IDirectSoundBuffer *firstBuf, OS2IDirectSoundBuffer *outBuf, 152 ULONG cbMix) { 153 OS2IDirectSoundBuffer *inBuf = firstBuf; 154 int i, outbits, outrate, outnch, tomix, outpos, outlen; 155 unsigned char *data8b; 156 signed short *data16b; 157 158 outbits = outBuf->lpfxFormat->wBitsPerSample; 159 outrate = outBuf->lpfxFormat->nSamplesPerSec; 160 outnch = outBuf->lpfxFormat->nChannels; 161 tomix = cbMix * 8 / outbits / outnch; 162 163 memset(&mixbuf[0], 0, tomix * 2 * sizeof(mixbuf[0])); 164 165 while (inBuf != NULL) { 166 if (inBuf->fPlaying) { 167 MixOneBuffer(inBuf, tomix, outrate); 168 } 169 inBuf = inBuf->next; 170 } 171 172 outpos = outBuf->playpos * 8 / outbits; 173 outlen = outBuf->bufferdesc.dwBufferBytes * 8 / outbits; 174 if (outbits == 16) { 175 data16b = (signed short *) outBuf->lpBuffer; 176 for (i = 0; i < tomix * outnch; i++) { 177 if (mixbuf[i] <= -32768) data16b[outpos] = -32768; 178 else if (mixbuf[i] >= 32767) data16b[outpos] = 32767; 179 else data16b[outpos] = (signed short)mixbuf[i]; 180 outpos++; 181 if (outpos >= outlen) outpos = 0; 182 } 183 } else { 184 data8b = (unsigned char *) outBuf->lpBuffer; 185 for (i = 0; i < tomix * outnch; i++) { 186 if (mixbuf[i] <= -32768) data8b[outpos] = 0; 187 else if (mixbuf[i] >= 32767) data8b[outpos] = 255; 188 else data8b[outpos] = (signed short)mixbuf[i] / 256 + 128; 189 outpos++; 190 if (outpos >= outlen) outpos = 0; 191 } 192 } 193 outBuf->playpos = outpos * outbits / 8; 189 190 void MixFunc (OS2IDirectSoundBuffer *firstBuf, 191 OS2IDirectSoundBuffer *outBuf, 192 ULONG cbMix) 193 { 194 OS2IDirectSoundBuffer *inBuf = firstBuf; 195 int i; 196 int outbits; 197 int outrate; 198 int outnch; 199 int tomix; 200 int outpos; 201 int outlen; 202 unsigned char *data8b; 203 signed short *data16b; 204 205 outbits = outBuf->lpfxFormat->wBitsPerSample; 206 outrate = outBuf->lpfxFormat->nSamplesPerSec; 207 outnch = outBuf->lpfxFormat->nChannels; 208 tomix = cbMix * 8 / outbits / outnch; 209 210 // calculate required size (elements) of mixer buffer 211 ULONG ulRequiredSize = tomix * outnch; 212 213 // dynamically allocate the mixerbuffer as required 214 if (ulMixerBufferSize < ulRequiredSize) 215 { 216 // check if buffer has been allocated at all 217 if (NULL == mixbuf) 218 { 219 // allocate new buffer 220 mixbuf = (signed long*) malloc(ulRequiredSize * sizeof(mixbuf[0])); 221 ulMixerBufferSize = tomix; 222 } 223 else 224 { 225 // reallocate existing buffer 226 mixbuf = (signed long*) realloc(mixbuf, ulRequiredSize * sizeof(mixbuf[0])); 227 ulMixerBufferSize = tomix; 228 } 229 } 230 231 232 /* PH 2001-04-20 PowerDVD 3 comes in with tomix==4096 233 * (ulNumDartBuffers == 1. 234 * So below memset() crashed as the former static 235 * mixer buffer was way to small. The dynamic allocation 236 * is supposed to fix this. 237 * 238 * Also the assumption (?) of outnch == 2 is not met here. 239 * PowerDVD tries with 4 channels, thus requiring an even 240 * larger buffer. 241 */ 242 memset(&mixbuf[0], 0, ulRequiredSize * sizeof(mixbuf[0])); 243 244 245 while (inBuf != NULL) 246 { 247 if (inBuf->fPlaying) 248 { 249 MixOneBuffer(inBuf, tomix, outrate); 250 } 251 inBuf = inBuf->next; 252 } 253 254 outpos = outBuf->playpos * 8 / outbits; 255 outlen = outBuf->bufferdesc.dwBufferBytes * 8 / outbits; 256 257 if (outbits == 16) 258 { 259 data16b = (signed short *) outBuf->lpBuffer; 260 for (i = 0; i < tomix * outnch; i++) 261 { 262 if (mixbuf[i] <= -32768) 263 data16b[outpos] = -32768; 264 else 265 if (mixbuf[i] >= 32767) 266 data16b[outpos] = 32767; 267 else 268 data16b[outpos] = (signed short)mixbuf[i]; 269 270 outpos++; 271 272 if (outpos >= outlen) 273 outpos = 0; 274 } 275 } 276 else 277 { 278 data8b = (unsigned char *) outBuf->lpBuffer; 279 for (i = 0; i < tomix * outnch; i++) 280 { 281 if (mixbuf[i] <= -32768) 282 data8b[outpos] = 0; 283 else 284 if (mixbuf[i] >= 32767) 285 data8b[outpos] = 255; 286 else 287 data8b[outpos] = (signed short)mixbuf[i] / 256 + 128; 288 289 outpos++; 290 if (outpos >= outlen) 291 outpos = 0; 292 } 293 } 294 295 outBuf->playpos = outpos * outbits / 8; 194 296 } 195 297
Note:
See TracChangeset
for help on using the changeset viewer.