Mercurial > pidgin
diff src/gtksound.c @ 12815:a8bffa7fb6ac
[gaim-migrate @ 15163]
SF Patch #1400794 from charkins
"This patch adds a software volume control in gaim when
libao is used. This patch could use some testing on
platforms other than linux/x86."
"this patch also removes a small
duplicated code block from the sound prefs code."
"Updating the patch again to fix . . . two other lines in [sound_page()]
that should be using GAIM_HIG_BOX_SPACE."
I modified this to make the volume control insensitive when sounds are
not going through libao (i.e. the method is "Console beep", "Command" or
"No sounds").
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Wed, 11 Jan 2006 03:42:22 +0000 |
parents | 8c339d9f1bb4 |
children | ff267281e882 |
line wrap: on
line diff
--- a/src/gtksound.c Wed Jan 11 03:37:59 2006 +0000 +++ b/src/gtksound.c Wed Jan 11 03:42:22 2006 +0000 @@ -52,6 +52,7 @@ }; #define PLAY_SOUND_TIMEOUT 15000 +#define SQRT2_2 0.70710678118654752440 static guint mute_login_sounds_timeout = 0; static gboolean mute_login_sounds = FALSE; @@ -321,6 +322,7 @@ gaim_prefs_add_bool("/gaim/gtk/sound/mute", FALSE); gaim_prefs_add_string("/gaim/gtk/sound/command", ""); gaim_prefs_add_string("/gaim/gtk/sound/method", "automatic"); + gaim_prefs_add_int("/gaim/gtk/sound/volume", 50); #ifdef USE_AO gaim_debug_info("sound", "Initializing sound output drivers.\n"); @@ -384,8 +386,51 @@ return FALSE; /* do not run again */ } + +static void +scale_pcm_data(char *data, int nframes, ao_sample_format *format, + double intercept, double minclip, double maxclip, + float scale) +{ + int i; + float v; + gint16 *data16 = (gint16*)data; + gint32 *data32 = (gint32*)data; +#ifdef G_HAVE_GINT64 + gint64 *data64 = (gint64*)data; #endif + switch(format->bits) { + case 16: + for(i = 0; i < nframes * format->channels; i++) { + v = ((data16[i] - intercept) * scale) + intercept; + v = CLAMP(v, minclip, maxclip); + data16[i]=(gint16)v; + } + break; + case 32: + for(i = 0; i < nframes * format->channels; i++) { + v = ((data32[i] - intercept) * scale) + intercept; + v = CLAMP(v, minclip, maxclip); + data32[i]=(gint32)v; + } + break; +#ifdef G_HAVE_GINT64 + case 64: + for(i = 0; i < nframes * format->channels; i++) { + v = ((data64[i] - intercept) * scale) + intercept; + v = CLAMP(v, minclip, maxclip); + data64[i]=(gint64)v; + } + break; +#endif + default: + gaim_debug_warning("gtksound", "Cannot scale %d bit pcm data.\n", format->bits); + break; + } +} +#endif /* USE_AO */ + static void gaim_gtk_sound_play_file(const char *filename) { @@ -393,6 +438,7 @@ #ifdef USE_AO pid_t pid; AFfilehandle file; + int volume = 50; #endif if (!sound_initialized) @@ -449,23 +495,31 @@ return; } #ifdef USE_AO + volume = gaim_prefs_get_int("/gaim/gtk/sound/volume"); + volume = CLAMP(volume, 0, 100); + pid = fork(); if (pid < 0) return; else if (pid == 0) { /* Child process */ + float scale = ((float) volume * volume) / 2500; file = afOpenFile(filename, "rb", NULL); if(file) { ao_device *device; ao_sample_format format; int in_fmt; int bytes_per_frame; + double slope, intercept, minclip, maxclip; format.rate = afGetRate(file, AF_DEFAULT_TRACK); format.channels = afGetChannels(file, AF_DEFAULT_TRACK); afGetSampleFormat(file, AF_DEFAULT_TRACK, &in_fmt, &format.bits); + afGetPCMMapping(file, AF_DEFAULT_TRACK, &slope, + &intercept, &minclip, &maxclip); + /* XXX: libao doesn't seem to like 8-bit sounds, so we'll * let libaudiofile make them a bit better for us */ if(format.bits == 8) @@ -497,6 +551,9 @@ while((frames_read = afReadFrames(file, AF_DEFAULT_TRACK, buf, buf_frames))) { + if(volume != 50) + scale_pcm_data(buf, frames_read, &format, intercept, + minclip, maxclip, scale); if(!ao_play(device, buf, frames_read * bytes_per_frame)) break; }