Shallow Thoughts : : laptop

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Fri, 30 Oct 2015

HDMI presentation setup on Linux, Part II: problems and tips

In Part I of HDMI Presentation Setup on Linux, I covered the basics of getting video and audio working over HDMI. Now I want to cover some finer-grained details: some problems I had, and ways to make it easier to enable HDMI when you need it.

Testing follies, delays, and screen blinking/flashing woes

While I was initially trying to get this working, I was using my own short sound clip (one of the alerts I use for IRC) and it wasn't working. Then I tried the test I showed in part I, $ aplay -D plughw:0,3 /usr/share/sounds/alsa/Front_Center.wav and that worked fine. Tried my sound clip again -- nothing. I noticed that my clip was mono and 8-bit while the ALSA sample was stereo and 16-bit, and I wasted a lot of time in web searches on why HDMI would play one and not the other.

Eventually I figured out that the reason my short clip wasn't playing was that there's a delay when switching on HDMI sound, and the first second two two of any audio may be skipped. I found lots of complaints about people missing the first few seconds of sound over HDMI, so this problem is quite common, and I haven't found a solution.

So if you're giving a talk where you need to play short clips -- for instance, a talk on bird calls -- be aware of this. I'm probably going to make a clip of a few seconds of silence, so I can play silence before every short clip to make sure I'm fully switched over to HDMI before the clip starts: aplay -D plughw:0,3 silence.wav osprey.wav

Another problem, probably related, when first starting an audio file: the screen blinks brieftly off then on again, then blinks again a little while after the clip ends. ("Flicker" turns out to be a better term to use when web searching, though I just see a single blink, not continued flickering). It's possible this is something about my home TV, and I will have to try it with another monitor somewhere to see if it's universal. It sounds like kernel bug 51421: Enabling HDMI sound makes HDMI video flicker, but that bug was marked resolved in 2012 and I'm seeing this in 2015 on Debian Jessie.

Making HDMI the sound default

What a pain, to have to remember to add -D plughw:0,3 every time you play a sound. And what do you do for other programs that don't have that argument?

Fortunately, you can make HDMI your default sound output. Create a file in your home directory called .asoundrc with this in it (you may be able to edit this down -- I didn't try) and then all audio will go to HDMI:

pcm.dmixer {
  type dmix
  ipc_key 1024
  ipc_key_add_uid false
  ipc_perm 0660
  slave {
    pcm "hw:0,3"
    rate 48000
    channels 2
    period_time 0
    period_size 1024
    buffer_time 0
    buffer_size 4096
  }
}
 
pcm. !default {
  type plug
  slave.pcm "dmixer"
}

Great! But what about after you disconnect? Audio will still be going to HDMI ... in other words, nowhere. So rename that file:

$ mv .asoundrc asoundrc-hdmi
Then when you connect to HDMI, you can copy it back:
$ cp asoundrc-hdmi .asoundrc 

What a pain, you say again! This should happen automatically!

That's possible, but tricky: you have to set up udev rules and scripts. See this Arch Linux discussion on HDMI audio output switching automatically for the gory details. I haven't bothered, since this is something I'll do only rarely, when I want to give one of those multimedia presentations I sometimes contemplate but never actually give. So for me, it's not worth fighting with udev when, by the time I actually need HDMI audio, the udev syntax probably will have changed again.

Aliases to make switching easy

But when I finally do break down and design a multimedia presentation, I'm not going to be wanting to do all this fiddling in the presentation room right before the talk. I want to set up aliases to make it easy.

There are two things that need to be done in that case: make HDMI output the default, and make sure it's unmuted.

Muting can be done automatically with amixer. First run amixer with no arguments to find out the channel name (it gives a lot of output, but look through the "Simple mixer control" lines, or speed that up with amixer | grep control.

Once you know the channel name (IEC958 on my laptop), you can run: amixer sset IEC958 unmute The rest of the alias is just shell hackery to create a file called .asoundrc with the right stuff in it, and saving .asoundrc before overwriting it. My alias in .zshrc is set up so that I can say hdmisound on or hdmisound off (with no arguments, it assumes on), and it looks like this:

# Send all audio output to HDMI.
# Usage: hdmisound [on|off], default is on.
hdmisound() {
    if [[ $1 == 'off' ]]; then
        if [[ -f ~/.asoundrc ]]; then
            mv ~/.asoundrc ~/.asoundrc.hdmi
        fi
        amixer sset IEC958 mmute
    else
        if [[ -f ~/.asoundrc ]]; then
            mv ~/.asoundrc ~/.asoundrc.nohdmi
        fi
        cat >> ~/.asoundrc <<EOF
pcm.dmixer {
  type dmix
  ipc_key 1024
  ipc_key_add_uid false
  ipc_perm 0660
  slave {
    pcm "hw:0,3"
    rate 48000
    channels 2
    period_time 0
    period_size 1024
    buffer_time 0
    buffer_size 4096
  }
}
 
pcm. !default {
  type plug
  slave.pcm "dmixer"
}
EOF
        amixer sset IEC958 unmute
    fi
}

Of course, I could put all that .asoundrc content into a file and just copy/rename it each time. But then I have another file I need to make sure is in place on every laptop; I decided I'd rather make the alias self-contained in my .zshrc.

Tags: , ,
[ 11:57 Oct 30, 2015    More linux/laptop | permalink to this entry | comments ]

Tue, 27 Oct 2015

HDMI presentation setup on Linux, video and audio: Part I

For about a decade now I've been happily connecting to projectors to give talks. xrandr --output VGA1 --mode 1024x768 switches on the laptop's external VGA port, and xrandr --auto turns it off again after I'm disconnected. No fuss.

But increasingly, local venues are eschewing video projectors and instead using big-screen TVs, some of which offer only an HDMI port, no VGA. I thought I'd better figure out how to present a talk over HDMI now, so I'll be ready when I need to know.

Fortunately, my newest laptop does have an HDMI port. But in case it ever goes on the fritz and I have to use an older laptop, I discovered you can buy VGA to HDMI adaptors rather cheaply (about $10) on ebay. I bought one of those, tested it on my TV at home and it at least worked there. Be careful when shopping: you want to make sure you're getting something that takes VGA in and outputs HDMI, rather than the reverse. Ebay descriptions aren't always 100% clear on that, but if you check the gender of the connector in the photo and make sure it's right to plug into the socket on your laptop, you should be all right.

Once you're plugged in (whether via an adaptor, or native HDMI built into your laptop), connecting is easy, just like connecting with VGA:

xrandr --output HDMI1 --mode 1024x768

Of course, you can modify the resolution as you see fit. I plan to continue to design my presentations for a 1024x768 resolution for the forseeable future. Since my laptop is 1366x1024, I can use the remaining 342-pixel-wide swath for my speaker notes and leave them invisible to the audience.

But for GIMP presentations, I'll probably want to use the full width of my laptop screen. --mode 1366x768 didn't work -- that resolution wasn't available -- but running xrandr with no arguments got me a list of available resolutions, which included 1360x768. That worked fine and is what I'll use for GIMP talks and other live demos where I want more screen space.

Sound over HDMI

My Toastmasters club had a tech session where a few of us tried out the new monitor in our meeting room to make sure we could use it. One person was playing a video with sound. I've never used sound in a talk, but I've always wanted to find an excuse to try it. Alas, it didn't "just work" -- xrandr's video settings have nothing to do with ALSA's audio settings. So I had to wait until I got home so I could do web searches and piece together the answer.

First, run aplay -l , which should show something like this:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: STAC92xx Analog [STAC92xx Analog]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Find the device number for the HDMI device, which I've highlighted here: in this case, it's 3 (which seems to be common on Intel chipsets).

Now you can run a test:

$ aplay -D plughw:0,3 /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
If you don't hear anything, don't worry: the HDMI channel is probably muted if you've never used it before. Run either alsamixer or alsamixergui.

[alsamixergui with HDMI muted] [alsamixer] Now find the channel representing your HDMI connection. (HDMI must be plugged in for this to work.) In alsamixer, it's called S/PDIF; in alsamixergui, it's called IEC958. If you look up either of those terms, Wikipedia S/PDIF will tell you that S/PDIF is the Sony/Philips Digital Interconnect Format, a data protocol and a set of physical specifications. Those physical specifications appear to have nothing to do with video, and use connectors that are nothing like HDMI. So it doesn't make much sense. Just remember that if you see IEC958 or S/PDIF in ALSA, that's probably your HDMI channel.

In the alsamixergui screenshot, IEC958 is muted: you can tell because the little speaker icon at the top of the column is bright white. If it were unmuted, the speaker icon would be grey like most of the others. Yes, this seems backward. It's Linux audio: get used to obscure user interfaces.

In the alsamixer screenshot, the mutes are at the bottom of each column, and MM indicates a channel is muted (like the Beep channel in the screenshot). S/PDIF is not muted here, though it appears to be at zero volume. (The 00 doesn't tell you it's at zero volume; 00 means it's not muted. What did I say about Linux audio?) ALSA apparently doesn't let you adjust the volume of HDMI output: presumably they expect that your HDMI monitor will have its own volume control. If your S/PDIF is muted, you can use your right-arrow key to arrow over to the S/PDIF channel, then type m to toggle muting. You can exit alsamixer with Ctrl-C (Q and Ctrl-Q don't work).

Now try that aplay -D command again and see if it works. With any luck, it will (loudly).

A couple of other tests you might want to try:
speaker-test -t sine -f 440 -c 2 -s 1 -D hw:0,3
plays a sine wave. speaker-test -c 2 -r 48000 -D hw:0,3
runs a general speaker test sequence.

In Part II of Linux HDMI Presentations, I'll cover some problems I had, and how to write an alias to make it easy to turn HDMI audio on and off.

Tags: , ,
[ 14:36 Oct 27, 2015    More linux/laptop | permalink to this entry | comments ]

Mon, 04 Mar 2013

How to enable/disable laptop wireless hardware

My Lenovo laptop has a nifty button, Fn-F5, to toggle wi-fi and bluetooth on and off. Works fine, and the indicator lights (of which the Lenovo has many -- it's quite nice that way) obligingly go off or on.

But when I suspend and resume, the settings aren't remembered. The machine always comes up with wireless active, even if it wasn't before suspending.

Since wireless can be a drain on battery life, as well as a potential security issue, I don't want it on when I'm not actually using it. So I wanted a way to turn it off programmatically.

The answer, it turns out, is rfkill.

$ rfkill list
0: tpacpi_bluetooth_sw: Bluetooth
        Soft blocked: yes
        Hard blocked: no
0: phy0: Wireless LAN
        Soft blocked: yes
        Hard blocked: no
tells you what hardware is currently enabled or disabled.

To toggle something off,

$ rfkill block bluetooth
$ rfkill block wifi

Type rfkill -h for more details on arguments you can use.

Fn-F5 still works to enable or disable them together. I think this is being controlled by /etc/acpi/ibm-wireless.sh, though I can't find where it's tied to Fn-F5.

You can make it automatic by creating /etc/pm/sleep.d/. (That's on Ubuntu; of course, the exact file location may vary with distro and version.) To disable wireless on resume, do this:

#! /bin/sh

case "$1" in
  resume)
    rfkill block bluetooth
    rfkill block wifi
    ;;
esac
exit $?

Of course, you can also tie that into other things, like your current network scheme, or what wireless networks are visible (which you can get with iwlist wlan0 scan).

Tags: , , ,
[ 19:46 Mar 04, 2013    More linux/laptop | permalink to this entry | comments ]

Mon, 31 Oct 2011

Synaptics horizontal scrolling (and other touchpad configurations)

My new netbook (about which, more later) has a trackpad with areas set aside for both vertical and horizontal scrolling. Vertical scrolling worked out of the box on Squeeze without needing any extra fiddling. My old Vaio had that too, and I loved it.

Horizontal scrolling took some extra research. I was able to turn it on with a command:

synclient HorizEdgeScroll=1
(thank you, AbsolutelyTech). Then it worked fine, for the duration of that session.

But it took a lot more searching to find out the right place to set it permanently. Nearly every page you find on trackpad settings tells you to edit /etc/X11/xorg.conf. Distros haven't normally used xorg.conf in over three years! Sure, you can generate one, then edit it -- but surely there's a better way.

And there is. At least in Debian Squeeze and Ubuntu Natty, you can edit /usr/share/X11/xorg.conf.d/50-synaptics.conf and add this options line inside the "InputClass" section:

        options "HorizEdgeScroll" "1"
Don't forget the quotes, or X won't even start.

In theory, you can use this for any of the Synaptics driver options -- tap rate and sensitivity, even multitouch. Your mileage may vary -- horizontal scroll is the only one I've tested so far. But at least it's easier than generating and maintaining an xorg.conf file!

Tags: , ,
[ 16:20 Oct 31, 2011    More linux/laptop | permalink to this entry | comments ]

Sat, 27 Aug 2011

Vaio tips for Debian Squeeze

I switched to the current Debian release, "Squeeze", quite a few months ago on my Sony Vaio laptop. I've found that Squeeze, with its older kernel and good attention to power management (compared to the power management regressions in more recent kernels), gets much better battery life than either Arch Linux or Ubuntu on this machine. I'm using Squeeze as the primary OS at least until the other distros get their kernel power management sorted out.

I did have to solve a couple of minor problems when switching over, though.

Suspend/Resume quirks

The first problem was that my Vaio TX650 would freeze on resuming from suspend -- something that every other Linux distro has handled out of the box on this machine.

The solution turned out to be simple though non-obvious, apparently a problem with controlling power to the display:

sudo pm-suspend --quirk-dpms-on

That wasn't easy to find, but ever since then the machine has been suspending without a single glitch. And it's a true suspend, unlike Ubuntu Natty, which on this machine will use up a full battery if I leave it suspended all day -- Natty uses nearly as much power when suspended as it does running.

Adjusting screen brightness: debugging ACPI

Of course, once I got that sorted out, there were the usual collection of little changes I needed to make. Number one was that it didn't automatically handle brightness adjustment with the Fn-F5 and Fn-F6 keys.

It turned out my previous technique for handling the brightness keys didn't work, because the names of the ACPI events in /etc/acpi/events had changed. Previously, /etc/acpi/events/sony-brightness-down had contained references to the Sony I/O Control, or SPIC:

event=sony/hotkey SPIC 00000001 00000010
action=/etc/acpi/sonybright.sh down
That device didn't exist on Squeeze. To find out what I needed now, I ran acpi-listen and typed the function-key combos in question. That gave me the codes I needed. I changed the sony-brightness-down file to read:
event=video/brightnessdown BRTDN 00000087 00000000
action=/etc/acpi/sonybright.sh down

It's probably a good thing, changing to be less Sony-specific ... but as a user it's one of those niggling annoyances that I have to go chase down every time I upgrade to a new Linux version.

Tags: , , , , ,
[ 12:07 Aug 27, 2011    More linux/laptop | permalink to this entry | comments ]

Mon, 13 Sep 2010

Of Laptops, Docking Stations and Changing Resolution

I've been setting up a new Lenovo X201 laptop at work. (Yes, work -- I've somehow fallen into an actual job where I go in to an actual office at least some of the time. How novel!)

At the office I have a Lenovo docking station, attached to a monitor and keyboard. The monitor, naturally, has a different resolution from the laptop's own monitor.

Under Gnome and compiz, when I plugged in the monitor, I could either let the monitor mirror the laptop display -- in which case X would refuse to work at greater than 1024x768, much smaller than the native resolution of either the laptop screen or the external monitor -- or I could call up the classic two-monitor configuration dialog, where I could configure the external monitor to be its correct size and sit alongside the computer's monitor. I had to do this every time I plugged in.

If I wanted to work on the big screen, then when I undocked, I had to drag all the windows on all desktops back to the built-in LCD first, or they'd be lost. Using just the external monitor and turning off the laptop screen didn't seem to be an allowed option.

That all lasted for about two days. Gnome and I just don't get along. Pretty soon gdm was mysteriously refusing to let me log in (probably didn't like my under-1000 user id), and after wasting half a day fighting it I gave up and reverted with relief to my familiar Openbox desktop.

But now I'm in the Openbox world and don't have that dialog anyway. What are my options?

xrandr monitor detection

Fortunately, I already knew about using xrandr to send to a projector; it was only a little more complicated using it for the monitor in the docking station. Running xrandr with no arguments prints all the displays it currently sees, so you can tell whether an external display or projector is connected and even what resolutions it supports.

I used that for a code snippet in my .xinitrc:

# Check whether the external monitor is connected: returns 0 on success
xrandr | grep VGA | grep " connected "
if [ $? -eq 0 ]; then
  xrandr --output VGA1 --mode 1600x900;
  xrandr --output LVDS1 --off
else
  xrandr --output VGA1 --off
  xrandr --output LVDS1 --mode 1280x800
fi

That worked nicely. When I start X it checks for an external monitor, and if it finds one it turns off the laptop display (so it's off when the laptop is sitting closed in the docking station) and sets the screen size for the external monitor.

Making it automatic

All well and good. I worked happily all day in the docking station, suspended the laptop and un-docked it, brought it home, woke it up -- and of course the display was still off. Oops.

Okay, so it also needs the same check when resuming from suspend. That used to be in /etc/acpi/resume.d, but in Lucid they've moved it (because we definitely wouldn't want users to get complacent and think they know how to configure things!) and now it lives in /etc/pm/sleep.d. I created a new file, /etc/pm/sleep.d/20_enable_display which looks like this:

#!/bin/sh

case "$1" in
    resume)
        # Check whether the external monitor is connected:
        # returns 0 on success
        xrandr | grep VGA | grep " connected "
        if [ $? -eq 0 ]; then
            xrandr --output VGA1 --mode 1600x900
            xrandr --output LVDS1 --off
        else
            xrandr --output VGA1 --off
            xrandr --output LVDS1 --mode 1280x800
        fi
        hsetroot -center `find -L $HOME/Backgrounds -name "*.*" | $HOME/bin/randomline`

        ;;
    suspend|hibernate)
        ;;
    *)
        ;;
esac
exit $?

Neat! Now, every time I wake from suspend, the laptop checks whether an external monitor is connected and sets the resolution accordingly. And it re-sets the background (using my random wallpaper method) so I don't get a tiled background on the big monitor.

Update: hsetroot -fill works better than -center given that I'm displaying background images on two different resolutions. Of course, if I wanted to get fancy I could make separate background sets, one for each monitor, and choose images from the appropriate set.

We're almost done. Two more possible adjustments.

Detecting undocking

First, while poking around in /etc/acpi I noticed a script named undock.sh. In theory, I can put the same code snippet in there, and then if I un-dock the laptop without suspending it first, it will immediately change resolution. I haven't actually tried that yet.

Projectors

Second, this business of turning off the built-in display if there's anything plugged into the VGA port is going to break if I use this laptop for presentations, since a projector will also show up as VGA1. So the code may need to be a little smarter. For example:

xrandr | grep VGA | grep " connected " | grep 16.0x

The theory here is that an external monitor will be able to do 1680 or 1600, so it will have a line like VGA1 connected 1680x1050+0+0 (normal left inverted right x axis y axis) 434mm x 270mm. The 1680x matches the 16.0x pattern in grep. A projector isn't likely to do more than 1280, so it won't match the pattern '16.0x'. However, that isn't very robust; it will probably fail for one of those fancy new 1920x1080 monitors. You could extend it with

xrandr | grep VGA | grep " connected " | egrep '16.0x|19.0x'
but that's getting even more hacky ... and it might be time to start writing some more intelligent code.

Which doubtless I'll do if I ever get a 1920x1080 monitor.

Tags: , ,
[ 23:11 Sep 13, 2010    More linux/laptop | permalink to this entry | comments ]

Fri, 27 Feb 2009

Updated Network Schemes page

I've used my simple network schemes setup for many years. No worries about how distros come up with a new network configuration GUI every release; no worries about all the bloat that NetworkManager insists on before it will run; no extra daemons running all the time polling my net just in case I might want to switch networks suddenly. It's all command-line based; if I'm at home, I type
netscheme home
and my network will be configured for that setup until I tell it otherwise. If I go to a cafe with an open wi-fi link, I type netscheme wifi; I have other schemes for places I go where I need a wireless essid or WEP key. It's all very easy and fast.

Last week for SCALE I decided it was silly to have to su and create a new scheme file for conferences where all I really needed was the name of the network (the essid), so I added a quick hack to my netscheme script so that typing netscheme foo, where there's no existing scheme by that name, will switch to a scheme using foo as the essid. Worked nicely, and that inspired me to update the "documentation".

I wrote an elaborate page on my network schemes back around 2003, but of course it's all changed since then and I haven't done much toward updating the page. So I've rewritten it completely, taking out most of the old cruft that doesn't seem to apply any more. It's here: Howto Set Up Multiple Network Schemes on a Linux Laptop.

Tags: , ,
[ 10:51 Feb 27, 2009    More linux/laptop | permalink to this entry | comments ]

Fri, 06 Feb 2009

Widescreen laptop for presentations

I've written before about how I'd like to get a netbook like an Asus Eee, except that the screen resolution puts me off: no one makes a netbook with vertical resolution of more than 600. Since most projectors prefer 1024x768, I'm wary of buying a laptop that can't display that resolution.

(What was wrong with my beloved old Vaio? Nothing, really, except that the continued march of software bloat means that a machine that can't use more than 256M RAM is hurting when trying to run programs (*cough* Firefox *cough) that start life by grabbing about 90M and goes steadily up from there. I can find lightweight alternatives for nearly everything else, but not for the browser -- Dillo just doesn't cut it.)

Ebay turned out to be the answer: there are lots of subnotebooks there, nice used machines with full displays at netbook prices. And so a month before LCA I landed a nice Vaio TX650 with 1.5G RAM, Pentium M, Intel 915GM graphics and Centrino networking. All nice Linux-supported hardware.

But that raised another issue: how do widescreen laptops (the TX650 is 1366x768) talk to a projector? I knew it was possible -- I see people presenting from widescreen machines all the time -- but nobody ever writes about how it works.

The first step was to get it talking to an external monitor at all. I ran a VGA cable to my monitor, plugged the other end into the Vaio (it's so nice not to need a video dongle!) and booted. Nothing. Hmm.

But after some poking and googling, I learned that with Intel graphics, xrandr is the answer:

xrandr --output VGA --mode 1024x768
switches the external VGA signal on, and
xrandr --auto
switches it back off.

Update, April 2010: With Ubuntu Lucid, this has changed and now it's
xrandr --output VGA1 --mode 1024x768
-- in other words, VGA changed to VGA1. You can run xrandr with no arguments to get a list of possible output devices and find out whether X sees the external projector or screen correctly.

Well, mostly. Sometimes it doesn't work -- like, unfortunately, at the lightning talk session, so I had to give my talk without visuals. I haven't figured that out yet. Does the projector have to be connected before I run xrandr? Should it not be connected until after I've already run xrandr? Once it's failed, it doesn't help to run xrandr again ... but a lot of fiddling and re-plugging the cable and power cycling the projector can sometimes fix the problem, which obviously isn't helpful in a lightning talk situation.

Eventually I'll figure that out and blog it (ideas, anyone?) but the real point of today's article is resolution. What I wanted to know was: what happened to that wide 1366-pixel screen when I was projecting 1024 pixels? Would it show me some horrible elongated interpolated screen? Would it display on the left part of the laptop screen, or the middle part?

The answer, I was happy to learn, is that it does the best thing possible: it sends the leftmost 1024 pixels to the projector, while still showing me all 1366 pixels on the laptop screen.

Why ... that means ... I can write notes for myself, to display in the rightmost 342 screen pixels! All it took was a little bit of CSS hacking in my HTML slide presentation package, and it worked fine. Now I have notes just like my Mac friends with their Powerpoint and their dual-head video cards, only I get to use Linux and HTML. How marvellous! I could get used to this widescreen stuff.

Tags: , , , , , ,
[ 22:12 Feb 06, 2009    More linux/laptop | permalink to this entry | comments ]