[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
hack: make "bwoop", not "beep"
- To: linux-il(at-nospam)cs.huji.ac.il
- Subject: hack: make "bwoop", not "beep"
- From: "Nadav Har'El" <nyh(at-nospam)math.technion.ac.il>
- Date: Sun, 28 Oct 2001 22:51:56 +0200
- Hebrew-Date: 12 Heshvan 5762
- Sender: linux-il-bounce(at-nospam)cs.huji.ac.il
- User-Agent: Mutt/1.2i
Free code below! :)
Ever wished that X windows will generate an interesting sound instead of
that boring old beep? Perhaps a "bwoop" sound, or somebody shouting "Yo!"?
Or perhaps pop up a custom visual bell, say have a large red penguin flash in
front of your eyes?
After about a year that my computer was mute (I don't know why, but its
beep circuitry apparently doesn't work), I got fed up and decided I needed
a program that plays a sound (I do have a soundcard and speakers) whenever
X gets requested to generate a beep. I knew of a program like that in Digital
Unix (xsoundsentry), but none for Linux.
Searching freshmeat and google I found several programs similar to what I
wanted (e.g., "fancybell"). But none could play sound samples directly
through a ESound server (esd) like I wanted - esd is essential when you need
to mix several streams of sound (e.g., you're constantly listening to music
but still need to hear "bwoops", or ICQ's "Oh Oh!" once in a while).
So I sat down and hacked such a program on my own. It's so short that I can
include it below :) It works by waiting for XkbBellNotify events on the
X server (this requires the XKEYBOARD extension, but it is available on any
modern XFree86), and when a bell event arrives, it plays a sample that has
been previously cashed with esd. Caching the sample (rather than reading the
file each time - or worse - running an external "esdplay" process to play
it) is important for better response, especially when bells repeat quickly.
Unfortunately, I couldn't find good (or any, for that matter...) documentation
of neither the Xkb extension or of esd's API - so I had to look at include
files, other source files, nm output, and a lot of guessing. But the result
works very nicely :) Enjoy!
Being a quick hack, this program (which I called esdbell) doesn't yet have
many options - in the future it might acquire the capability to run external
programs, to play sounds via other mechanisms (not only esd), to show
funky visual bells, to generate different bells in various conditions and
so on. But as it stands it is already quite useful and easy to extend.
-----------------------------------------------------------------------------
/* capture bell events (using Xkb extensions) and play sound samples (using
the efficient eSound)
To compile: cc main.c -L/usr/X11R6/lib -lX11 -lesd
(C) 2001 Nadav Har'El. License: GPL
*/
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <esd.h>
int
main(int argc, char **argv)
{
Display *dpy;
char *dpyname;
char *progname=argv[0];
unsigned int bit1 = XkbAudibleBellMask, bit2 = XkbAudibleBellMask;
XEvent event;
int major = XkbMajorVersion, minor = XkbMinorVersion;
int Xkb_event_base;
char *esd_server;
int esd, sample;
/* TODO: -display, $DISPLAY argument */
dpyname=NULL;
dpy=XOpenDisplay(dpyname);
if(!dpy){
fprintf(stderr,"%s: Unable to open display \"%s\"\n",progname,
XDisplayName(dpyname));
exit(1);
}
/* initialize Xkb */
if (!XkbLibraryVersion(&major, &minor) ||
!XkbQueryExtension(dpy, NULL, &Xkb_event_base, NULL, &major, &minor)){
fprintf(stderr,"%s: No Xkb extension on display \"%s\"?\n",
progname,XDisplayName(dpyname));
XCloseDisplay(dpy);
exit(1);
}
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbBellNotifyMask, XkbBellNotifyMask);
XkbSetAutoResetControls(dpy, XkbAudibleBellMask, &bit1, &bit2);
XkbChangeEnabledControls(dpy, XkbUseCoreKbd, XkbAudibleBellMask, 0);
/* initialize esd */
esd_server=NULL;
esd = esd_open_sound(esd_server);
if(esd<=0){
fprintf(stderr,"%s: Couldn't connect to Esound server.\n",
progname);
XCloseDisplay(dpy);
exit(1);
}
sample=esd_file_cache(esd, "esdbell", "/usr/share/enlightenment/themes/ShinyMetal/sound/samples/drip.wav");
if(sample<0){
fprintf(stderr,"%s: couldn't cache sound sample.\n",
progname);
XCloseDisplay(dpy);
exit(1);
}
/* event loop */
for(;;){
XNextEvent(dpy,&event);
if(event.type == Xkb_event_base &&
((XkbEvent *)&event)->any.xkb_type == XkbBellNotify){
esd_sample_play(esd, sample);
}
}
/* TODO: do this also on interrupt */
esd_sample_free(esd, sample);
esd_close(esd);
XCloseDisplay(dpy);
exit(0);
}
-----------------------------------------------------------------------------
--
Nadav Har'El | Sunday, Oct 28 2001, 12 Heshvan 5762
nyh@math.technion.ac.il |-----------------------------------------
Phone: +972-53-245868, ICQ 13349191 |Isn't Disney World a people trap operated
http://nadav.harel.org.il |by a mouse?
=================================================================
To unsubscribe, send mail to linux-il-request@linux.org.il with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail linux-il-request@linux.org.il