Neil Schemenauer's Web Log

[Archives]

August 12, 2023

Mic boost for MSI B650 TOMAHAWK WIFI board

You would think in the year 2023, they would have finally figured out how to make audio chips and drivers that can perform basic functions (e.g. play sound through headphones, record sound through a mic). Alas, it is not so. With my shiny new MSI B650 TOMAHAWK WIFI motherboard, I cannot record the mic. Updating the ALSA UCM2 files in /usr/share/alsa/ucm2 made the mic actually produce a signal. However, the level is too low to work properly in most apps. There is no "Mic Boost" control, even when using "alsamixer -D hw:N" to control it directly.

I filed a bug report in the Linux bug tracker since it seems to be a bug in the ALSA USB Audio driver. I was able to confirm that the Windows Realtek driver does expose a "Mic Boost" setting (+10, +20, and +30 db). I was able to run Windows in Qemu and "pass-through" the USB device. The key qemu option is as follows.

-usb -device usb-host,vendorid=0x0db0,productid=0x422d

Since I filed the bug report, I figured out a work-around. Pipewire allows you to set the "volume" property of the device node, at a level beyond what the GUI will allow. My shell script to do it follows.

#!/bin/sh

set -e

# This is the node.description for the mic
name='USB Audio Microphone'

# Default value is 1.0.
volume=15

find_id () {
    pw-dump -N| 
        jq --arg n "$name" 
            '..|objects|select(.["node.description"]==$n)|.["object.id"]'
}

# Lookup id of node for mic
id="$(find_id)"

# Set volume property
pw-cli set-param "$id" Props "{ volume: $volume }"

April 26, 2017

Normal CDF in Python

I needed a single function provided by scipy, i.e. scipy.stats.lognorm.sf(). I think scipy is a high quality library but having to include such a huge library just for a single function bothers me. So, I did a bit of research as to how to implement it myself. I need an accurate and high performance version and my initial table-based linear interpolation version was not accurate enough.

It turns out that modern versions of Python have the ERF function included. That gets you most of the way there. Computing the normal (Gaussian) CDF is pretty simple.

def norm_cdf(x):
    '''Probability that a statistic is less than x. This equates to the
    area of the distribution below x.
    '''
    return 0.5*(1.0 + math.erf(x/math.sqrt(2)))

What my algorithm actually needs is the log-normal survival function, but getting to that from the normal CDF is also pretty simple. Traditially, the log-normal distribution takes two additional parameters, mu and sigma (i.e. location parameter, scale parameter). The survival function then is as follows.

def lognormal_sf(x, mu, sig):
    return 1 - norm_cdf((math.log(x)-mu)/sig)

Trivial test:

>>> scipy.stats.lognorm.sf(1, 2, 0, math.exp(.5))
0.5987063256829237
>>> lognormal_sf(1, .5, 2)
0.5987063256829237

Thanks to Mark Dickinson for adding math.erf() to Python. Implementing those special functions accurately is non-trivial and the versions in Python look to be high quality.

July 06, 2013

Bridging with 2wire 2701HG-S DSL modem

Sasktel has installed a 2wire 2701HG-S to provide DSL service for me. After quite a bit of messing around, I believe I've figured out how to make it act like a bridge instead of routing with NAT. The instructions from James Hartig on how to use the DMZplus feature are key.

The short version is to use the firewall menu to mark your own router as the DMZplus device. As far as I can tell, the 2wire device uses the MAC address of the second router to bridge traffic (layer 2 bridge?). Your router can use DHCP to get the WAN IP address. I care about latency so I don't want two layers of NAT. The 2wire device is fairly flexible but not like OpenWRT or DD-WRT, etc.

July 28, 2012

Making of Warcraft

A great post about working on Warcraft. Aside from interesting background on development details, I'm struck by the incremental process of innovation. I never played Dune 2 but I had heard that it was a pioneer for RTS games. Patrick Wyatt confirms the influence. Also, the influence of Warhammer is noted. I don't think Blizzard would ever admit such things, Starcraft/Warcraft is their creation and they did it all themselves and you better not infringe on "their IP".

I intensely dislike the media's tendency to portray each technological advance as the result of one or a couple of people's genius. Except in very rare cases, progress does not work that way. Instead, more often than not, a "breakthrough" is actually just a small improvement on an existing idea. Also, often the same improvement is "discovered" multiple times completely independently. It seems like when an idea's time has come, it's discovery is almost inevitable.

Anyhow, enough ranting. I enjoyed Patrick Wyatt's blog. If you are interested in game development, check it out.

July 05, 2012

Where's Chigurh?

On some weird tangent, I started thinking about No Country for Old Men again today. It's one of my favorite movies. I enjoy almost anything by Coen brothers and the acting in the movie was also fantastic. Like many good movies, and like a good Rorschach ink blot, the details of the plot are left open for interpolation by the viewer.

One key point of the plot left ambiguous is: where is Chigurh when Ed Tom enters the hotel room?. There are lots of theories out there. I've never seen my theory presented however, so I feel like I should write about it.

To me, the central theme of the move is Ed Tom's feeling that he is too old to continue fighting evil. He feels like crime is getting worse and he is no longer up to fighting it. He's "overmatched". Chigurh represents the modern evil. The meeting in the hotel room is the ultimate test of Ed Tom. Is he up to it?

To me, it seems clear that Chigurh is in the room. There is no good reason as to why he would not be there and that's why it was a popular topic of discussion after the movie's release. So, if he is there, why was there no confrontation?

The key clue is provided when the accountant asks Chigurh "Are you going to shoot me?". Chigurh responds That depends. Do you see me?. There are numerous examples in the movie of evidence that Chigurh lives by some strict code of rules.

Ed Tom makes himself not see Chigurh. It's the only explanation that makes sense to me. Chigurh is standing behind the door but Ed Tom ignores him. He is not up to confronting the evil. He knows he will die and he is afraid. Chigurh follows his code and does not kill him.

The exact details of how the situation unfolds is not clear. I haven't watched the movie in a while but in my imagination, Ed Tom initially does not see Chigurh. When he does, Chigurh has got his gun pointed at him and there is no way Ed Tom could win the showdown. Instead Ed Tom lets Chigurh escape.

At the end of movie, the first dream is about this failure. Ed Tom's father entrusted him to uphold the law, protect innocent people, fight against evil. Ed Tom failed. The second dream is a forgiveness for this failing.

April 03, 2012

Samsung Galaxy S (I9000) partitioning scheme

I had trouble finding details about how flash memory is partitioned on this device, here's what I learned in case it helps others. The device has two built-in flash memory devices: 8 or 16GB NAND and flash memory connected directly to the processor chip (MMC).

The MMC can be partitioned using different schemes. The stock ROMs use a scheme called BML. Most open source ROMs use a more flexible scheme called MTD. When you first install CyanogenMod 7, for example, the MMC is converted to use MTD partitioning. The MMC partitions are as follows:

If you are familiar with the Heimdall or Odin tools, these names will be familiar. Odin and Heimdall use the PIT file to control the partitioning of the MMC (e.g. s1_odin_20100512.pit).

The NAND device is partitioned into two parts: /data and /mnt/sdcard. The partition mounted on /mnt/sdcard is referred to as the internal SD card. If you put a SD card in the external slot, it is mounted as /emmc (at least in CM9).

For reference, here is the NAND partition information for my i9000m phone.

klonk:~$ adb shell
shell@android:/ $ su
shell@android:/ # fdisk /dev/block/mmcblk0

The number of cylinders for this disk is set to 1953792.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/block/mmcblk0: 16.0 GB, 16005464064 bytes
1 heads, 16 sectors/track, 1953792 cylinders
Units = cylinders of 16 * 512 = 8192 bytes

              Device Boot      Start         End      Blocks  Id System
/dev/block/mmcblk0p1               5     1708032    13664224   c Win95 FAT32 (LBA)
Partition 1 does not end on cylinder boundary
/dev/block/mmcblk0p2         1708033     1953792     1966080   c Win95 FAT32 (LBA)
Partition 2 does not end on cylinder boundary

Command (m for help): 

On my phone /data is formatted as ext4 and /mnt/sdcard as vfat. One other thing, if you connect your phone to a computer with USB, the mass storage devices that are visible correspond to /mnt/sdcard and /emmc (i.e. one partition of the NAND and the external SD card). The other devices are not visible.

March 27, 2012

Microsoft Exchange time-zone confusion

This has happened to me more than once and somehow I think I'm not the only one. When Microsoft Exchange sends out calendar related email, it includes time-zone information in the text of the message. Good idea, right? Well, the implementation leaves something to be desired. For example, if the message contains the line:

When: Wednesday, March 28, 2012 3:00 PM-4:00 PM (GMT-06:00) Central Time (US & Canada).

what time would you guess the event occurs at? If you guessed 21:00 UTC (12+3+6) then you lose. The time zone offset is actually GMT-5 as the "text/calendar" attachment (not so) plainly shows. The problem is that the local time-zone of the sender was Central Daylight Time.

February 20, 2012

Silly Quixote benchmark

Looks like the old dog can still run with the young pups. If you are starting a new web project in Python, Flask is worth a look. I spent some time poking around at the source code and it looks decent. The "context" hacks are probably the ugliest part of it but not so bad. I don't care for Django, it's origin as a content delivery system is pretty apparent.

BTW, Durus has been doing NoSQL for ages, almost as long as ZODB. :-)

[comments]