Profile cover photo
Profile photo
Magnus Hoff
90 followers
90 followers
About
Magnus's posts

I've been making some notes on running Linux on my MacBook Pro. Today I figured out another detail.

When switching to Linux, I noticed that the sound out of the speakers seemed thinner somehow. After a while, I noticed that the sound would get fuller if I boosted the volume of the bass speaker in alsamixer.

This is all well and good, but for no apparent reason, the volume of the bass speaker would be reset to 77/100 at different times. After a while I realized that it must be Pulseaudio that does this.

Today, I figured out how to configure Pulseaudio to keep the bass speaker volume at 100/100 automatically. To configure how Pulseaudio utilizes alsa under the hood, go to /usr/share/pulseaudio/alsa-mixer. I went around looking in here for a while, and in the end changed a setting in /usr/share/pulseaudio/alsa-mixer/paths/analog-output-speaker.conf. Under the section [Element Bass Speaker], I changed the volume setting from "merge" to "127".

I found no documentation for any of this outside the config files. Searching for help on Pulseaudio is difficult, because there are so many basic questions that that's all you're going to find. For example, I had to figure out that "127" is the max value by guessing and seeing what would work.

Now, finally, the bass speaker volume is automatically on max, giving me rich, full sound again.

Software project idea: A set top box software with no on screen display. Let's call it Cinema View. The entire screen would always be devoted to the currently playing media.

Kodi/XBMC, which I use for my set top box, was initially designed for an XBox. The entire UX is designed around having a game controller.

These days, we all carry pocket computers (smart phones) and some people have tablets with gigantic screens laying around. Cinema View would have something like no user interaction on screen, but instead focus on having a really good user experience on the control devices. Rich browsing and even local previews would be possible, even while a movie is rolling undistracted on the main screen. Last generation media players are not designed to allow this. (Trivially; listing a file system directory is a blocking operation in Kodi and will cause the currently playing video to stutter)

----

Now, to file this in the back of my mind alongside all the other software projects which never take off the ground.

Post has attachment
Jeg holdt en presentasjon om Rust på Revolverconf 2015. Det var gøy! :)

Post has attachment
The quote of the week in the latest This Week in #rustlang is evocative of the particular feeling of working with WinAPI. Maybe something for you, +Rolf W. Rasmussen :)

----

@retep998 has, by and large, taken it upon himself to try and bind the Windows API using the sadistically horrible official windows.h header. By hand.

Having chipped away at the surface myself, let me tell you some of the horrors I've seen. windows.h contains sub-headers that implicitly depend on other headers having been imported in a particular order. Get the order wrong, and the definitions change. This makes isolating anything, let alone defining where it canonically is supposed to come from a Sisyphean task. It contains symbols that are deliberately defined multiple times. Sometimes, with different types. Sometimes, with different values. Because windows.h was written by shambling horrors from beyond time and space. That's not even touching the titanic, C'thuloid mass of brain-twisting agony that is the conditional compilation definitions and annotations sprinkled throughout like some kind of virulent pox. There are obscure conditional flags that change or omit functions based on bizarre edge cases buried in some obscure file which is included three different ways by paths so obtuse you could make a credible argument for a satellite map of the damn thing except it'd have to be a six dimensional monstrosity that would drive you mad just from looking at it. Then there's the vast tracts of API surface that are exposed via COM which Rust does absolutely jack toward making in any way usable so you have to write the damn vtables by hand and heaven help you if you run into an interface with multiple base interfaces because at that point you might as well give up and just use C because at least that has an IDL generator for it. That's even before you realise that LLVM's code generation isn't even correct on Windows, and this whole time, it's been silently generating bad code for stdcall methods which you'd think would be just like functions but nooo that's now how Visual C++ works, so methods with particular return types are incompatible at the binary level, unless you know about this and manually correct for it by fudging the type signatures in the Rust binding code and really it's no wonder he's a rabbit because a human would have been driven so deep into madness they'd need be halfway to the Earth's firey core.

To put it another way: I think it'd be kinda nice to give him a proverbial pat on the back for his herculean efforts thus far.

Post has shared content
Seems like I accidentally applied +Magnus Hoff's placejoearmhand filter to Erlang the Movie. https://www.youtube.com/watch?v=y90DYguD74whttp://placejoearmhand.magnushoff.com )

Post has attachment
I implemented this incredibly useful tool for calling "Hello Joe" on the phone. It tries to find all faces in a given picture, and then places Joe Armstrong's phone-with-hand from Erlang the Movie somewhere in the vicinity.

The hardest part of this project was setting up the webserver to handle the CGI script properly, including setting all the right permissions in the file system. The next hardest thing was figuring out how to invoke ImageMagick. Which is to say, face detection is surprisingly simple, and dealing with file permissions could still be easier.

The juicy part is of course the face detection. For this I ostensibly used OpenCV -- Open Source Computer Vision. OpenCV is too low level for me, since I am completely uninitiated to the computer vision field. Fortunately, third party utilities with a simpler user interface exist. I used http://www.thregr.org/~wavexx/software/facedetect/, which takes an image file as a command line argument and writes out coordinates for all the faces it can find on standard output. This is simple enough to handle that I could write the rest of the service in bash.

Test it out by going to http://placejoearmhand.magnushoff.com/ and putting a link to an image with faces in the box! The source is up on github: https://github.com/revolverhuset/placejoearmhand
Photo

When I posted my #rustlang implementation of tic-tac-toe (https://plus.google.com/+MagnusHoff/posts/KDKuWWnFeAu), +Stian Eikeland commented "I wonder if this code will run in a couple of months :)"

The jury is in: It doesn't compile in Rust 1.0.

I have had to make the changes in this diff: http://pastebin.com/GUZrgGtJ producing this result: http://pastebin.com/DmgbU8PH

There has been a number of breaking changes, some more interesting than others. One that produced a great amount of compile errors was the new default scope for enum values. They now need to be explicitly named (Field::N), or explicitly be brought into scope (use Field::{N,X,O};). This change matches the general feel of the language: Explicit is better than implicit.

Another change, which I think produced the greatest amount of work, was the new way to pass closures. With the 1.0 way, you need to know which one of three variants your closure is going to be; Fn, FnMut or FnOnce. Fn can be copied, moved and called as much as you like, but it cannot mutate its environment. FnMut is like Fn, but it can mutate its environment. Note, though, that you need a mutable reference to it to do so. FnOnce is like Fn, except it cannot be copied, and it can be called only once. FnOnce seems weird, but I have been needing exactly that variant for some asynchronous code in a C++ project.

The most fun change was the range literal syntax. Gone is range(0, 9), here is 0..9. This makes simple for loops nice: for x in 0..9 { ... }. But what is this? A special syntax to make some for loops a little bit nicer?

It turns out that this is an extensible and widely usable language syntax. .. is an operator that creates an object of a Range type (https://doc.rust-lang.org/reference.html#range-expressions). Range (https://doc.rust-lang.org/std/ops/struct.Range.html) objects can be used for a bunch of stuff, including taking a slice of something. Assuming we have let arr = [1, 2, 3];, then let slice = arr[0..2]; is the same thing as: let range = 0..2; let slice = arr[range];

Furthermore, Range is generic. You can for example use it with u32; 0u32..2u32, but more interestingly, you can use it with user defined types; Test::new(32)..Test::new(64). Currently, this requires you to implement a bunch of traits, some of which are deprecated, so this might become more ergonomic in the future.

Post has attachment
Excellent and thorough treatment of error handling in Rust 1.0.

I'm excited to see what becomes of this as Rust idioms get settled. It certainly looks like it could feel too cumbersome to use, but is that mostly in a small scale? Does the overhead of making your own error type fade away as your code base gets to a reasonable size?

I do think, however, it is good that the simplest way out, using unwrap, causes the program to abort on errors. This is certainly better than the tendency in ... let's say a fictional language with checked exceptions, to catch and swallow exceptions, continuing as if nothing had happened.

Post has attachment
What happens when you design for a specific webfont that fails to load.

Aka: Fuel for your fire, +Sverre Nøkleby 

Post has attachment
When shooting a photograph in portrait orientation, cameras generally recognize the situation and are able to store the resulting image such that the top of the photo corresponds with the top of the scene. Yet somehow, portrait photos sometimes show up in the wrong orientation; the top of the image on screen suddenly corresponds to the top of the camera as it was when the photo was taken. The culprit in this situation is lack of support for the EXIF orientation tag.
Wait while more posts are being loaded