git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7553
d7cf8633-e32d-0410-b094-
e92efae38249
// Initialize the channel
memset (target_chan, 0, sizeof (*target_chan));
VectorCopy (origin, target_chan->origin);
// Initialize the channel
memset (target_chan, 0, sizeof (*target_chan));
VectorCopy (origin, target_chan->origin);
- target_chan->master_vol = (int)(fvol * 255);
target_chan->sfx = sfx;
target_chan->flags = flags;
target_chan->pos = 0; // start of the sound
target_chan->sfx = sfx;
target_chan->flags = flags;
target_chan->pos = 0; // start of the sound
// Lock the SFX during play
S_LockSfx (sfx);
// Lock the SFX during play
S_LockSfx (sfx);
+
+ // and finally, apply the volume
+ S_SetChannelVolume(target_chan - channels, fvol);
void S_SetChannelVolume (unsigned int ch_ind, float fvol)
{
void S_SetChannelVolume (unsigned int ch_ind, float fvol)
{
+ sfx_t *sfx = channels[ch_ind].sfx;
+ if(sfx->volume_peak > 0)
+ {
+ // Replaygain support
+ // Con_DPrintf("Setting volume on ReplayGain-enabled track... %f -> ", fvol);
+ fvol *= sfx->volume_mult;
+ if(fvol * sfx->volume_peak > 1)
+ fvol = 1 / sfx->volume_peak;
+ // Con_DPrintf("%f\n", fvol);
+ }
channels[ch_ind].master_vol = (int)(fvol * 255.0f);
}
channels[ch_ind].master_vol = (int)(fvol * 255.0f);
}
unsigned int total_length; // in sample frames
const snd_fetcher_t *fetcher;
void *fetcher_data; // Per-sfx data for the sound fetching functions
unsigned int total_length; // in sample frames
const snd_fetcher_t *fetcher;
void *fetcher_data; // Per-sfx data for the sound fetching functions
+
+ float volume_mult; // for replay gain (multiplier to apply)
+ float volume_peak; // for replay gain (highest peak); if set to 0, ReplayGain isn't supported
};
// maximum supported speakers constant
};
// maximum supported speakers constant
if (snd_renderbuffer == NULL)
return false;
if (snd_renderbuffer == NULL)
return false;
+ // Initialize volume peak to 0; if ReplayGain is supported, the loader will change this away
+ sfx->volume_peak = 0.0;
+
// LordHavoc: if the sound filename does not begin with sound/, try adding it
if (strncasecmp(sfx->name, "sound/", 6))
{
// LordHavoc: if the sound filename does not begin with sound/, try adding it
if (strncasecmp(sfx->name, "sound/", 6))
{
qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
{
unsigned char *data;
qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
{
unsigned char *data;
- const char *loopcomment;
+ const char *thiscomment;
fs_offset_t filesize;
ov_decode_t ov_decode;
OggVorbis_File vf;
vorbis_info *vi;
vorbis_comment *vc;
ogg_int64_t len, buff_len;
fs_offset_t filesize;
ov_decode_t ov_decode;
OggVorbis_File vf;
vorbis_info *vi;
vorbis_comment *vc;
ogg_int64_t len, buff_len;
+ double peak = 0.0;
+ double gaindb = 0.0;
+ double gain;
if (!vf_dll)
return false;
if (!vf_dll)
return false;
vc = qov_comment(&vf, -1);
if(vc)
{
vc = qov_comment(&vf, -1);
if(vc)
{
- loopcomment = qvorbis_comment_query(vc, "LOOP_START", 0);
- if(loopcomment)
- sfx->loopstart = bound(0, (unsigned int) (atof(loopcomment) * (double)snd_renderbuffer->format.speed / (double)per_sfx->format.speed), sfx->total_length);
+ thiscomment = qvorbis_comment_query(vc, "LOOP_START", 0);
+ if(thiscomment)
+ sfx->loopstart = bound(0, (unsigned int) (atof(thiscomment) * (double)snd_renderbuffer->format.speed / (double)per_sfx->format.speed), sfx->total_length);
+ thiscomment = qvorbis_comment_query(vc, "REPLAYGAIN_TRACK_PEAK", 0);
+ if(thiscomment)
+ peak = atof(thiscomment);
+ thiscomment = qvorbis_comment_query(vc, "REPLAYGAIN_TRACK_GAIN", 0);
+ if(thiscomment)
+ gaindb = atof(thiscomment);
vc = qov_comment(&vf, -1);
if(vc)
{
vc = qov_comment(&vf, -1);
if(vc)
{
- loopcomment = qvorbis_comment_query(vc, "LOOP_START", 0);
- if(loopcomment)
- sfx->loopstart = bound(0, (unsigned int) (atoi(loopcomment) * (double)snd_renderbuffer->format.speed / (double)sb->format.speed), sfx->total_length);
+ thiscomment = qvorbis_comment_query(vc, "LOOP_START", 0);
+ if(thiscomment)
+ sfx->loopstart = bound(0, (unsigned int) (atoi(thiscomment) * (double)snd_renderbuffer->format.speed / (double)sb->format.speed), sfx->total_length);
+ thiscomment = qvorbis_comment_query(vc, "REPLAYGAIN_TRACK_PEAK", 0);
+ if(thiscomment)
+ peak = atof(thiscomment);
+ thiscomment = qvorbis_comment_query(vc, "REPLAYGAIN_TRACK_GAIN", 0);
+ if(thiscomment)
+ gaindb = atof(thiscomment);
+ if(peak)
+ {
+ sfx->volume_mult = min(1 / peak, exp(gaindb * 0.05 * log(10)));
+ sfx->volume_peak = peak;
+ Con_DPrintf ("\"%s\" uses ReplayGain (gain %f, peak %f)\n", filename, sfx->volume_mult, sfx->volume_peak);
+ }
+