in reply to Re^4: sound and gamepad support in Perl?
in thread sound and gamepad support in Perl?
No problem, as I understood your original post to be asking for non-SDL solutions to gamepads and audio.
You don't need the Audio::DSP module to access the /dev/dsp, BUT to properly initialize the soundcard, to accept your audio as input, you need some system calls. Audio::DSP does this in code like
BUT, you can read Audio::DSP and see what system calls are required to init the soundcard manually, using h2ph. It is not simple, and involves various low level hex codes, using#!/usr/bin/perl use warnings; use strict; use Audio::DSP; #alsamixer must be setup right, just turn everything up :-) my ($buf, $chan, $fmt, $rate) = (4096, 1, 16, 44100); #use the formats from soundcard.h, plain 16 for $fmt might not work w +ith sblive #($buf, $chan, $fmt, $rate) = (4096, 1, 8, 8192); #crummy minimum soun +d my $dsp = new Audio::DSP( buffer => $buf, channels => $chan, format => $fmt, rate => $rate); my $seconds = 5; my $length = ($chan * $fmt * $rate * $seconds) / 8; $dsp->init() || die $dsp->errstr(); # Record 5 seconds of sound for (my $i = 0; $i < $length; $i += $buf) { $dsp->read() || die $dsp->errstr(); } print "Play Back\n"; # Play it back for (;;) { $dsp->write() || last; } $dsp->close();
Once inited, you can write to the /dev/dsp directly from Perl. This involves alot of work. Initing can also be done with a c app, like alsactl. But once inited, you can write directly to the /dev/dsprequire 'sys/ioctl.ph';
#!/usr/bin/perl my $file = shift || 'testout.wav'; open FH, "< $file" or warn "$!\n"; open(DSP,">/dev/dsp") or warn "$!\n"; while ( 4096 == read( FH, my $buffer, 4096 ) ) { print DSP $buffer; } #1liner #perl -e 'local $/;$w=<>;open(F,">","/dev/dsp") && print F $w;' dtmf.w +av
You can also use a "c" app like aplay, to play your sounds. Every time you want to make a sound, send the file to a forked aplay, with simple IPC.
As far as the gamepad goes, you really need an event-loop system, to take advantage of the input. SDL gives you this, but I would also look at the gtk+ libraries for it..... google for "gtk+ gamepad" for librairies.
That brings us back to the point of you trying to avoid SDL. First SDL gives you an eventloop system, it's audio access is way better than direct access to /dev/dsp, because it lets you access the soundcard's channels independently. See below, the cannons, explosions, and music all can be played simultaneously in different channels. ( Although aplay, probably has a command line option for which channel to play thru.)
The code and test files are at z-sampler
#!/usr/bin/perl use SDL; use SDL::Mixer; use SDL::Music; use SDL::App; use SDL::Event; $|++; $width=400; $height=300; my $app = new SDL::App( -title => "Sampler", -width => 400, -height =>300, -depth => 8); $mixer = SDL::Mixer->new(-frequency => MIX_DEFAULT_FREQUENCY, -format => MIX_DEFAULT_FORMAT, -channels => MIX_DEFAULT_CHANNELS, -size => 4096); # provides 8 channels of # 16 bit audio at 22050 Hz. and a single channel of music. my $music = new SDL::Music('1bb.mp3'); #background can be mp3,ogg or w +av my $sound0 = new SDL::Sound('cannon.wav'); #effects must be wav $sound0->volume(128); #max my $sound1 = new SDL::Sound('explosion.wav'); $sound1->volume(128); #max $mixer->music_volume(MIX_MAX_VOLUME); my $event = new SDL::Event; my %events = ( SDL_KEYUP() => sub { my ($e) = @_; my $key = SDL::GetKeyName($e->key_sym()); print "$key up\n"; if ($key eq 'm'){ $mixer->play_music($music,10)}; if ($key eq 'c'){ $mixer->play_channel(0,$sound0,0)}; if ($key eq 'e'){ $mixer->play_channel(1,$sound1,0)}; }, SDL_KEYDOWN() => sub { my ($e) = @_; if ($e->key_sym() == SDLK_ESCAPE){exit}; my $key = SDL::GetKeyName($e->key_sym()); print "$key down\n"; }, SDL_QUIT() => sub { exit }, ); $app->loop(\%events);
The "c" apps I'm talking about, are the various ones laying around for playing audio or possible controlling a gamepad or soundcard. See the use of the c app amixer in ztk-v4l-video-bloger/recorder for switching mic inputs. Perl is a great GLUE language. But you are far better off using SDL OR finding a gtk+ library for the gamepad, and see if SDL's usb support see's it. Otherwise, switch to gtk+ ( which can be converted to Perl/Gtk2) thru the gtk+ to Perl pathways.
So, you can do this all from straight Perl, but it is way more difficult than using modules. You will need an eventloop system, for the gamepad, so an alternative would be use the gtk+ gamepad libs, and a simple c app, like aplay, to make sounds.
Or go with SDL, and google for "SDL gamepad", use that code combined with my code above for audio.
Finally, if you want to reinvent the wheel, and not use modules, you can find the low-level ways of initing the soundcard and directly reading the gamepad input from it's usb file in /proc/input/gamepad ( or wherever )
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^6: sound and gamepad support in Perl?
by AGhoulDoingPerl (Sexton) on Jan 08, 2011 at 19:08 UTC |