add libao support
Brought to you by:
bergo
libao is an audio library with support for OSS, ALSA, aRts, ESD, etc. sound outputs. This patch adds support for outputing sound via libao to eboard.
Notes:
1. Someone with dgt should check that the change to link_check() in configure doesn't break it (it shouldn't).
2. The ALSA/OSS libao plugins don't output the "ICS challenge" sound completely cleanly.
libao patch
Logged In: NO
P.S.: The plugin is selected by auto-detection, but it can be set by editing libao.conf or ~/.libao.
Logged In: NO
This patch applies to 1.0.4 (only difference from previous patch is configure):
--- configure 2007-05-24 16:20:19.589966963 +0300
+++ configure 2007-05-24 16:36:43.245904082 +0300
@@ -14,6 +14,7 @@
my $nls = 1;
my $dataprefix = '';
my $manprefix = '';
+my $libao = 0;
#my $dgt = 1;
# ------------
@@ -23,7 +24,7 @@
sub cplusplus_lang;
sub install_util;
sub header_check;
-#sub link_check;
+sub link_check;
sub header_def;
sub macro_check;
sub spaces;
@@ -45,6 +46,7 @@
print "\t--enable-debug compile with gdb debugging info\n";
print "\t--disable-nls disable translation support\n";
# print "\t--disable-dgt disable DGT board support\n";
+ print "\t--enable-libao output sound via libao\n";
print "\t--compiler=prog use alternative compiler (default: g++)\n";
print "\t--extra-inc=list additional include file search paths, separated by :\n";
print "\t--extra-ld=list additional library search paths, separated by :\n";
@@ -298,30 +300,30 @@
print CONFIGH "#undef $macro\n";
}
-#sub link_check {
-# my ($lib,$func,$inc) = @_;
-# my $result;
-
-# print "library verification: $func in $lib: ";
-
-# if (!open(TESTCC,">test.cc")) {
-# print "cannot write test program, FAIL\n";
-# return 0;
-# }
-# print TESTCC "$inc\n";
-# print TESTCC "int main(int argc, char **argv) {\n";
-# print TESTCC "$func;\n}\n\n";
-# close TESTCC;
-# if (run_cmd($cxx,@cxxflags,@ldflags,"test.cc","-o","xxtest","-ldgtnix","-lpthread") == 0) {
-# print "ok\n";
-# $result = 1;
-# } else {
-# print "FAIL\n";
-# $result = 0;
-# }
-# unlink("test.cc","xxtest");
-# return $result;
-#}
+sub link_check {
+ my ($lib,$func,$inc,$link) = @_;
+ my $result;
+
+ print "library verification: $func in $lib: ";
+
+ if (!open(TESTCC,">test.cc")) {
+ print "cannot write test program, FAIL\n";
+ return 0;
+ }
+ print TESTCC "$inc\n";
+ print TESTCC "int main(int argc, char **argv) {\n";
+ print TESTCC "$func;\n}\n\n";
+ close TESTCC;
+ if (run_cmd($cxx,@cxxflags,@ldflags,"test.cc","-o","xxtest",$link) == 0) {
+ print "ok\n";
+ $result = 1;
+ } else {
+ print "FAIL\n";
+ $result = 0;
+ }
+ unlink("test.cc","xxtest");
+ return $result;
+}
sub header_check {
my $x,$y,$fail=0,$z,$bsdbug;
@@ -439,6 +441,10 @@
# $dgt = 0;
# next;
# }
+ if ($_ eq '--enable-libao') {
+ $libao = 1;
+ next;
+ }
if (/--compiler=(.*)/) {
$cxx = $1;
next;
@@ -641,6 +647,19 @@
# }
#}
+# libao library
+if ($libao!=0) {
+ $libao=0 if (!header_check(<ao/ao.h>));
+ $libao=0 if (($libao!=0) && (!link_check("ao","ao_default_driver_id()","#include <ao/ao.h>","-lao")));
+ if ($libao==0) {
+ print "** libao not found, eboard will not output sound via libao.\n";
+ print CONFIGH "#undef LIBAO_DRIVER\n";
+ } else {
+ push @ldflags, "-lao";
+ print CONFIGH "#define LIBAO_DRIVER 1\n";
+ }
+}
+
# end
--- sound.cc 2007-05-23 21:57:45.000000000 +0300
+++ sound.cc 2007-05-24 16:17:37.939627735 +0300
@@ -47,7 +47,11 @@
#define SOME_DRIVER 1
-#ifdef HAVE_SYS_SOUNDCARD_H
+#ifdef LIBAO_DRIVER
+#include <ao/ao.h>
+static short initalized = 0;
+
+#elif defined HAVE_SYS_SOUNDCARD_H
#define OSS_DRIVER 1
#include <sys/soundcard.h>
@@ -75,8 +79,13 @@
Duration=250;
Count=1;
strcpy(Device,"/dev/dsp");
- ExtraData[0]=0;
+ ExtraData[0]='\0';
enabled = true;
+#ifdef LIBAO_DRIVER
+ if (initalized == 0) ao_initialize();
+ if ((id = ao_default_driver_id()) == -1) enabled = false;
+ initalized = 1;
+#endif /* LIBAO_DRIVER */
}
SoundEvent SoundEvent::operator=(SoundEvent &se) {
@@ -85,6 +94,9 @@
Duration=se.Duration;
Count=se.Count;
enabled = se.enabled;
+#ifdef LIBAO_DRIVER
+ id = se.id;
+#endif
strcpy(Device,se.Device);
strcpy(ExtraData,se.ExtraData);
return(*this);
@@ -96,6 +108,9 @@
if (Pitch!=se.Pitch) return 0;
if (Duration!=se.Duration) return 0;
if (Count!=se.Count) return 0;
+#ifdef LIBAO_DRIVER
+ if (id!=se.id) return 0;
+#endif
if (strcmp(Device,se.Device)) return 0;
if (strcmp(ExtraData,se.ExtraData)) return 0;
return 1;
@@ -217,31 +232,43 @@
}
void SoundEvent::sine_beep(char *device,int pitch,int duration) {
-#ifdef SOME_DRIVER
int rate=11025; // Hz
int interval;
unsigned char *wave;
- int bl,fd,i,ts;
+ int bl,i,ts;
double r,s;
-#endif // SOME
+
+#ifdef LIBAO_DRIVER
+ struct ao_sample_format ao_format;
+ struct ao_device *ao_d;
+
+ if (id == -1) return;
+ ao_format.bits = 8;
+ ao_format.rate = rate;
+ ao_format.channels = 1;
+ ao_format.byte_format = AO_FMT_NATIVE; // ignored because fmt->bits = 8
+#else
+ int fd;
+#endif // LIBAO_DRIVER
#ifdef OSS_DRIVER
int format=AFMT_U8;
int channels=1;
-#endif
+#endif // OSS_DRIVER
#ifdef OPENBSD_DRIVER
audio_info_t ai;
#endif // OPENBSD
-#ifdef SOME_DRIVER
+#ifndef SOME_DRIVER
+ return;
+#endif // !SOME
+
interval=120*rate/1000; // 120 msec
wave=(unsigned char *)malloc(ts = (Count*(bl=(rate*duration)/1000) + (Count-1)*interval) );
-
- if (!wave)
- return;
+ if (!wave) return;
memset(wave,127,ts);
for(i=0;i<bl;i++) {
@@ -252,15 +279,24 @@
s/=(double)bl;
s=0.30+sin(M_PI*s)*0.70;
wave[i]=(unsigned char)(128.0+127.0*s*sin(M_PI*2.0*r));
+#ifdef LIBAO_DRIVER
+ if (id != 0) wave[i] -= 128;
+ // Most of libao's plugins expect signed input. The arts plugin (id==0)
+ // is an exception. The Mac OSX plugin (untested) also has id==0.
+#endif
}
for(i=1;i<Count;i++)
memcpy(wave+i*(bl+interval),wave,bl);
+#ifndef LIBAO_DRIVER
fd=open(device,O_WRONLY);
if (fd<0)
goto leave2;
-#endif // SOME
+#else
+ ao_d=ao_open_live(id, &ao_format, NULL);
+ if (ao_d == NULL) goto leave2;
+#endif // !LIBAO_DRIVER
#ifdef OSS_DRIVER
if (ioctl(fd,SNDCTL_DSP_SETFMT,&format)==-1)
@@ -284,10 +320,12 @@
goto leave1;
#endif // OPENBSD
-#ifdef SOME_DRIVER
+#ifndef LIBAO_DRIVER
for(i=0;i<ts;)
i+=::write(fd,&wave[i],ts-i);
-#endif // SOME
+#else
+ ao_play(ao_d, (char *)wave, (guint32)ts);
+#endif // !LIBAO_DRIVER
#ifdef OSS_DRIVER
ioctl(fd,SNDCTL_DSP_POST,0);
@@ -297,13 +335,14 @@
ioctl(fd,AUDIO_DRAIN,0);
#endif // OPENBSD
-#ifdef SOME_DRIVER
leave1:
+#ifndef LIBAO_DRIVER
close(fd);
+#else
+ ao_close(ao_d);
+#endif // !LIBAO_DRIVER
leave2:
free(wave);
-#endif // SOME
-
}
char *SoundEvent::getDescription() {
@@ -618,6 +657,9 @@
global.debug("SoundSlave","kill");
if (!pid)
return;
+#ifdef LIBAO_DRIVER
+ ao_shutdown();
+#endif
::kill((pid_t)pid,SIGKILL);
close(sout[0]);
close(sout[1]);
--- sound.h 2007-05-23 21:57:45.000000000 +0300
+++ sound.h 2007-05-24 16:17:37.940627583 +0300
@@ -69,6 +69,9 @@
char Device[64];
char ExtraData[256];
bool enabled;
+#ifdef LIBAO_DRIVER
+ int id;
+#endif
private:
void sine_beep(char *device,int pitch,int duration);