Uploading to Google Play Music without matching

I’ve had some trouble with Google Play Music’s scan and match service. It sometimes matches tracks to the wrong versions of them. Sometimes the volume of a track is wildly different from what I have locally (with or without ReplayGain). Unfortunately, there is no way to disable matching in Google’s official Music Manager application.

gmusicapi supports uploading to Google Play Music without their “scan and match” service. gmusicapi-scripts utilises gmusicapi. Let’s use them!

  1. Install gmusicapi-scripts:

    # Windows
    py -3 -m pip install gmusicapi-scripts
    # Others
    pip install gmusicapi-scripts
    
  2. Convert tracks (if needed) to 320kbps MP3 and place them in <directory>.

    • If you place non-MP3 files in this directory, gmsync will try to convrt them with FFMPEG or AVConv if they are on the PATH. Look at the docs to see what formats it supports.
  3. Run gmsync. Follow any instructions it provides:

    gmsync up <directory>
    

gmsync uploads without matching by default. Perfect.

Working around Intel CPU Running at a Maximum of 49%/50%

My laptop had been feeling slower than it had used to, and I was getting more and more certain that it wasn’t just me.

One time I opened Task Manager and noticed that whenever I put load on the machine, it maxed out at 49%. Every time. Cooling wasn’t the issue as the laptop fan (which is a dumb fan controlled by hardware, not software) wasn’t spinning up much.

After searching online, I stumbled across a thread that would provide the (really rather insane) workaround: Move the Intel processor driver so Windows does not use it. Thanks to everyone there for the discussion.

  1. Restart in the advanced command prompt mode. (Hold Shift when clicking Restart)

  2. Log in to your account.

  3. Run the following:

    cd drivers
    move intelppm.sys intelppm.sys.old
    exit
    
  4. Select the option to exit and continue to Windows 10.

One comment on that thread suggests that this also works for AMD CPUs by moving amdppm.sys instead of intelppm.sys.

Update 2017-06-23: I previously suggested to add the .bak extension to the driver file. However, Windows recognises this extension, and so it will restore the driver back to its original location at the next restart, meaning the problem will return! I’ve changed the instructions to suggest using .old instead, which I don’t believe Windows recognises, but is still fairly obvious to users.

Tips for Ripping Blu-Ray Audio

I recently ripped my first Blu-Ray audio discs. Here are a few tips I’ve discovered along the way:

tl;dr

Backup the disc using MakeMKV and extract the audio using the updated version of the command under Putting it all together.

Ripping the discs

MakeMKV can be used to rip and, if necessary, decrypt Blu-Ray audio discs. While it is in beta, it can be evaluated by using the current beta key.

I use the complete Blu-Ray backup feature so I have the raw stream files to work with.

Extracting the audio from the video files

ffmpeg can be used to extract the audio track(s) from the video streams on the Blu-Ray.

First interrogate one of your streams using ffprobe to see how the different tracks are laid out:

ffprobe -hide_banner BDMV/STREAM/00002.m2ts

I use -hide_banner to reduce the amount of text printed to the terminal. If you have troubles and decide to ask others for help, be sure to omit -hide_banner as the information it emits can be useful when debugging!

Here is the output I got:

Input #0, mpegts, from 'BDMV/STREAM/00002.m2ts':
  Duration: 00:01:47.07, start: 4200.000000, bitrate: 7133 kb/s
  Program 1
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc
    Stream #0:1[0x1100]: Audio: pcm_bluray (HDMV / 0x564D4448), 48000 Hz, stereo, s16, 1536 kb/s

In my case I only have one audio stream to worry about at address 0:1. Note it is labelled s16 which means that it is a signed 16-bit depth audio stream. These details will be important in a moment.

Next comes the extraction:

Update 2017-09-10: I now think it is much more straightforward to trust FFMPEG to do the right thing:

for i in BDMV/STREAM/*.m2ts; do ffmpeg -hide_banner -i "$i" -map 0:1 "$(basename "${i%.*}").flac"; done

Note that I do not set the audio codec, and merely set the file extension to .flac as that is the format that I want.

For reference, this is original command I used:

for i in BDMV/STREAM/*.m2ts; do ffmpeg -hide_banner -i "$i" -map 0:1 -acodec pcm_s16le "$(basename "${i%.*}").wav"; done

The -map 0:1 refers to our address from earlier. The s16 part of -acodec pcm_s16le matches the description of the stream ffprobe gave us. We cannot use -acodec copy as ffmpeg cannot encode pcm_bluray.

Make sure to use .wav at the end of the filename, as ffmpeg considers it important. I was originally trying to use .pcm, but all I got was this error message:

[NULL @ 000000000283dc20] Unable to find a suitable output format for '00002.pcm'

If you have multiple streams, re-run this command, changing -map, -acodec and the output filename (to not overwrite your previous extractions!) as appropriate.

Removing initial silence

After I had extracted the audio, I noticed that every track had about 1.0-1.6 seconds of silence at the beginning. I had no interest in keeping this, so I used ffmpeg with the silenceremove filter:

mkdir no-silence
for i in *.wav; do ffmpeg -i "$i" -af silenceremove=start_periods=1:detection=peak "no-silence/$(basename "$i")"; done

start_periods=1 means remove one block of silence from the beginning of the track, a.k.a. the silence before any audio begins. I use detection=peak because I know I’m working with audio with digital silence; if you’re working with audio that was originally recorded from analogue, omit this option.

Putting it all together

Incidentally, this filter could have been added to the original extraction command, if I knew that I wanted it at the time. :)

Update 2017-09-10: As above, I now think it is much more straightforward to trust FFMPEG to do the right thing:

for i in BDMV/STREAM/*.m2ts; do ffmpeg -hide_banner -i "$i" -map 0:1 -af silenceremove=start_periods=1:detection=peak "$(basename "${i%.*}").flac"; done

For reference, this is original command I used:

for i in BDMV/STREAM/*.m2ts; do ffmpeg -hide_banner -i "$i" -map 0:1 -acodec pcm_s16le -af silenceremove=start_periods=1:detection=peak "$(basename "${i%.*}").wav"; done

Update 2017-05-14: Changed ${i/.*} to ${i%.*} to remove file extensions, as the new way will only remove everything following the last . in the filename, not the first. Thanks to my good friend Mark Holland-Avery for the suggestion!

Using the option key in macOS Terminal

I like using the Meta+left/right to navigate back and forth between words. On macOS by default, no key is mapped to Meta!

Fortunately for me, it is possible to configure the Option key to act as a Meta key. With the Terminal app selected, this can be done by going in to Terminal > Preferences (Cmd+,) > Profiles > Select your profile > Keyboard > Use Option as Meta.

React: Unexpected token <

I’ve been fiddling around with React recently and made some pages with some normal-looking URLs, despite being a single-page application. This was done using React Router and configuring it to use the History API with browserHistory. Here is one of those URLS:

http://localhost:3000/course/react-flux-building-applications

When the page was refreshed (either manually or by the hot loader), or when I visited that page manually, I got this odd error in the console:

Unexpected token <

When I inspected the contents of bundle.js, which is what I had configured webpack to bundle all of my JS in to, I noticed it wasn’t JS at all; it was the HTML for my index page!

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Pluralsight Admin</title>
</head>
<body>
    <div id="app"></div>
    <script src="bundle.js"></script>
</body>
</html>

After a few moments of wondering, I realised what had happened. It was pretty dumb. Can you see it?


What happened is that bundle.js was being loaded from:

http://localhost:3000/course/bundle.js

And not:

http://localhost:3000/bundle.js

Since the URL was not recognised, webpack or React Router (I’m unsure exactly which) merely served index.html instead of a 404 error.

This meant that HTML was served for a JS request!

The simple fix is to change:

<script src="bundle.js"></script>

To:

<script src="/bundle.js"></script>

That way the requests always go to http://localhost:3000/bundle.js.

This may need to be solved slightly better if I don’t want to host the application at the root of a domain, but it’ll work for now while I experiment!

Working around Chroma Subsampling over HDMI on Nvidia cards

If you have chroma subsampling issues when connecting a display via HDMI on an Nvidia card, despite all the settings appearing as if there shouldn’t be any, try creating a new custom profile at a fractionally higher refresh rate and using that new profile.

  1. Go in to the Nvidia Control Panel.
  2. Go to Display > Change resolution
  3. Select Customise…
  4. Check “Enable resolutions not exposed by the display”
  5. Select Create Custom Resolution…
  6. Select the correct horizontal pixels, vertical pixels, colour depth and scan type. Then enter the desired Refresh rate, and add 1 to it.
    • The Nvidia Control Panel does not allow you to create duplicates of profiles that exist by default. So changing the refresh rate ensures that the new profile is not a duplicate, and means you do not need to change resolution.
  7. Test the profile, save it, exit the customise window.
  8. Select your new resolution off the list, and click Apply.

With any luck, your new profile will not have any chroma subsampling, leaving your colours (particularly reds) looking good, especially on menus.

Printing Brother labels through GIMP

I’ve been fiddling with a Brother P-Touch D600, which is able to connect to a computer through USB. Since I’ve realised that it appears to Windows as a standard printer, I’ve been trying to see if any applications can print to the device. They can!

Notepad works (albeit not in the most useful fashion). But I had a bit of trouble with GIMP.

I found that, for some reason, even after setting the correct image/DPI settings and running through page setup, GIMP still seems to think it is printing via A4. I’m unclear where the problem comes from, but it can be worked around when you go to print.

After selecting Print, select the Image Settings tab, and ensure the image is aligned to the top-left corner. You’ll need to factor in a margin. On my 24mm labels, I set a top and left margin of 3mm or so.

How to update Qualcomm Atheros QCA61x4 drivers

Qualcomm seem to make up-to-date wireless and wireless+bluetooth drivers available to Killer Networking first. Forunately you are able to download and install them yourself.

  1. Go to the Killer Networking driver page.
  2. Download the Standard drivers (no Killer Features).
  3. If your wireless adapter has Bluetooth, download the Bluetooth drivers as well.
    • My QCA61x4 device has Bluetooth, so I downloaded the Bluetooth driver for the K1525/1535.
  4. Install the driver(s) in the usual manual way: Device Manager > your wireless adapter > Driver > Update driver… > Browse > Let me pick > Have disk… > Browse to driver.
    • In my case, the k11acw10 directory worked for the wireless adapter.
    • If Windows complains there is no valid driver, try another directory.

Bonus chatter: The driver needed updating as it was causing BSODs. A very helpful post by Glenn Meuth on this forum thread helped me identify the unreliable driver via analysing the BSOD’s memory dump.