bcrowell2 has asked for the wisdom of the Perl Monks concerning the following question:

O monks,

I have a perl-gtk oscilloscope application that works just fine on my development machine. However, the first time I ran it on a different machine, I found that the Gtk buttons mysteriously were not drawn, although it seems as though clicking on them does have an effect. The following is a minimal example that demonstrates the problem. All of this is on linux (ubuntu 10.04 and 10.10). The sound input is done using OSS emulation, so if you're running a unix that doesn't have OSS emulation (e.g., ubuntu 10.10), you need to install the aoss utility (packaged in debian package alsa-oss), and run the program like so: "alsa foo" (where "foo" is the file containing the sample code). If you run it, you may or may not find that the button gets drawn.

#!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 -init; use IO::File; my $window = new Gtk2::Window ( "toplevel" ); $window->signal_connect ("delete_event", sub { Gtk2->main_quit; }); my $button = Gtk2::Button->new('foo'); $window->add($button); $window->show_all; my $dsp = new IO::File("</dev/dsp"); my $event_source_tag = Glib::IO->add_watch( fileno($dsp), 'in', sub { my $buff = " " x 1024; my $nread = read($dsp,$buff,1024); return 1; } ); Gtk2->main; exit(0);

Does anyone have any insight into what might be causing this problem and how to solve it? I'm at wit's end. Although it runs on the development machine, it has failed on three out of three other machines I tried it on. There doesn't seem to be any common denominator, e.g., the version of the OSS doesn't predict whether it will work or not.

Thanks in advance!

-Ben

Replies are listed 'Best First'.
Re: mysterious hardware/OSS/Gtk interaction?
by Khen1950fx (Canon) on Mar 11, 2011 at 07:40 UTC
    This should work better for you:
    #!/usr/bin/perl use strict; use warnings; use Gtk2 '-init'; my $mw = Gtk2::Window->new('toplevel'); my $t = Gtk2::Table->new(1, 2, 0); $mw->add($t); my $label = Gtk2::Label->new('Example'); $t->attach_defaults($label, 0, 1, 0, 1); $label->show; my $button = Gtk2::Button->new('foo'); $t->attach_defaults($button, 0, 1, 1, 2); $button->signal_connect( 'clicked' => sub { exit } ); $button->show; $mw->show_all; Gtk2->main; 0;

      Thanks for the replies, Khen1950fx and zentara!

      Khen1950fx, I think I didn't explain the problem clearly enough. The example I gave is truly a minimal example, in the sense that the sound I/O stuff is necessary in order to produce the buggy behavior. The problem is not that the "foo" button is small and hard to see, it's that it actually isn't rendered at all. If I take your code and put the sound I/O back in, I get this:

      #!/usr/bin/perl use strict; use warnings; use Gtk2 '-init'; use IO::File; my $mw = Gtk2::Window->new('toplevel'); my $t = Gtk2::Table->new(1, 2, 0); $mw->add($t); my $label = Gtk2::Label->new('Example'); $t->attach_defaults($label, 0, 1, 0, 1); $label->show; my $button = Gtk2::Button->new('foo'); $t->attach_defaults($button, 0, 1, 1, 2); $button->signal_connect( 'clicked' => sub { exit } ); $button->show; $mw->show_all; my $dsp = new IO::File("</dev/dsp"); my $event_source_tag = Glib::IO->add_watch( fileno($dsp), 'in', sub { my $buff = " " x 1024; my $nread = read($dsp,$buff,1024); return 1; } ); Gtk2->main; 0;

      This works on the same machine where my original example works, and fails on the same machine where my original example fails.

      Here is a rundown on which machines it works on and which it fails on:

      AMD Athlon 64 X2 4200+, Gigabyte GA-M61P-S3, onboard sound, Ubuntu 10.10 -- works

      Dell Optiplex GX260, 1.8 GHz P4, 512 Mb, 40 Gb, onboard sound, Ubuntu 10.04 -- fails

      Dell Optiplex GX260, 1.8 GHz P4, 512 Mb, 40 Gb, onboard sound, Ubuntu 10.10 -- fails

      Core 2 Duo E8400, 3 GHz, Gigabyte EP45-UD3P mobo, onboard sound, Ubuntu 10.04 -- fails

      HP, Ubuntu 10.10 -- fails

      I suspect that the problem has something to do with event handling in Gtk. Maybe the program gets overloaded with events and never gets a chance to draw the widget? But I don't understand why it's hardware-dependent, and I don't understand how to fix it :-(

        I suspect that the problem has something to do with event handling in Gtk. Maybe the program gets overloaded with events and never gets a chance to draw the widget? But I don't understand why it's hardware-dependent,

        You are thinking corectly. I notice it works on a newer 64 bit machine and fails on older, slower, 32 bit machines with minimum ram for Ubuntu ( 512 Mb).

        Also, you are going to find that io operations will block anything if they are hung. So the solution for you, is to put the /dev/dsp read io watch into a separate thread. See Threads-w-Perl/Gtk2 demo for a simplistic example.


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
        Good! I added Audio::DSP, and it works, provided that you give it a specfic file to read.
        #!/usr/bin/perl use strict; use warnings; use Gtk2 '-init'; use IO::File; use Audio::DSP; $|=1; my $mw = Gtk2::Window->new('toplevel'); my $t = Gtk2::Table->new(1, 2, 0); $mw->add($t); my $label = Gtk2::Label->new('Example'); $t->attach_defaults($label, 0, 1, 0, 1); $label->show; my $button = Gtk2::Button->new('foo'); $t->attach_defaults($button, 0, 1, 1, 2); $button->signal_connect( 'clicked' => sub { exit } ); $button->show; $mw->show_all; my $dsp = new IO::File("</dev/dsp"); my $event_source_tag = Glib::IO->add_watch( fileno($dsp), 'in', sub { my ($buf, $chan, $fmt, $rate) = (4096, 1, 8, 8192); $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(); for (my $i = 0; $i < $length; $i += $buf) { #records $dsp->read() || die $dsp->errstr(); for (;;) { #playback $dsp->write() || last; } $dsp->close(); } }); Gtk2->main; 0;
Re: mysterious hardware/OSS/Gtk interaction?
by zentara (Cardinal) on Mar 11, 2011 at 15:31 UTC
    Although it runs on the development machine, it has failed on three out of three other machines I tried it on. There doesn't seem to be any common denominator, e.g., the version of the OSS doesn't predict whether it will work or not.

    Your code runs fine here. From my accumulated zen wisdom in how this stuff goes down, whenever there seems to be odd issues where the very same code runs differently on other machines, it usually is some hardware difference.... maybe the io from the /dev/dsp is better from the /dev/dsp on some machines, and on others, the oss io is flawed and creates a bottleneck. Who knows? But the code you posted is valid, runs here fine, and what else can I say except check those differences in the kernel and software updates from Ubuntu 10.04 to 10.10, and see how they may affect your particular hardware. You don't even mention if the 2 machines have the same hardware... ie processor speed, ram, and soundcard.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      Thanks for the reply, zentara. I posted a list of hardware above. What hardware and OS are you running? Since the problem only occurs when I'm using sound, I guess the best option I can think of is something like this. Have the program fork itself. Fork A is responsible for reading sound input and storing the results in a circular buffer on disk. Fork B runs the GUI and only reads from the buffer file when needed. Does this seem like a reasonable plan?
        Does this seem like a reasonable plan?

        Yeah, forking is good, probably better than threads. The only time you really need threads is for "realtime" sharing of cross-thread data. Also depending on your buffer design, you may need some sort of file locking.

        But in that regards of timing, especially with sound, you may want to go with the fastest IPC possible, thru shared memory segments. Search for examples of IPC::SysV


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh