int dsound_set_buffer_3d_maximum_distance ( LPDIRECTSOUND3DBUFFER buffer, float distance ) { unsigned int dsrval; #ifdef _WIN32 dsrval = IDirectSound3DBuffer_SetMaxDistance ( buffer, distance, DS3D_DEFERRED ); if ( dsrval != DS_OK ) { debug_log ( "Unable to set max distance of 3d buffer: %s", get_dsound_error_message ( dsrval ) ); return ( FALSE ); } else { return ( TRUE ); } #endif }
int I2_PlaySound(void *data, boolean play3d, sound3d_t *desc, int pan) { sampleheader_t *header = data; byte *sample = (byte*) data + sizeof(sampleheader_t); sndsource_t *sndbuf; void *writePtr1=NULL, *writePtr2=NULL; DWORD writeBytes1, writeBytes2; int samplelen = header->length, freq = header->frequency, bits = 8; // Can we play sounds? if(!initOk || data == NULL) return 0; // Sorry... if(snd_Resample != 1 && snd_Resample != 2 && snd_Resample != 4) { ST_Message("I2_PlaySound: invalid resample factor.\n"); snd_Resample = 1; } // Get a buffer that's doing nothing. sndbuf = I2_GetFreeSource(play3d); sndbuf->startTime = I_GetTime(); // Prepare the audio data. if(snd_Resample == 1 && !snd_16bits) // Play sounds as normal? { // No resampling necessary. sndbuf->freq = header->frequency; } else { // Resample the sound. sample = I_Resample8bitSound(sample, header->length, freq, snd_Resample, snd_16bits, &samplelen); if(snd_16bits) bits = 16; freq *= snd_Resample; sndbuf->freq = freq; } if(sndbuf->source) { // Release the old source. I2_KillSource(sndbuf); } // Create a new source. if(FAILED(hr = createDSBuffer(play3d? DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE | DSBCAPS_STATIC : DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_STATIC, header->length * snd_Resample, freq, bits, 1, &sndbuf->source))) { ST_Message("I2_PlaySound: couldn't create a new buffer (result = %d).\n", hr & 0xffff); memset(sndbuf, 0, sizeof(*sndbuf)); return 0; } if(play3d) { // Query the 3D interface. if(FAILED(hr = IDirectSoundBuffer_QueryInterface(sndbuf->source, &IID_IDirectSound3DBuffer, &sndbuf->source3D))) { ST_Message("I2_PlaySound: couldn't get 3D buffer interface (result = %d).\n", hr & 0xffff); IDirectSoundBuffer_Release(sndbuf->source); memset(sndbuf, 0, sizeof(*sndbuf)); return 0; } } // Lock the buffer. if(FAILED(hr = IDirectSoundBuffer_Lock(sndbuf->source, 0, samplelen, &writePtr1, &writeBytes1, &writePtr2, &writeBytes2, 0))) { I_error("I2_PlaySound: couldn't lock source (result = %d).\n", hr & 0xffff); } // Copy the data over. memcpy(writePtr1, sample, writeBytes1); if(writePtr2) memcpy(writePtr2, (char*) sample + writeBytes1, writeBytes2); // Unlock the buffer. if(FAILED(hr = IDirectSoundBuffer_Unlock(sndbuf->source, writePtr1, writeBytes1, writePtr2, writeBytes2))) { I_error("I2_PlaySound: couldn't unlock source (result = %d).\n", hr & 0xffff); return 0; } if(play3d) { // Set the 3D parameters of the source. if(desc->flags & DDSOUNDF_VERY_LOUD) { // You can hear this from very far away (e.g. thunderclap). IDirectSound3DBuffer_SetMinDistance(sndbuf->source3D, 10000, DS3D_DEFERRED); IDirectSound3DBuffer_SetMaxDistance(sndbuf->source3D, 20000, DS3D_DEFERRED); } else { IDirectSound3DBuffer_SetMinDistance(sndbuf->source3D, 100, DS3D_DEFERRED); IDirectSound3DBuffer_SetMaxDistance(sndbuf->source3D, MAX_SND_DIST, DS3D_DEFERRED); } if(desc->flags & DDSOUNDF_LOCAL) IDirectSound3DBuffer_SetMode(sndbuf->source3D, DS3DMODE_DISABLE, DS3D_DEFERRED); } else { // If playing in 2D mode, set the pan. I2_SetPan(sndbuf, pan/1000.0f); } I2_UpdateSource(sndbuf, desc); // Start playing the buffer. if(FAILED(hr = IDirectSoundBuffer_Play(sndbuf->source, 0, 0, 0))) { I_error("I2_PlaySound: couldn't start source (result = %d).\n", hr & 0xffff); return 0; } // Return the handle to the sound source. return (sndbuf->id = idGen++); }