support per-sample volume
This commit is contained in:
@@ -135,6 +135,7 @@ DSoundBuf::DSoundBuf(DSound &ds, DSoundBuf::hw hardware,
|
|||||||
samplerate = samplerate_;
|
samplerate = samplerate_;
|
||||||
samplebits = samplebits_;
|
samplebits = samplebits_;
|
||||||
writeahead = writeahead_;
|
writeahead = writeahead_;
|
||||||
|
volume = 0;
|
||||||
buffer_locked = false;
|
buffer_locked = false;
|
||||||
last_cursor_pos = write_cursor = buffer_bytes_filled = 0;
|
last_cursor_pos = write_cursor = buffer_bytes_filled = 0;
|
||||||
LastPosition = 0;
|
LastPosition = 0;
|
||||||
@@ -254,9 +255,14 @@ void DSoundBuf::SetVolume(float vol)
|
|||||||
vol = 0.001f; // fix log10f(0) == -INF
|
vol = 0.001f; // fix log10f(0) == -INF
|
||||||
float vl2 = log10f(vol) / log10f(2); /* vol log 2 */
|
float vl2 = log10f(vol) / log10f(2); /* vol log 2 */
|
||||||
|
|
||||||
/* Volume is a multiplier; SetVolume wants attenuation in thousands of a
|
/* Volume is a multiplier; SetVolume wants attenuation in thousands of a decibel. */
|
||||||
* decibel. */
|
const int new_volume = max( int(1000 * vl2), DSBVOLUME_MIN );
|
||||||
buf->SetVolume(max(int(1000 * vl2), DSBVOLUME_MIN));
|
|
||||||
|
if( volume == new_volume )
|
||||||
|
return;
|
||||||
|
volume = new_volume;
|
||||||
|
|
||||||
|
buf->SetVolume( volume );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if "pos" is between "start" and "end", for a circular buffer. */
|
/* Determine if "pos" is between "start" and "end", for a circular buffer. */
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class DSoundBuf
|
|||||||
IDirectSoundBuffer *buf;
|
IDirectSoundBuffer *buf;
|
||||||
|
|
||||||
int channels, samplerate, samplebits, writeahead;
|
int channels, samplerate, samplebits, writeahead;
|
||||||
|
int volume;
|
||||||
|
|
||||||
int buffersize;
|
int buffersize;
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ bool RageSound_DSound::stream::GetData(bool init)
|
|||||||
* fill anything in STOPPING; in that case, we just clear the audio buffer. */
|
* fill anything in STOPPING; in that case, we just clear the audio buffer. */
|
||||||
if(state != STOPPING)
|
if(state != STOPPING)
|
||||||
{
|
{
|
||||||
|
pcm->SetVolume( snd->GetVolume() );
|
||||||
|
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
int bytes_left = len;
|
int bytes_left = len;
|
||||||
|
|
||||||
@@ -236,14 +238,6 @@ RageSound_DSound::~RageSound_DSound()
|
|||||||
delete stream_pool[i];
|
delete stream_pool[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageSound_DSound::VolumeChanged()
|
|
||||||
{
|
|
||||||
for(unsigned i = 0; i < stream_pool.size(); ++i)
|
|
||||||
{
|
|
||||||
stream_pool[i]->pcm->SetVolume(SOUNDMAN->GetMixVolume());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RageSound_DSound::StartMixing( RageSoundBase *snd )
|
void RageSound_DSound::StartMixing( RageSoundBase *snd )
|
||||||
{
|
{
|
||||||
LockMutex L(SOUNDMAN->lock);
|
LockMutex L(SOUNDMAN->lock);
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ class RageSound_DSound: public RageSoundDriver
|
|||||||
void StopMixing( RageSoundBase *snd ); /* used by RageSound */
|
void StopMixing( RageSoundBase *snd ); /* used by RageSound */
|
||||||
int64_t GetPosition( const RageSoundBase *snd ) const;
|
int64_t GetPosition( const RageSoundBase *snd ) const;
|
||||||
void Update(float delta);
|
void Update(float delta);
|
||||||
void VolumeChanged();
|
|
||||||
|
|
||||||
int GetSampleRate( int rate ) const { return rate; }
|
int GetSampleRate( int rate ) const { return rate; }
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
const int channels = 2;
|
const int channels = 2;
|
||||||
const int bytes_per_frame = channels*2; /* 16-bit */
|
const int bytes_per_frame = channels*2; /* 16-bit */
|
||||||
const int samplerate = 44100;
|
const int samplerate = 44100;
|
||||||
const int buffersize_frames = 1024*4; /* in frames */
|
const int buffersize_frames = 1024*16; /* in frames */
|
||||||
const int buffersize = buffersize_frames * bytes_per_frame; /* in bytes */
|
const int buffersize = buffersize_frames * bytes_per_frame; /* in bytes */
|
||||||
|
|
||||||
/* We'll fill the buffer in chunks this big. This should evenly divide the
|
/* We'll fill the buffer in chunks this big. This should evenly divide the
|
||||||
@@ -80,7 +80,6 @@ bool RageSound_DSound_Software::GetData()
|
|||||||
memset(buf, 0, bufsize*sizeof(Uint16));
|
memset(buf, 0, bufsize*sizeof(Uint16));
|
||||||
|
|
||||||
static SoundMixBuffer mix;
|
static SoundMixBuffer mix;
|
||||||
mix.SetVolume( SOUNDMAN->GetMixVolume() );
|
|
||||||
|
|
||||||
for(unsigned i = 0; i < sounds.size(); ++i)
|
for(unsigned i = 0; i < sounds.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -114,7 +113,7 @@ bool RageSound_DSound_Software::GetData()
|
|||||||
bytes_read += got;
|
bytes_read += got;
|
||||||
bytes_left -= got;
|
bytes_left -= got;
|
||||||
|
|
||||||
mix.write( (Sint16 *) buf, bytes_read / sizeof(Sint16) );
|
mix.write( (Sint16 *) buf, bytes_read / sizeof(Sint16), sounds[i]->snd->GetVolume() );
|
||||||
|
|
||||||
if( bytes_left > 0 )
|
if( bytes_left > 0 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ bool RageSound_WaveOut::GetData()
|
|||||||
memset(buf, 0, bufsize*sizeof(Uint16));
|
memset(buf, 0, bufsize*sizeof(Uint16));
|
||||||
memset(buffers[b].lpData, 0, bufsize*sizeof(Uint16));
|
memset(buffers[b].lpData, 0, bufsize*sizeof(Uint16));
|
||||||
static SoundMixBuffer mix;
|
static SoundMixBuffer mix;
|
||||||
mix.SetVolume( SOUNDMAN->GetMixVolume() );
|
|
||||||
|
|
||||||
const int64_t play_pos = last_cursor_pos;
|
const int64_t play_pos = last_cursor_pos;
|
||||||
const int64_t cur_play_pos = GetPosition( NULL );
|
const int64_t cur_play_pos = GetPosition( NULL );
|
||||||
@@ -113,7 +112,7 @@ bool RageSound_WaveOut::GetData()
|
|||||||
bytes_read += got;
|
bytes_read += got;
|
||||||
bytes_left -= got;
|
bytes_left -= got;
|
||||||
|
|
||||||
mix.write( (Sint16 *) buf, bytes_read / sizeof(Sint16) );
|
mix.write( (Sint16 *) buf, bytes_read / sizeof(Sint16), sounds[i]->snd->GetVolume() );
|
||||||
|
|
||||||
if( bytes_left > 0 )
|
if( bytes_left > 0 )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user