#25 add libao support

open
nobody
None
5
2007-05-07
2007-05-07
Anonymous
No

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.

Discussion

  • Nobody/Anonymous

    Logged In: NO

    P.S.: The plugin is selected by auto-detection, but it can be set by editing libao.conf or ~/.libao.

     
  • Nobody/Anonymous

    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);

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks