04 November 2019

Science with Arthur C. Clarke (1)

In Chapter 1 of 2010: Odyssey Two, Arthur C. Clarke wrote that an astronaut achieved a tenth of the speed of light in less than two minutes, and this meant an acceleration of about a quarter of million gravities.

Let's check. Here, I feel that the term "gravity" is not technical enough: Does it mean \( 1~\mathrm{ms}^{-2} \), the unit acceleration in SI units? Or g-force, an acceleration of about \( 9.8~\mathrm{ms}^{-2} \)?

Given that:

$$ u = 0~\mathrm{ms}^{-1} \\ v = \frac{c}{10} \approx 3.0 \times 10^7~\mathrm{ms}^{-1} \\ t=120~s $$

We have:

$$ a = \frac{v-u}{t} = \frac{3.0 \times 10^7}{120}~\mathrm{ms}^{-2} \\ \approx 250,000~\mathrm{ms}^{-2} $$

Indeed! The term "gravity" here should mean \( 1~\mathrm{ms}^{-2} \), which is the unit acceleration in SI units.

18 October 2019

Xubuntu 19.10 on Lenovo T495

Here are the steps I use to setup Xubuntu 19.10 on a Lenovo T495 properly.

Installation

  • Drive Partitions:
    • /: 48GB
    • swap: 4GB
    • /home: Remaining space

Problems & Solutions

Problem 1: Pixelated Graphics Artifacts

Solution:
  1. Start Settings Editor (of Xfce4)
  2. Find
    • Channel: xfwm4
    • Property: general -> vblank_mode
  3. Set the value from auto to xpresent

Problem 2: Deactivate Bluetooth on System Startup

Sometimes it's not desirable to on the Bluetooth whenever the system boots up. To deactivate it on system startup:
  1. Create /etc/rc.local and put the following line.
    echo disable > /proc/acpi/ibm/bluetooth
  2. Make /etc/rc.local to be executable:
    $ sudo chmod 755 /etc/rc.local

Problem 3: VirtualBox with Secure Boot

References:

Problem 4: UFRII Printer Driver for Canon imageCLASS MF244dw

Both Ubuntu and Canon imageCLASS MF244dw printers support IPP Everywhere protocol, so Ubuntu automatically adds the printer if it discovers it in the network.
You can also use the Canon proprietary printer driver UFR II (stands for "Ultra Fast Rendering II") for faster printer times. To do this:
  1. Download the latest UFRII driver (select Linux 64bit) from: https://www.usa.canon.com/internet/portal/us/home/support/details/printers/black-and-white-laser/imageclass-mf244dw/imageclass-mf244dw
  2. Uncompress the installation file and run sudo ./install.sh
    • When asked about "Do you want to register the printer now? (y/n)", answer n.
  3. Run "Printers" and add the detected "Canon MF240 UFRII LT ..."
    • The UFR II LT driver will be chosen automatically

Miscellaneous

Disable WiFi on Ethernet Connection

  1. Refer to: https://www.richud.com/wiki/Ubuntu_disable_wifi_on_ethernet_connection
  2. Change the 4th line from eth*) to eth*|usb*|en*)

27 April 2019

WiFi Dongle: Realtek RTL8188

I have a mini PC without any built-in WiFi, and I would like to use a WiFi dongle so that it can connect to the Internet easily. I have a D-Link DWA-110 WiFi dongle I bought with about RM100 about 10 years ago. Unfortunately, it does not work properly any more: It would give up the connection once I have used it for a few minutes and its temperature becomes high.

So I decided to buy a new one. I bought one with only RM10 (including shipping fee), but I neither knew what brand it was nor what chipset it used. I just trusted the description on the web page that it would just work perfectly in Linux. Can't ask for much with only RM10.

Here is a photo showing the old (on the left, of course) and the new one. Behold! Technology advances fast!


However, I was very disappointed when I first used it: A speed test showed that its download speed was 'only' 0.4 Mbps?!! And I got a higher (?) upload speed of 'only' 2.5 Mbps?!! I tested it on two computers running Ubuntu 18.04 and Ubuntu 19.04 but still obtained the same results. For once I thought that I was terribly cheated by the seller.
(Edited: I have later tested this driver r8188eu with options rtw_power_mgnt=0 rtw_enusbss=0. The speed does improve greatly to about but is still slower, in the range of 30 Mbps+.)

I decided to find out more. I checked the CD that it shipped with and found that it included a Linux driver. Weird, because Linux kernel has usually included all popular drivers, and the manufacturer does not have to provide one. Then I found something: This dongle embeds RealTek RTL8188ETV, and somehow the driver included by the current version of Linux kernel is not good enough. Better drivers are available out there.

Here's the procedure I follow to set it up, tested to work fine on Ubuntu 18.04 and Ubuntu 19.04:

  1. Check the existing driver and add it into the blacklist:
    $ lsmod | grep 8188
    r8188eu
      ...
    $ vi /etc/modprobe.d/50-blacklist-8188eu.conf
    blacklist r8188eu
  2. Obtain the latest source code from https://github.com/quickreflex/rtl8188eus:
    $ git clone -b v5.2.2.4 https://github.com/quickreflex/rtl8188eus.git
  3. Compile, install, and use the driver:
    $ cd rtl8188eus/
    $ make all
    $ sudo make install
    $ sudo rmmod r8188eu
    $ sudo depmod -a
    $ sudo update-initramfs -u
    $ sudo modprobe 8188eu
  4. Test it now, or to play safe, reboot the computer and test it again.
A speed test shows that it can achieve 54 Mbps now, which is also the WiFi speed limit of my modem. So it finally works fine!

If you run into the problem of losing connection after some time (so far I haven't encountered this problem), you may want to set some options for the driver:
$ cat /sys/module/8188eu/parameters/rtw_power_mgnt  # Check the current value
$ cat /sys/module/8188eu/parameters/rtw_enusbss  # Check the current value
$ vi /etc/modprobe.d/8188eu.conf
options 8188eu rtw_power_mgnt=0 rtw_enusbss=0

Here are the values defined for these options:
  • rtw_power_mgnt
    • 0: disable power saving
    • 1: power saving on, minPS
    • 2: power saving on, maxPS
  • rtw_enusbss
    • 0: disable auto suspend
    • 1: enable auto suspend
External References:

23 April 2019

Prove that \(2\lfloor y \rfloor > y\) when \(y \geq 1\)

Problem:
Prove that \(2\lfloor y \rfloor > y\) when \(y \geq 1\).

Proof:
Let \(y = \lfloor y \rfloor + r\), then \(0 \leq r < 1\).
Besides, since \(y \geq 1\), we have \(\lfloor y \rfloor \geq 1\), and thus \(\frac{1}{\lfloor y \rfloor} \leq 1\).
From \(r < 1\),
$$ \frac{r}{\lfloor y \rfloor} < \frac{1}{\lfloor y \rfloor} \leq 1 \\ \frac{r}{\lfloor y \rfloor} + 1 = \frac{r + \lfloor y \rfloor}{\lfloor y \rfloor} < 1+1 \\ \frac{y}{\lfloor y \rfloor} < 2 \\ y < 2 \lfloor y \rfloor \\ 2 \lfloor y \rfloor > y \quad \blacksquare $$

17 April 2019

USB Sound Card for Raspberry Pi 3B+ with Ubuntu Mate 18.04.2

I have bought and configured an external USB sound card for my Raspberry Pi.

After plugging in the sound card, here are what I have. Important lines are highlighted.

$ lsusb
Bus 001 Device 004: ID 1941:8021 Dream Link WH1080 Weather Station / USB Missile Launcher
Bus 001 Device 006: ID 8086:0808 Intel Corp. 
Bus 001 Device 005: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 007: ID 0424:7800 Standard Microsystems Corp. 
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ sudo aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 7/7
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

After disabling the onboard audio with:

$ sudo vi /boot/config.txt
...
dtparam=audio=off
...

I have these now.

$ cat /proc/asound/modules 
 1 snd_usb_audio
$ cat /proc/asound/cards
 1 [Device         ]: USB-Audio - USB PnP Sound Device
                      C-Media Electronics Inc. USB PnP Sound Device at usb-3f980000.usb-1.1.3.4, full
$ sudo amixer -c 1
Simple mixer control 'Speaker',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 151
  Mono:
  Front Left: Playback 44 [29%] [-20.13dB] [on]
  Front Right: Playback 44 [29%] [-20.13dB] [on]
Simple mixer control 'Mic',0
  Capabilities: pvolume pvolume-joined cvolume cvolume-joined pswitch pswitch-joined cswitch cswitch-joined
  Playback channels: Mono
  Capture channels: Mono
  Limits: Playback 0 - 127 Capture 0 - 16
  Mono: Playback 0 [0%] [0.00dB] [off] Capture 0 [0%] [0.00dB] [on]
Simple mixer control 'Auto Gain Control',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]

Need to set the volume properly (to maximum).

$ sudo amixer scontrols
amixer: Mixer attach default error: No such file or directory
$ sudo amixer -c 1 scontrols
Simple mixer control 'Speaker',0
Simple mixer control 'Mic',0
Simple mixer control 'Auto Gain Control',0
$ sudo amixer -c 1 sset 'Speaker' 100%
Simple mixer control 'Speaker',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 151
  Mono:
  Front Left: Playback 151 [100%] [-0.06dB] [on]
  Front Right: Playback 151 [100%] [-0.06dB] [on]

MPD works properly now!

References:



08 April 2019

MRTG on Raspberry Pi 3B+ with Ubuntu Mate 18.04

I have installed and configure MRTG for system monitoring on a Raspberry Pi 3B+ running Ubuntu Mate 18.04.

I have also tested a similar setup (without CPU temperature) on a PC running Ubuntu 18.10.

1. Install SNMP Daemon for Organizing and Collecting Device Information

Install the package.
  $ sudo apt install snmpd

Backup existing /etc/snmpd.conf.
  $ sudo mv /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.ORIG

Create /etc/snmpd.conf.
  $ sudo vi /etc/snmp/snmpd.conf
  agentAddress    127.0.0.1:161
  rocommunity     public
(Yes, only these two lines.)

Restart snmpd.
  $ sudo systemctl restart snmpd

2. Install SNMP Utilities

Install the package.
  $ sudo apt install snmp

Check whether the setup works by trying to get the free CPU percentage.
  $ snmpget -v 1 -c public localhost .1.3.6.1.4.1.2021.11.11.0
  iso.3.6.1.4.1.2021.11.11.0 = INTEGER: 97

There is no well known OID (Object Identifier) for CPU temperature, so we are going to write a custom script and feed the value to SNMP.
  $ vi ~/snmp-cpu-temp.sh
#!/bin/bash
if [ "$1" = "-g" ]
then
    echo .1.3.6.1.2.1.25.1.8
    echo gauge
    cat /sys/class/thermal/thermal_zone0/temp
    # The above is for Raspberry Pi 3B+. For Ubuntu PC,
    # I don't know a portable way applicable for all.
    # Tell me if you know one.
    # This ugly hack works for mine:
    #sensors -u 2>/dev/null | sed -n '4p' | sed -e 's/temp1_input: \(.*\)/scale=0; 1000 * \1 \/ 1/g' | bc -l
fi
exit 0
  $ chmod +x ~/snmp-cpu-temp.sh
  $ ./snmp-cpu-temp.sh -g
  .1.3.6.1.2.1.25.1.8
  gauge
  49768

Tell SNMP how to handle this OID by appending a line to /etc/snmp/snmpd.conf.
  $ sudo vi /etc/snmp/snmpd.conf
(append)
  pass .1.3.6.1.2.1.25.1.8 /bin/sh /home/username/snmp-cpu-temp.sh
  $ sudo systemctl snmpd restart
(Change username above to reflect yours.)

Check if it works.
  $ snmpget -v 1 -c public localhost .1.3.6.1.2.1.25.1.8
  iso.3.6.1.2.1.25.1.8 = Gauge32: 41856

3. Install MRTG

Install the package.
  $ sudo apt install mrtg

Backup existing /etc/mrtg.cfg.
  $ sudo mv /etc/mrtg.cfg /etc/mrtg.cfg.ORIG

Create /etc/mrtg.cfg. I am more interested in monitor the system health, including CPU load, memory usage, and CPU temperature.
  $ sudo vi /etc/mrtg.cfg
WorkDir: /var/www/mrtg
EnableIPv6: no 

Title[cpuload]: CPU Load
Target[cpuload]: 100 - .1.3.6.1.4.1.2021.11.11.0&.1.3.6.1.4.1.2021.11.11.0:public@localhost
Options[cpuload]: gauge, nopercent, growright, unknaszero, noo
MaxBytes[cpuload]: 100
YLegend[cpuload]: %
ShortLegend[cpuload]: %
LegendI[cpuload]: CPU
Legend1[cpuload]: CPU usage
PageTop[cpuload]: <H1>CPU Load</H1>

Title[memory]: Memory Usage
Target[memory]: .1.3.6.1.2.1.25.2.3.1.6.1&.1.3.6.1.2.1.25.2.3.1.6.3:public@localhost 
Options[memory]: gauge, nopercent, growright, unknaszero
Factor[memory]: 1024
kilo[memory]: 1024
kMG[memory]: ,,Mi,Gi,Ti,Pi,Ei,Zi,Yi
MaxBytes[memory]: 100000000000
YTicsFactor[memory]: 1024
YLegend[memory]: Bytes
ShortLegend[memory]: B 
LegendI[memory]: Physical 
LegendO[memory]: Virtual 
Legend1[memory]: Physical Memory
Legend2[memory]: Virtual Memory 
PageTop[memory]: <H1>Memory Usage</H1>

Title[cputemp]: CPU Temperature
Target[cputemp]: .1.3.6.1.2.1.25.1.7.0&.1.3.6.1.2.1.25.1.8:public@localhost 
Options[cputemp]: gauge, nopercent, growright, noi 
Factor[cputemp]: 0.001
MaxBytes[cputemp]: 100000
YTicsFactor[cputemp]: 0.001
YLegend[cputemp]: Celsius
ShortLegend[cputemp]: Celsius
LegendO[cputemp]: CPU temperature 
Legend2[cputemp]: CPU temperature in Celsius
PageTop[cputemp]: <H1>CPU Temperature</H1>

Create the corresponding web directory for MRTG. Here we use apache2, so install the apache2 package first if you haven't.
  $ sudo mkdir /var/www/mrtg
  $ sudo vi /etc/apache2/sites-available/mrtg.conf
Alias /mrtg "/var/www/mrtg/"
<Directory "/var/www/mrtg/">
  Options FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>
  $ sudo a2ensite mrtg
  $ sudo systemctl restart snmpd

Use the indexmaker helper to create the main page index.html.
  $ sudo indexmaker /etc/mrtg.cfg --title='System Monitor' --columns=1 --output=/var/www/mrtg/index.html

It should work now! So surf http://address/mrtg/ and you should see something.
(Change address above to reflect yours.)



Notes:
  • The mrtg package installs /etc/cron.d/mrtg to run mrtg every 5 minutes.
  • The cfgmaker helper can create a draft /etc/mrtg.cfg based on what it detects, including network traffics. I don't have much luck with it, but you can try it if you want.
  • We can improve the MRTG setup further with RRDTool. But the CGI scripts I found that can work nicely with MRTG+RRDTool are outdated and do not run well with my setup.

05 April 2019

First Post from Blogger

Does Blogger for Android work? At least write a post with simple format?
If your see this, it works! Bold, italic, link.
Attaching image doesn't seem to work.

27 March 2019

Notes for Pre-U Physics

I would like to write some notes (minimalist's notes) for certain topics in pre-university physics. I found that some students may be confused by the content of these topics, and sometimes I would also want to make a quick revision should I need them. That's why I write the notes and share them here.

I am a minimalist in writing notes: Just retain the essential definitions and concepts, while omit obvious applications and consequences. Keep in mind if you want to use them. 😊

06 November 2016

Array Initialization in C and C++

A smart student new to C/C++ is confused by array initialization in C and C++. Indeed, standard says something, best practices say something, and compilers may say something else too. So I wrote this.
Note that I wrote in year 2016, this is important because many things can change very fast in the computing world! I will try to update it when I am free.

/* Array initialization in C and C++ */


// Stop GCC from nagging. Yes, you can use gcc/g++ to compile this piece of source code.

#pragma GCC diagnostic ignored "-Wunused-variable"

// This declares an array of 4 integers

// - It has static storage allocation
int ar01[4];

// The first two will be initialized to 1 and 2

// - There is only one copy of this variable, therefore the variable
//   has static storage.
// - The array will be initialized once during load time.
int ar02[4] = {1,2};

int main(void)

{
  // This declares an array of 4 integers
  int ar03[4];

  // The first two will be initialized to 1 and 2

  int ar04[4] = {1,2};

  // The array will be initialized to 2, 3, 4 and 5

  // - How about 6? It's extra and will be ignored by the compiler
  // - C compiler generally issues a warning for this
  //   E.g., gcc: warning: excess elements in array initializer
  // - C++ compiler generates an error instead
  //   E.g., g++: error: too many initializers for int [4]
  int ar05[4] = {2,3,4,5,6};
  // This is a stack-dynamic variable. Therefore it has to be
  // initialized each time it's declared.
  // - A compiler will generally translate the code to:
  //     int ar05[4];
  //     ar05[0] = 2;
  //     ar05[1] = 3;
  //     ar05[2] = 4;
  //     ar05[3] = 5;
  // - In other words, array initialization here is just a syntactic sugar.

  // This declares an array of characters

  // - First 3 elements initialized to 'a', 'b', 'c'
  char ar06[4] = {'a', 'b', 'c'};

  // In C, a string is simply an array of characters where the final

  // character is null ('\0').
  // The array below is thus a C string.
  char ar07[4] = {'a', 'b', 'c', '\0'};

  // We can use a string literal as a 'shortcut' to initialize this array.

  char ar08[4] = "abc";
  // It is important to note that, when you do so, the compiler simply
  // translates the code to:
  //    char ar08[4];
  //    ar08[0] = 'a';
  //    ar08[1] = 'b';
  //    ar08[2] = 'c';
  //    ar08[3] = '\0';

  // How about this?

  char ar09[4] = "abcdef";
  // The size of array initializer is greater than the size of array.
  // So the compiler will ignore excess elements.
  // - In other words, the compiler will simply treat the code above as:
  //     char ar09[4] = {'a', 'b', 'c', 'd'};
  // - Note that 'e', and 'f' will simply be *ignored* by the compiler!
  //     (If you have doubt, use gcc -S and examine the assembly output.)
  // - A string "abcdef" will NEVER be generated by the compiler!
  // - C compiler generally issues a warning for this
  //   E.g., gcc: warning: initializer-string for array of chars is too long
  // - C++ compiler generates an error instead
  //   E.g., g++: error: initializer-string for array of chars is too long

  // How about this?

  char ar10[4] = "abcd";
  // Same as the array above.
  // - So the compiler will ignore the excess terminating null character.
  // - Interestingly, C compiler may not issue warning
  //   for this excess null character!
  //   - E.g., gcc 5.4.1 and clang 3.8.0 do not issue warning here
  //   - However, this array should NOT be used as a normal C string,
  //     since there is NO guarantee that it is null-terminated!
  // - C++ compiler generates an error instead!
  //   E.g., g++: error: initializer-string for array of chars is too long
  // - So this is a 'boundary' case between C and C++:
  //   - No problem with C (may not even have a warning!)
  //   - Error with C++

  // If the size of the array is the same as that of the array initializer,

  // we can choose not to specify the size and let the compiler to fill it
  // in for us.
  int ar11[] = {3, 4, 5};
  // In this case, the size of the array is 3.

  // Same for array of characters

  char ar12[] = {'a', 'e', 'i', 'o', 'u'};
  // In this case, the size of the array is 5

  // How about a C string?

  char ar13[] = "aeiou";
  // In this case, the code is equivalent to:
  //     char ar13[] = {'a', 'e', 'i', 'o', 'u', '\0'};
  // So the size of array is 6.

  // Now, consider the following code:

  char *str01 = "aeiou";
  // We are NOT declaring an array, so there is no array initializer here!
  // Instead, the statement above is equivalent to:
  //     char *str01;
  //     str01 = "aeiou";
  // Here:
  // - When the program is loaded, (at least) 6 bytes will be allocated
  //   to store the null-terminated string "aeiou".
  //   - The string "aeiou" will be allocated to a region that is
  //     supposed to be read-only, enforced either by the hardware
  //     or by the operating system. In other words, the technically
  //     correct data type should be "const char *".
  //   - However, such intensive use of the 'const' keyword is not
  //     practiced by many C programmers.  Nonetheless, care must
  //     be taken as not to modify such strings, or it can lead
  //     to undefined behavior.
  // - When the statement above is reached:
  //   (1) A few bytes will be allocated for the character pointer 'str01'
  //   (2) The pointer will then be assigned the starting address of the
  //       string "aeiou" allocated above.
  //
  // Differences between 'ar13' and 'str01':
  // (1) While 'str01' can be assigned a new value (an address), 'ar13'
  //     can be reassigned and always refers to the starting address of
  //     the array.
  // (2) Storage is allocated for 'str01', but no storage is allocated
  //     for the name 'ar13'.
  //
  // - C compiler generally accepts the statement.
  //   - Since 'const' is not practiced in many C programs, the warning
  //     is disabled by default (in gcc and clang)
  // - C++ compiler generates warning for it since 'const' is encouraged
  //   to be used whenever possible:
  //     gcc -std=c++98: warning: deprecated conversion from string constant to ‘char*’
  //     gcc -std=c++11: warning: ISO C++ forbids converting a string constant to ‘char*’
  //   - So the statement is best to be replaced with:
  //         const char *str01 = "aeiou";

  return 0;

}

27 May 2015

Setup WinEdt to Use Cygwin/TeX Live

1. Scenario

I have installed Cygwin, and included TeX Live so that I can compile LaTeX files in Cygwin.
Then I install WinEdt 9, and to save hard disk space, I would like to configure WinEdt such that it can (re-)use Cygwin/Tex Live.

2. Configuration

2.1. Edit System Environment Vaiables to include Path to Cygwin Executables

Skip this step if you have included the path to Cygwin executables.
  1. In Windows 8.1, press [Windows Key] + [Q], type "variables", and select "Edit the system environment variables" from the list. (For other Windows versions, try to find "System Properties", then select "Environment Variables...".)
  2. Under System variables, select "Path" variable, click "Edit...". Append ";C:\cygwin\bin" to the value.
  3. Click 'Ok' three times to complete.

2.2. Configure WinEdt 9

  1. Select Options > Configurations > TeX Live. This tells WinEdt 9 to make use of TeX Live.
  2. Go to Options > Execution Modes.
  3. Select TeX System tab.
  4. Modify the following fields
    • TeX Root: C:\cygwin
    • TeX Bin: C:\cygwin\bin
    • TeX Help: C:\cygwin\usr\share\texmf-dist\doc
  5. Select TeX Options tab.
  6. Modify the following fields
    • Default PDFTeXify Engine: pdftex.exe -fmt=latex -output-format=pdf

3. Bonus

Can use Sumatra PDF, which synchronizes well with WinEdt and TeX Live.

18 January 2013

BASH: Single-Quotes inside a Single-Quoted String

In bash, to escape some characters for the command-line arguments properly, you can use single quotes. E.g.,
$ file 'Some # Weird File Name.odt'
But how about the single quote characters? There are several methods. I found the following ways most convenient.

(1) Replace ' with '\''

Break out of the quoted string, and escape the single quote alone.
 $ file 'My wife'\''s file.txt'
(2) Replace ' with '"'"'

Same idea, but different way of escaping the single quote.
$ file 'My wife'"'"'s file.txt'
So, in Python, you can use:
s = string.replace("'", "'\"'\"'")
or in PHP,
s = str_replace("'", "'\"'\"'", string);

17 January 2013

MPlayer & MEncoder: Manipulating Audio Channels

MPlayer provides powerful controls to manipulate different audio channels.

During playback,

  • ( and ) keys: Adjust audio balance in favor of left/right channel.
  • # key: Cycle through the available audio tracks.
You can add, remove, route, or copy audio channels with the -af channels=nch[:nr:from1:to1:from2:to2:from3:to3:...] option. For example, if there are 2 channels, and you want to copy channel 0 to channel 1 (and thus abandon the original channel 1), you can use -af channels=2:2:0:0:0:1.

You can even mix the channels with specified proportions with the -af pan=... option. Unfortunately, the suboptions are naturally much more complicated. Basically you can specify a 2D matrix to indicate the amount of each source channel that will be mixed to the destination channel.

References: