/* Demoniac v0.666a -- DAEMON'iac Advisor ====================================== Coded by Stas (Mail: stanis@linuxmail.org; URL: http://sysd.org/); (C)opyLeft by SysD Destructive Labs, 1997-2004 DESCRIPTION: Produces sound (in this specific case, the beginning of Iron Maiden song "Fear Of The Dark") on internal PC Speaker hardware. Compiles and works on: * DOS (DJGPP, Turbo C) * Windows 9x/NT/2K/XP (Borland C, Microsoft Visual C, MinGW) * Linux (gcc) * FreeBSD (gcc) (see compiling instructions below) Can be useful to provide audible alert without acessing soundcard. Requires superuser powers except for Windows NT/2K/XP (note that superuser is default mode for DOS & Windows 9x ;) This code is also supposed to be portable to *any* OS that runs on i386 architecture. Other architectures are not supported and neither will be! COMPILING: * Compile on Linux & FreeBSD with: gcc -O2 -o demoniac demoniac.c; strip demoniac * Compile Windows generic with: gcc -O2 -o demoniac.exe demoniac.c strip demoniac.exe or cl demoniac.c or bcc32 demoniac.c * Compile Windows 9x-specific (for debugging) with: gcc -D_WIN9X -O2 -o demoniac.exe demoniac.c or cl -D_WIN9X demoniac.c or bcc32 -D_WIN9X demoniac.c * Compile Windows NT/2K/XP-specific (for debugging) with: gcc -D_WINNT -O2 -o demoniac.exe demoniac.c or cl -D_WINNT demoniac.c or bcc32 -D_WINNT demoniac.c * Compile on DOS under Turbo C: tcc -O demoniac.c * Compile on DOS under DJGPP: gcc -O2 -o demoniac.exe demoniac.c strip demoniac Note: you might try -DNOFEAR compiler flag if you want more simple music. (this WAS the original music played by demoniac 0.1b ;) USAGE: Reprogram sound in the way you want and paste into your own source :) BUGS: * Sound timing is different on different circunstances. * Sound finalization isn't properly handled on DOS/Win9x. THANKS: * Dr. Checks, for music conversion * Iron Maiden, for music itself :) * Linus Torvalds, for /usr/src/linux/include/asm-i386 * Peter Norton, for PC speaker controlling algorithm * Riku Saikkonen, for his IO-Port-Programming-HOWTO * The Snowblind Alliance, for Rio utility v1.07 * t0p, for idea of daemon beeper */ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <stdlib.h> #include <windows.h> #if defined(_MSC_VER) #pragma comment(linker,"/ENTRY:main") #pragma comment(linker,"/MERGE:.rdata=.data") #pragma comment(linker,"/MERGE:.text=.data") #pragma comment(linker,"/NODEFAULTLIB:libc.lib") #pragma comment(linker,"/NODEFAULTLIB:libcmt.lib") #pragma comment(lib,"msvcrt.lib") #pragma comment(lib,"kernel32.lib") #if (_MSC_VER < 1300) #pragma comment(linker,"/IGNORE:4078") #pragma comment(linker,"/OPT:NOWIN98") #endif #elif defined(__BORLANDC__) typedef int (*toutp) (unsigned short port, int databyte); typedef int (*tinp) (unsigned short port); toutp _outp = NULL; tinp _inp = NULL; int ImportMSFunc(void) { HINSTANCE hMsvcrt; hMsvcrt = LoadLibrary("msvcrt.dll"); if (hMsvcrt == NULL) return 0; _outp = (toutp) GetProcAddress(hMsvcrt, "_outp"); if (_outp == NULL) return 0; _inp = (tinp) GetProcAddress(hMsvcrt, "_inp"); if (_inp == NULL) return 0; return 1; } #endif #define OUTPORT(p, v) _outp((uword) (p), v) #define INPORT(p) _inp(p) #define SLEEP(t) Sleep(t) #elif defined(__TURBOC__) #include <dos.h> #define _DOS #define SLEEP(t) delay(t) #elif defined(__DJGPP__) #include <pc.h> #define _DOS #undef nosound void nosound(void) { sound(0); return; } #define SLEEP(t) delay(t/2) #endif #if defined (_WIN9X) #define DoSound(freq, time) HWDoSound(freq, time) #elif defined(_WINNT) #define INTERN #define DoSound(freq, time) Beep(freq, time) #elif defined (_WIN32) #define API_OR_HW #elif defined (_DOS) #define INTERN #define NEEDSTOP void DoSound(unsigned int freq, unsigned int time) { sound(freq); SLEEP(time); nosound(); return; } #elif defined(__linux__) #include <asm/io.h> #include <signal.h> #include <stdio.h> #define NEEDINIT #define NEEDSTOP #define IS_UNIX #define OUTPORT(p, v) outb(v, p) #define INPORT(p) inb(p) #define SLEEP(t) usleep(t*1000) // microsseconds => milliseconds #define DoSound(freq, time) HWDoSound(freq, time) #elif defined(__FreeBSD__) #include <fcntl.h> #include <machine/cpufunc.h> #include <signal.h> #include <stdio.h> #define NEEDINIT #define NEEDSTOP #define IS_UNIX #define OUTPORT(p, v) outb(p, v) #define INPORT(p) inb(p) #define SLEEP(t) usleep(t*1000) // microsseconds => milliseconds #define DoSound(freq, time) HWDoSound(freq, time) #else #error Unsupported platform! #endif #ifndef INTERN #ifdef uword #undef uword #endif typedef unsigned short uword; #ifdef uchar #undef uchar #endif typedef unsigned char uchar; #ifndef LOBYTE #define LOBYTE(w) ((uchar) (w)) #endif #ifndef HIBYTE #define HIBYTE(w) ((uchar) (((uword) (w) >> 8) & 0xFF)) #endif void HWSound(unsigned int freq) { uword counter = 1193280 / freq; /* cycle counter */ OUTPORT(0x43, 0xB6); /* prepare timer */ OUTPORT(0x42, LOBYTE(counter)); /* send low byte */ OUTPORT(0x42, HIBYTE(counter)); /* send high byte */ OUTPORT(0x61, INPORT(0x61) | 0x03); /* turn speaker ON */ return; } void HWNoSound(void) { OUTPORT(0x61, INPORT(0x61) & 0xFC); /* turn speaker OFF */ return; } void HWDoSound(unsigned int freq, unsigned int time) { HWSound(freq); SLEEP(time); HWNoSound(); return; } #endif #ifdef API_OR_HW void DoSound(unsigned int freq, unsigned int time) { static OSVERSIONINFO osver; if (osver.dwOSVersionInfoSize != sizeof(OSVERSIONINFO)) { osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osver); } if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) Beep(freq, time); else HWDoSound(freq, time); return; } #endif #ifdef NEEDINIT #if defined(__linux__) int InitSound(void) { if ( ioperm(0x42, 2, 1) || ioperm(0x61, 1, 1) || ioperm(0x80, 1, 1) ) /* can we do that? */ return 0; /* no; see errno() */ else return 1; /* yeah, I've done it!!! */ } #elif defined(__FreeBSD__) int InitSound(void) { if (open("/dev/io", O_RDONLY) == -1) return 0; else return 1; } #else #error I dunno how to init sound on this platform! #endif #endif #ifdef NEEDSTOP #if defined(IS_UNIX) static void shutup(int signal) { HWNoSound(); exit(1); } #endif void StopHandle(void) { #if defined(_DOS) atexit(nosound); #elif defined(IS_UNIX) signal(SIGTERM, shutup); signal(SIGINT, shutup); signal(SIGHUP, shutup); #else #error I dunno how to handle finalization on this platform! #endif return; } #endif #define LEN 150 #define MLEN 1 #define PlayNote(freq, time) { DoSound(freq, time); SLEEP(MLEN); } int main(void) { #ifdef NEEDINIT if (!InitSound()) { fprintf(stderr, "must be root!!!\n"); return -1; } #endif #if defined(_WIN32) && defined(__BORLANDC__) if (!ImportMSFunc()) { fprintf(stderr, "can't import from MSVC runtime!!!\n"); return -1; } #endif #ifdef NEEDSTOP StopHandle(); #endif #ifndef NOFEAR PlayNote(587, LEN * 2); // D5 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(698, LEN); // F5 PlayNote(698, LEN); // F5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(523, LEN * 2); // C5 PlayNote(392, LEN); // G4 PlayNote(392, LEN); // G4 PlayNote(523, LEN); // C5 PlayNote(523, LEN); // C5 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(523, LEN); // C5 PlayNote(523, LEN); // C5 PlayNote(659, LEN); // E5 PlayNote(523, LEN); // C5 PlayNote(587, LEN * 2); // D5 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(698, LEN); // F5 PlayNote(698, LEN); // F5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(523, LEN * 2); // C5 PlayNote(392, LEN); // G4 PlayNote(392, LEN); // G4 PlayNote(523, LEN); // C5 PlayNote(523, LEN); // C5 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(659, LEN); // E5 PlayNote(659, LEN); // E5 PlayNote(587, LEN); // D5 PlayNote(587, LEN); // D5 PlayNote(523, LEN); // C5 PlayNote(523, LEN); // C5 PlayNote(659, LEN); // E5 PlayNote(523, LEN); // C5 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(330, LEN); // E4 PlayNote(330, LEN); // E4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(523, LEN); // C5 PlayNote(523, LEN); // C5 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(392, LEN); // G4 PlayNote(392, LEN); // G4 PlayNote(294, LEN); // D4 PlayNote(294, LEN); // D4 PlayNote(392, LEN); // G4 PlayNote(392, LEN); // G4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(392, LEN); // G4 PlayNote(392, LEN); // G4 PlayNote(494, LEN); // B4 PlayNote(392, LEN); // G4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(330, LEN); // E4 PlayNote(330, LEN); // E4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(523, LEN); // C5 PlayNote(523, LEN); // C5 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(440, LEN); // A4 PlayNote(440, LEN); // A4 PlayNote(494, LEN); // B4 PlayNote(494, LEN); // B4 PlayNote(349, LEN); // F4 PlayNote(349, LEN); // F4 PlayNote(262, LEN); // C4 PlayNote(262, LEN); // C4 PlayNote(349, LEN); // F4 PlayNote(349, LEN); // F4 PlayNote(392, LEN); // G4 PlayNote(392, LEN); // G4 PlayNote(440, LEN + (LEN / 8)); // A4 PlayNote(440, LEN + (LEN / 7)); // A4 PlayNote(392, LEN + (LEN / 6)); // G4 PlayNote(392, LEN + (LEN / 5)); // G4 PlayNote(349, LEN + (LEN / 4)); // F4 PlayNote(349, LEN + (LEN / 3)); // F4 PlayNote(440, LEN + (LEN / 2)); // A4 PlayNote(349, LEN * 4); // F4 #else PlayNote(466, LEN); // A#4 PlayNote(622, LEN); // D#5 PlayNote(784, LEN); // G5 PlayNote(932, LEN * 2); // A#5 PlayNote(784, LEN); // G5 PlayNote(932, LEN * 3); // A#5 #endif return 0; }