Rakefile sound effects

Ruboids:

Suppose I wanted to play a WAV file each time any Rakefile tasks all
succeed, and play another one each time any task fails.

How could one add such a feature, portably between Linux and WinXP?

The two sub-questions are therefore:

  • what’s Ruby’s dirt-simple but portable sound library?

  • how to hook into the Rakefile task stack
    to intercept its results?

Long term, I will select choice samples from “Holy Grail”, such as “Ni!”
and
“Bad Zoot!” But that’s the easy part…

On 11/5/06, Phlip [email protected] wrote:

  • how to hook into the Rakefile task stack
    to intercept its results?

Long term, I will select choice samples from “Holy Grail”, such as “Ni!” and
“Bad Zoot!” But that’s the easy part…


Phlip
Redirecting... ← NOT a blog!!!

I suppose you can check the result code/errorlevel that rake returns,
but I haven’t verified this.

Hi,

Jan S. wrote:

I suppose you can check the result code/errorlevel that rake returns,
but I haven’t verified this.

Simple and portable:

rake && echo FINE || echo BAD

Replace echo with your command of choice… Although the command might
not
be portable…

Guillaume

Phlip wrote:

  • what’s Ruby’s dirt-simple but portable sound library?

For dirt-simple, bundle mplayer and shellout to it. Not exactly a
library, but probably simpler than anything more direct by far, and the
purpose you mention wouldn’t be worth more than the fastest hack I can
come up with anyway. Depends on how many computers you need this to run
on.

David V.

On 11/5/06, Phlip [email protected] wrote:

Ruboids:

Suppose I wanted to play a WAV file each time any Rakefile tasks all
succeed, and play another one each time any task fails.

… snip

  • what’s Ruby’s dirt-simple but portable sound library?

For windows it definitely doesn’t get any easier than win-32 sound:
http://raa.ruby-lang.org/project/win32-sound/

idk about Linux unfortunately,
-Harold

Harold H. wrote:

  • what’s Ruby’s dirt-simple but portable sound library?

For windows it definitely doesn’t get any easier than win-32 sound:
http://raa.ruby-lang.org/project/win32-sound/

idk about Linux unfortunately,
-Harold

Hi,

For Linux, here are a couple of suggestions:

  1. try 'cat’ing the WAV file to the sound device - maybe something like
    /dev/audio.
  2. Write the file’s contents to the device.

Do either of the above, from your Ruby code, is what I mean.

I don’t know or remember right now how to do the first - ‘cat’ a file,
i.e. Linux equivalent of the DOS TYPE command - from a Ruby
program. In Python it would be :

import os
os.system(“your_command_with_optional_arguments_here”)

This does the equivalent of the Linux library function called system -
a C code fragment showing how to use it:

char cmd = “cat filename.WAV”;
int rc;
rc = system(cmd);
if (rc == -1)
{
/
print error message */
}

A thought: it’s not always necessary or worth it to try and make the
code portable across OS’s - though a good idea in theory, sometimes the
effort may not be worth it. If you have a quick and easy way to do it
non-portably (i.e. using different pieces of code for Windows and
Linux), nothing wrong with using that approach. Just IMO, of course -
its your call, ultimately. Or, another way could be to write your own
thin wrapper method, with nothing OS-specific in its name or arguments,
and within that, detect the OS and call the appropriate OS-specific
code with in the two branches of an if-else statement, like:

def play_wav_file
if (Windows)
# Windows-specific code here
else # assuming no other OS except Linux
# Linux-specific code here
end
end

Replace the (Windows) in the if statement with some appropriate code to
detect the OS your Ruby program is running on. Again, don’t know or
remember how to do that in Ruby right now, there surely will be some
simple way.

HTH
Vasudev

Vasudev Ram
Dancing Bison Enterprises
Software consulting and training
http://www.dancingbison.com

vasudevram wrote:

  1. try 'cat’ing the WAV file to the sound device - maybe something like
    /dev/audio.
  2. Write the file’s contents to the device.

Do either of the above, from your Ruby code, is what I mean.

Except they won’t work. /dev/dsp and /dev/audio take only very specific
file formats, neither of which is .WAW.

I’m afraid multimedia handling is a nontrivial problem on any OS and
generally a mess. Windows has builtin support for .WAW, Linux for raw
PCM at 8kHz/8bit/mono (for dsp). Which means you’re probably still
dependent on some outside tool to transform your sound file into the
desired format. And you might as well use mplayer (my criterium for
choosing that one is that it’s console-based, comes with a Win32 build,
and is easy to bundle with an app, and Just Works)

A thought: it’s not always necessary or worth it to try and make the
code portable across OS’s - though a good idea in theory, sometimes the
effort may not be worth it. If you have a quick and easy way to do it
non-portably (i.e. using different pieces of code for Windows and
Linux), nothing wrong with using that approach.

Except that you have to do OS sniffing, sniffing for presence of support
you require (windows native .wav handling, DirectSound, OSS, ALSA), and
heavens forbid you want to support multiple source file formats.
Generally the problem is that per se, the OS portability is the least of
your concerns, it’s getting a framework that will handle the sound
format / output method issueswith minimal fuss. (To wit: if you’re using
a freeware / open-source video manipulation software, odds are it’s a
frontend to ffmpeg) If that framework is nonportable, you have to go on
and code against two. But in this specific case, since you pretty much
have to go on and get a preexisting sound playback solution anyway, you
might as well find one that won’t double your coding effort (even if
it’s hopefully a minimal one.) The issue here isn’t expending effort to
create a cross-platform solution, it’s saving it by reusing a
cross-platform solution.

David V.

Phlip wrote:

→ Ant does this out of the box ←
Does everyone understand the mandate now?? :wink:
Er… no, but I’ll try & help anyhoo.

10 seconds searching on RAA got me this:
http://raa.ruby-lang.org/project/ruby-audiere/

SourceForge seems to be down, so I couldn’t find out much about audiere,
but google says “For audio output, Audiere supports DirectSound or WinMM
in Windows, OSS on Linux and…”

So… yeah.

Devin

Ruboids:

I need to light a fire under this thread.

Firstly, the current solution is outside the Rakefile. That’s easy; you
just
collect the shell’s return value.

I want a solution inside the Rakefile. And I want Someone Else,
preferrably
a Ruby library, to take care of the ‘if’ statement that detects the
platform.

The current solution looks like this:

    got = system(command)  # <-- shells to rake

    sound  = if got
                      'drumloop.wav'
                  else
                      'jaguar.wav'
                  end

    weWin32 = RUBY_PLATFORM.include?('mswin32')

    if weWin32
        system('"C:\\Program Files\\Windows Media 

Player\mplayer2.exe"
/play /close s:\bin\’ + sound)
else
system(‘aplay ~/bin/’ + sound)
end

That sucks bigtime, for many various reasons. Windows is too awesome and
sophisticated to provide a true command-line solution; we are calling
‘system’, etc.

Now here’s the fire to light under this thread - the reason I want a
solution inside the Rakefile, and portable:

–> Ant does this out of the box <–

Does everyone understand the mandate now?? :wink:

Phlip wrote:

I want a solution inside the Rakefile. And I want Someone Else, preferrably
a Ruby library, to take care of the ‘if’ statement that detects the
platform.

Unfortunately, rake doesn’t seem to let you check for failure of
dependent tasks - if a task fails, all goes pear-shaped and the process
exits, that’s it. Short of a change to Rake to use for example a
TaskFailedError that Task#execute / Task#invoke would throw (HINT) you
could catch and rethrow, that just isn’t doable.

See below why platform sniffing isn’t quite necessary if you’re willing
to depend on a cross-platform media player.

    weWin32 = RUBY_PLATFORM.include?('mswin32')

‘system’, etc.

Windows, in its awesomeness and sophistication, has a unified way of
opening documents with their default handlers from the command line.

system(‘start s:\bin\#{sound}’) would’ve worked.

Provided mplayer.exe (or any other cross-platform media player program)
is on PATH:

If you registered mplayer as the default handler for .wav files (“ftype
soundrec=mplayer %1”), this would work without opening an unsightly
window.

Please refrain flaming at the Windows command line when it’s in fact
your ignorance of how it actually works showing. It’s sad to look at and
all. I’m not saying there isn’t anything to flame about either Windows
or its command line, but this isn’t it - both Windows and Linux will
launch a program on PATH, the only difference is that with the Linux
directory structure, usually all software on your computer will be in
PATH already by convention.

Of course, if mplayer.exe is on PATH on your Windows box, and also on
your Linux box, provided you can find the .wav file you want to play
using a pathname relative to some parameter accessible at runtime (the
script location), you don’t need any OS sniffing whatsoever. As of
Windows XP, system() will happily accept any combination of forward or
backward slashes in the filename whatsoever. Which means the script will
work cross-platform. As for the system() call, I’m afraid there’s very
little you can do. To my best knowledge, there just is no in-process
audio framework with a Ruby binding that comes with anything close to an
installation method requiring less effort than getting the sound to play
is worth.

Now here’s the fire to light under this thread - the reason I want a
solution inside the Rakefile, and portable:

–> Ant does this out of the box <–

java.sound being around since 2001, I’m somehow not surprised. The Ruby
standard library having… well… no multimedia support whatsoever, I’m
not surprised Rake doesn’t.

David V.

From: “Phlip” [email protected]

   sound  = if got
   else
       system('aplay ~/bin/' + sound)
   end

Could play win32 sounds like this, assuming .wav files:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/55423

(Assuming you didn’t want to have a dependency on win32-sound
library.)

Regards,

Bill

Phlip wrote:

  • how to hook into the Rakefile task stack
    to intercept its results?

Long term, I will select choice samples from “Holy Grail”, such as “Ni!” and
“Bad Zoot!” But that’s the easy part…

maybe with bundled (parts of) sdl - but then you would need to offer
dlls/sos for multiple platforms.

what about pc-speaker? any interface to that existing in ruby?