Things I’ve learned, published for the public benefit
Trying To Be Helpful header image

In search of a quiet PSU: Second Edition

The world of computer power supplies is a strange one. We have smart, knowledgeable reviewers like Aris Mpitziopoulos of Tom’s Hardware or Jeremy Schrag of JonnyGuru going into pornographic detail describing 1% differences in efficiency or voltage stability, even though such things never make a noticeable difference in real life (assuming you’ve bought a decent, brand-name PSU). Meanwhile, electrical noise (generally known as “coil whine”), which affects the user’s daily comfort in a very tangible way, barely gets mentioned.

I am not an EE nerd who salivates over ripple graphs. I’m just a guy who wants a solid PSU that doesn’t make noise, just like in the old days. The last time I was looking for a new PSU was in 2012 – the search ended in a resounding defeat. I spent dozens of hours testing five different power supplies. In the end, every single one had more electrical noise than my Corsair HX520 from 2007, though one of them (the entry-level Be Quiet! model) came close. In the end, I just decided to stick to my old Corsair. After 10 years of constant use, it’s working perfectly well, thanks for asking.

If I’m so happy with my HX520, why am I writing a new post about PSUs? Well, I recently bought a new video card (a GTX1070 from MSI). As every silent PC enthusiast knows, modern graphics cards generate tremendous amounts of coil whine, and my unit is no different. Tellingly, my HX520, which was dead silent with my previous card (an AMD HD7850), started making electrical noise – specifically, reproducing the coil whine of the video card. I know it isn’t just the noise of the card bouncing around, because I took the PSU out of the case and put my ear to it. This seems to suggest that maybe my beloved Corsair isn’t as spotless as I thought.

The second reason is that, when I was buying the GTX1070, I got into a conversation with the salesman about coil whine. He mentioned that he used to have a huge coil whine problem on his card, but that he managed to reduce the noise by getting a new PSU.

Finally, I was also curious to see if the acoustics of power supplies had improved over the past 5 years.

So I ordered three PSUs – all of them praised on the Internet for being particularly quiet: the Corsair RM650x, the Be Quiet! Pure Power 10 600W, and the BitFenix Whisper M 550W.

What’s your setup?

  • Motherboard: Asus P8Z77-V Pro
  • CPU: Intel i5 3570K (overclocked to 4.1 GHz)
  • Video card: nVidia GTX1070 (MSI Gaming X 8 GB)
  • 1 SSD drive and 1 very quiet mechanical hard drive (WD Red 2 TB)
  • Case: Fractal Design Define R4, all optional vents are closed
  • Case fan: 140 mm at 600-700 rpm (in the back of the case)
  • CPU fan: 120 mm at 600-700 rpm
  • GPU fan: I had the fan off while testing the PSU noise (of course not for long)

The computer is about 1 meter away, under a heavy desk. There’s a carpet on the floor.

How did you test for coil whine?

I ran a number of applications that place a high load on the GPU: the Unigine Valley benchmark, the Kombustor benchmark, Far Cry 4, The Witcher 2, Mass Effect 3, Grand Theft Auto IV, Dishonored 2, and Deus Ex: Mankind Divided. Some of these are older titles, because I wanted to generate high framerates (which are known to lead to coil whine). I tested each application with vsync off and on. Predictably, turning vsync on (with a 60 Hz monitor) eliminated coil whine or made it very faint.

Corsair RM650x

I’m a big fan of the Silent PC Review forums. The kind people over there truly care about computer silence, so if they say that some piece of hardware is silent, I know that’s the case. The only other site whose opinions on PSU noise are worth reading is Tom’s Hardware, because they publish the rpm graphs of PSU fans, rather than useless decibel measurements (I know that a 500 rpm fan is inaudible in my setup, but I don’t know what 18 dB means, especially that the sound pressure level depends on the distance at which you take the measurement.)

The Corsair RMx line is probably the most recommended PSU on SPCR. If you also consider my good experiences with the HX520, you see why the Corsair RM650x instantly landed at the top of my shortlist.

The RMx PSUs are semi-passive, which means that the fan in the PSU only turns on when the power drawn by the computer and/or the temperature inside the PSU exceeds a certain threshold. Under “average” conditions, the RM650x is supposed to run fanless up to 260 W, which is why I chose it over the RM550x, for which the threshold is 225 W. (As it turned out, that wasn’t the best decision.)

Now for the big question: is it quiet? Yes, it’s very quiet! To my genuine surprise, the overall electrical noise generated by the GTX1070 + RM650x duo was much lower than for the GTX1070 + HX520. This was true across all the tested apps. Essentially, what seemed to happen was that the PSU was now near-silent (save for some light buzzing that’s inaudible from more than 30 cm) – the only coil whine was coming out of the video card. As a result, the overall electrical noise was cut in half. The boys at SPCR didn’t lie. The Corsair RM650x is an excellent PSU for the silent PC enthusiast.

After an hour or two of testing, I couldn’t help but notice that the PSU case got quite hot – hot enough that I couldn’t touch it for more than a couple seconds (so probably > 40°C). This was despite the fact that I was working with an open case and the unit was supplying no more than 300 watts – and even that, only for brief periods. I am certain that the Japanese capacitors used by Corsair, which are rated for 105°C, will take the heat without breaking a sweat. That’s not the issue. The problem is that the PSU radiates heat into my case. I can, of course, remove the excess heat by cranking up my case fan. But then I would end up with noise because the case fan would cross the threshold of audibility. Suddenly, the “dead silent” PSU doesn’t seem so silent anymore.

Testing the RM650x made me realize that I am not a fan of semi-passive power supplies. I would much rather have a PSU with an always-on 500 rpm fan (which I won’t hear anyway) that will help expel hot air out of my case.

Here are some other thoughts about the Corsair RM650x:

  • The fans didn’t immediately switch on after maximizing the power draw with IntelBurnTest and Kombustor simultaneously (reaching total system power of 300 W). It took a few minutes for that to happen, which suggests that the fan speed depends not just on power, but also temperature or time. The fan also stayed on for at least 5 minutes after the test apps were closed. In the Tom’s Hardware review, the fan on the RM550x (the lower model) didn’t turn on below 275 W. (And, according to Corsair, the threshold is higher in the RM650x.)
  • The fan was very quiet once it switched on. I couldn’t hear it even with my head next to the case – the case and CPU fans in my system completely drowned it out. In fact, I had to look to make sure it was running. In the Tom’s Hardware review of the RM650x, the fan turned on at about 325W, slowly reaching 600 rpm at 375 W, then staying at 600 rpm until about 450 W. It’s risky to make statements about a subjective thing like noise, but 600 rpm in a fan located at the bottom of a case should be inaudible to almost everyone, even in the middle of the night. I would therefore expect this PSU to be practically silent in even the most high-powered single-GPU setups.
  • The fan seems to be of a high quality. Unlike with the other two review units, I couldn’t hear any clicking, even with my ear next to the fan.
  • The motherboard ATX connector is hard to plug in. I had to push so hard that it bent the motherboard PCB. Not cool.
  • When I first turned the PSU on, it blew out a fuse in my apartment. The capacitors fill up too quickly, which creates excessive current. I’ve seen reports of this problem with this specific PSU (not sure about the RM550x). If you’re one of the people who turn off their PSU (or the power strip connected to the PSU) at the end of the day, and you want to buy the RM650x, I suggest getting it from a store with a good return policy.
  • The PSU uses daisychained VGA cables, which is nice, because you can connect a card with two power inputs using just one cable.
  • The Corsair RM650x has a crazy 10-year warranty. Talk about having confidence in your product!

Be Quiet! Pure Power 10 600W

After the encouraging experience with the Corsair, it was time to hook up the Be Quiet. The Pure Power 10 is the successor of the Pure Power L8 model that almost won my last PSU comparison, so I was very interested to see if the current generation lives up to that.

The answer is yes! The Be Quiet! Pure Power 10 600W is a very quiet PSU. My electrical noise tests yielded results on par with the Corsair RM650x. Since I don’t have two identical PCs to do a side-by-side comparison, I had to rely on impressionistic notes to compare the PSUs (e.g. “when playing the Witcher 2 at 170 fps at 3 am, the coil noise is barely noticeable when the computer is under the desk”), but – as far as I can tell – these two models are equally quiet in terms of electrical noise.

The Pure Power 10 is not a semi-passive PSU, but the fan spins at a leisurely pace and, in practice, I wasn’t able to hear it over the sound of the rest of my system. In my stress tests, with a total load of 300–350 watts, I was unable to hear the fan spinning up, despite having the PSU just 30 cm away. According to this eTeknix review, the fan stays below 560 rpm up to about 80% load, which explains the excellent noise performance of this model. The active fan of this PSU has a clear advantage over Corsair’s semi-passive solution – the PSU stayed much cooler, even under a heavy load, while still staying inaudible. It seems there is a big difference between 0 rpm and 560 rpm in terms of cooling.

Some further observations about the Be Quiet! Pure Power 10:

  • The Pure Power 10 uses mediocre Chinese capacitors which are rated for 85°C, unlike most enthusiast PSUs nowadays, which use Japanese capacitors rated at 105°C. Heck, even my old Corsair HX520 is 100% Japanese 105°C (which might explain its longevity). Be Quiet clearly views the Pure Power 10 as a budget unit – which is kind of funny, because it only costs €20 less than the RM650x, at least here in Poland.
  • The fan (or something close to the fan) makes soft clicking noises at random intervals. This is only audible when the fan is pointing directly at your ear.
  • There is some doubt about the type of fan used on the Pure Power 10. The official spec says it’s a rifle-bearing fan, while Tom’s Hardware says (in their review of the Pure Power 9, which has the exact same fan model number: BQ QF1-12025-MS) “our sources indicate that the cooling fan has a sleeve bearing”.
  • The Pure Power 10 has a relatively short warranty of 3 years. This could indicate that Be Quiet does not expect the capacitors and/or the fan to last more than a few years.
  • The VGA cable is a little too short. An extra 5 cm would have made it possible to route it a bit better in my Fractal Define R4 case. As on the RM650x, it is daisychained, which allows you to connect two VGA power sockets with one cable.

BitFenix Whisper M 550W (BWG550M)

BitFenix is not normally considered one of the top PSU brands, but their latest Whisper M line has earned a recommendation from Tom’s Hardware and is based on the latest platform from CWT, the company that makes power supplies for Corsair.

The crucial difference between the Whisper and Corsair RMx is that the Whisper has an active fan, which keeps the PSU much cooler. The difference is quite dramatic and can be easily felt by touching the PSU chassis after playing a demanding game for 30 minutes. At the same time, BitFenix gave the fan a very quiet profile: in the Tom’s Hardware test, it stayed at 400 rpm up to 325 W, then slowly spun up to 600 rpm at 375 W – this is at ambient temperatures of 34–46 °C. The fan’s speed is temperature-dependent, so if the temperature inside your case is lower (it likely is), you will be able to reach higher wattage while staying below 600 rpm. In my tests, I was unable to make the fan audible over the rest of my system, despite stress testing my system rather vigorously, and sitting right next to the PSU.

What about the primary target of this comparison – coil whine? I’m happy to report that the BitFenix Whisper M 550W is every bit as coil-whine-free as the Be Quiet! and the Corsair.

Some more comments on the BitFenix:

  • The Whisper uses an FDB fan, which is theoretically very good, but – according to Tom’s Hardware – the model they used is only rated for 30,000 hours. At 12 hours a day, this is only 7 years, though one can hope that the slow rotational speed will extend the lifetime.
  • The fan has the same random clicking disease as the fan on the Be Quiet, except that the clicking happens more frequently. It’s inaudible unless the fan is facing you – the only problem is that it makes me worry about the long-term reliability of the fan.
  • The PSU uses a 135 mm fan. If you ever need to replace it, good luck finding a quality fan in that size.
  • The VGA power cable is not daisychained, which means that I need to route two separate cables from the PSU to my nVidia 1070 card.
  • On the other hand, the SATA power cables are super-long with 4 connectors each. This is the first PSU that has allowed me to connect my DVD-ROM and two hard drives with one cable.
  • The ATX cable is made up of 4 separate ribbons. I’m not sure what BitFenix was thinking here, but these cables take up more space than a standard sleeved round cable, and are more difficult to route behind your motherboard because you need to place them flat against the motherboard tray (at least my case wouldn’t close otherwise), which is very hard because they’ll twist around. In the end, I gave up and routed the ATX cable behind my hard drives, which is not ideal. Ribbons are a bad idea for huge cables!
  • The ATX plug is huge because it houses a bunch of capacitors to further reduce ripple (see here for photo). As far as I can tell, this accomplishes no useful goal, other than impressing the EE nerds who write PSU reviews. I love EE nerds, but that damn plug makes it harder to route the ATX cable and I daresay even blocks some airflow to the RAM sticks. At least the plug itself goes in and out easily, unlike on the Corsair RMx. It’s also a 24-pin plug, so there’s none of the 20+4 nonsense to deal with.
  • BitFenix backs the Whisper M with a 7-year warranty. Not as good as Corsair’s 10 years, but still very nice.
  • At the time of this writing, the BitFenix Whisper M 550 W is only €5 cheaper than Corsair RM550x.

Decisions, decisions

Well, what do you know – the quality of computer power supplies seems to have gone up over the past few years. Whereas five years ago I had to concede defeat in my quest to find a PSU to equal my almost ancient Corsair HX520, this time I have gotten my hands on no less than three PSUs that reduce the overall electrical noise in my system by about 50% when paired with my MSI Gaming X 1070 graphics card.

In a quiet room in the middle of the night, with a well-insulated case placed under a desk, I can just notice some coil whine (usually a kind of buzz) in demanding applications, especially with high framerates. I have to make a bit of an effort to hear it. If I put the computer on the desk, or had a less insulated case, it would of course be a different story. Is that a result I’m totally happy with? Heck no. I believe electrical devices should not be heard (unless they’re speakers). But until video card manufacturers start designing less noisy products, it’s a result I can live with.

With all the tested PSUs offering virtually identical performance in the noise department, I have to make a decision based on secondary considerations:

  • The Corsair RM650x is an excellent model with quality components and a crazy long warranty, but the semi-passive cooling means it runs quite hot, even without extreme load. I don’t want to deal with extra heat in my already hot case, so the Corsair was the first PSU that I eliminated. (The lower-rated brother, Corsair RM550x, turns on the fan a bit earlier, but the threshold is only 35W lower and it wouldn’t make much of a difference.)
  • The Be Quiet! Pure Power 10 600W runs much cooler than the Corsair, but the cheap Chinese capacitors and the relatively short warranty make me worried that it will not last more than a few years. (The higher-end Straight Power model also uses Chinese caps. Be Quiet! has announced a new generation of the Straight Power, to be released in the fall of 2017, which will have 100% Japanese caps.)
  • My personal winner? The BitFenix Whisper M 550W. It combines the cool operation of the Be Quiet! with the uncompromising component quality of the Corsair. The long-term reliability of the fan is a bit of an unknown in light of the unimpressive 30,000 h rating, and the non-typical fan size would make replacing it a challenge – if anything goes wrong, I will just have to use the 7-year warranty.

→ No CommentsTags:

Review of the Dell U2415 LCD monitor

It was 7 years ago that I last bought a display for my desktop PC. The display I picked then – the Dell 2209WA – is still kicking, although it has begun to show signs of advanced age. The CCFL backlight has yellowed and dimmed, and the panel now has a weird dark smear in its left half. It is a display that doesn’t believe in climate change, happily guzzling 50 watts of power and giving off enough heat to make the entire backplate hot to the touch.

So far, my display strategy has been to hold off on an upgrade until someting really great comes along. “Maybe this year we’ll finally get affordable OLED displays? Maybe this is the year that Windows gets proper support for Retina screens?”, I would think, every year – until I got tired of waiting and decided to order the Dell U2415, a display that Wirecutter has singled out as the best 24″ monitor. I admit one of my reasons was curiosity – I wanted to see how much display technology has improved in 7 years. With so many commenters gushing over the picture quality on the U2415, maybe I was missing out?

[Read more →]

→ 2 CommentsTags:

FAQ about the constitutional crisis in Poland

If you happen to be interested in European politics, you might want to check out my FAQ about the current constitutional crisis in Poland. (A constitutional crisis is what happens when two or more branches of the government fight so intensely that basic cooperation is impossible.) It took me over 100 hours to write – mostly because I had to do a lot of research about legal issues, including talking to constitutional lawyers.

Polish Constitutional Crisis – FAQ

Kryzys konstytucyjny – FAQ

→ 2 CommentsTags:

Plasticity 1.2: Keyboard shortcuts, mobile support, and some eye candy!

I’ve just released a new version of my music training / anti-tinnitus Web app Plasticity. Here is a list of changes:

  • Keyboard shortcuts with WASD keys should make long training sessions easier (per Lord Denton’s request)
  • Mobile support with a responsive design lets you train when you don’t have your computer with you. Please use high-quality headphones and make sure all “audio enhancements” (built-in sound distortion) are disabled on your device.
  • Eye candy: Pretty sweet slide in/out transitions between questions, re-rendered high-resolution images for retina screens, redesigned buttons (uniform across platforms)
  • Improved performance when replaying last tone
  • Tested on Firefox, Chrome (Win/Android), Safari (Mac/iOS). (Worked around a Web Audio bug in Safari which sometimes resulted in sounds no longer playing until the game is restarted.)

→ 1 CommentTags:

Technicolor TC7200 router freezes under load – solution

I have a Technicolor TC7200 cable modem/router which was forced on me by my cable provider (UPC). After one of the automatic firmware updates last year, I started having intermittent problems with stability. The router would suddenly “freeze” with the following symptoms:

  • No websites can be opened
  • DNS requests fail
  • Existing connections keep working (all downloads started before the freeze just keep going)
  • Other machines connected to the same router work fine
  • If you do nothing, connectivity will come back after a while (10 minutes?)
  • Right-clicking the network adapter in Windows and choosing Diagnose successfully restores connectivity, even though Windows reports no issues.

The issue would mostly arise under heavy load. Whenever I opened a lot of new connections (for example, many concurrent downloads, streaming video in several tabs, multiple torrents downloading), I could be reasonably sure that a freeze would occur within 1-20 minutes. It would also occur 1-2 times a day regardless of the load.

Solution

The Technicolor TC7200 does not work properly if you change its default IP address. I had changed the router’s IP address from the default (192.168.0.1) to 192.168.1.1 because that was the address of my previous router and I wanted to spare myself some reconfiguration.

Changing the address of the router back to 192.168.0.1 (and moving all the devices on my LAN back to the 192.168.0.xxx subnet) has completely eliminated the issue. For the past month or so, I’ve had zero freezes despite my attempts to trigger one. Just to be sure, I briefly changed the subnet to 192.168.1.xxx, and – you guessed it – the issue came back.

Polish version

Router Technicolor TC7200 instalowany standardowo przez UPC nie obsługuje prawidłowo sieci lokalnych, których podsieć jest inna niż domyślna (192.168.0.xxx). W przypadku ustawienia w panelu administracyjnym adresu routera innego niż 192.168.0.1 (czyli np. 192.168.1.1), urządzenie zacznie od czasu do czasu się “zawieszać”, a dokładniej blokować możliwość nawiązywania nowych połączeń z danego komputera (wygląda to tak, że nie otwierają się nowe strony, nie działa DNS). Charakterystyczne jest to, że dotychczasowe połączenia trwają nadal (czyli np. pobieranie pliku rozpoczęte przed “zwisem” będzie kontynuowane) oraz że inne urządzenia w tym samym LAN-ie działają w tym czasie bez zarzutu. Problem pojawia się zwłaszcza pod obciążeniem – w przypadku otwarcia wielu połączeń, pobierania/wysyłania dużej ilości danych. Po powrocie do domyślnej podsieci (192.168.0.xxx) problem znika.

Więcej szczegółów powyżej w wersji angielskiej.

→ 1 CommentTags:

Sublime Text 3 doesn’t play well with Equalizer APO and other applications that monitor file changes

I just spent a day investigating a really baffling bug that occurred when I installed Equalizer APO on a new Windows machine. (Equalizer APO is a free equalizer that plugs into the Windows Audio subsystem, which lets you, among other things, correct the acoustic flaws of your room to dramatically improve the quality of all audio playing on your computer. Maybe I’ll write a post about it some day — it’s awesome.)

Equalizer APO uses a plain text config file (config.txt) that it constantly monitors for changes using a mechanism provided by Windows. Normally, you can hear the sound playing on your PC change within a few seconds of saving the file. Soon after installing Equalizer APO on a fresh Windows installation, I noticed that the changes I was making in config.txt were often being ignored. For example, the first two changes after reboot might get applied, but subsequent changes would be ignored. I tried fiddling around with folder permissions and moving the config.txt file to various locations on the hard drive, which seemed to fix the issue for some time (usually until the next reboot).

The weirdest thing was that whenever I changed config.txt, Equalizer APO wrote the following message to its log:

Error while reading configuration file:
The system cannot find the file specified.

This did not make any sense at all. How could Equalizer APO not find a file that was clearly there? And why was it unable to find the file only some of the time? After spending an hour studying the source code for Equalizer APO, I grew convinced that the only possible reason was a bug in Equalizer APO which somehow blocks access to the config.txt file (after all, weird contention issues are not unheard of in multithreaded apps) combined with an obscure Windows bug which results in CreateFile() reporting a sharing violation as a missing file.

After submitting a lengthy and detailed bug report to the author of Equalizer APO, I accidentally opened config.txt in Notepad instead of Sublime Text 3, my go-to text editor…

Impossible. The problem was gone. I could edit the file as much as I wanted, and every change was applied. Back to Sublime Text 3 — it stopped working. I tried opening the file in Komodo Edit — it worked just like it did in Notepad.

A-ha! Clearly Sublime Text 3 was doing something weird with the file. Could it somehow be hiding the file from Equalizer APO?

It turns out, when you save a file in Sublime Text 3, in its default configuration, it doesn’t simply overwrite it like all other editors. Instead, it does the following:

  1. Write the modified text into a temporary file.
  2. Delete the original file.
  3. Rename the temporary file so that it looks like the original file.

At the exact moment when ST3 deleted the original file, Windows would notify Equalizer APO about the “change” and cause it to re-read the file. If the read operation was quick enough (which would have depended on things like the overall disk load), Equalizer APO would find the file missing.

Why does Sublime Text 3 save your files in such a weird way? It’s supposed to be a safety feature. If ST3 simply overwrote the original file and something really bad happened during the overwrite, you could lose data. Making a temporary file first guarantees that you will always be able to get your data back.

However, this roundabout way of modifying files can cause problems with software that monitors file changes. I’m not just talking about the scenario that gave me the headache which occasioned this post, but other scenarios as well. For example, there are backup and versioning apps which monitor filesystem changes. To such an app, a save operation in ST3 will look like a file got deleted, and then a new file got created, which may ruin the association between the current version of the file and its earlier versions. For real-life reports of problems like that, see the previously linked thread on the ST forum and this StackOverflow question.

According to the above sources, the “atomic save” feature can be disabled in ST3 by editing user preferences, but I could not get it to work (in build 3065). In the end I simply downgraded to ST2.

→ 3 CommentsTags:

Plasticity and Online Tone Generator now work in Firefox and Chrome

I have just uploaded new versions of Plasticity – my audio training game which may also alleviate tinnitus – and my increasingly popular Online Tone Generator – a handy tool for those times when you need your speakers to produce a specific frequency, and nothing else. The current versions use the HTML5 Web Audio API and have been tested to work on Chrome 33 and Firefox 28, at least on Windows. (They might also work on recent versions of other browsers – it’s worth a try.) Enjoy!

→ 5 CommentsTags:

Web Audio API – things I learned the hard way

Firefox recently dropped support for the Mozilla Audio Data API, so I started porting my two audio-enabled Web apps (Plasticity and Online Tone Generator) to the Web Audio API, which is the W3C-blessed standard way to work with audio in the browser.

In the process, I ran into a few problems, which I thought I’d share here for the benefit of other developers making their first steps with the Web Audio API.

AudioBufferSourceNodes and OscillatorNodes are single-use entities

Suppose we want to generate two 440 Hz tones, each with a duration of 1 second, separated with a 1-second pause. This is not the way to do it:

oscillator = context.createOscillator();
oscillator.frequency.value = 440;
oscillator.connect(context.destination);
currentTime = context.currentTime;
oscillator.start(currentTime);
oscillator.stop(currentTime + 1); //stop after 1 second
oscillator.start(currentTime + 2); //resume after 2 seconds
oscillator.stop(currentTime + 3); //stop again after 3 seconds

What’s wrong? We cannot call .start() on an OscillatorNode or AudioBufferSourceNode more than once. The second call in the above code will result in an error. Both OscillatorNodes (which are used to generate simple tones) and AudioBufferSourceNodes (which are used to play back short samples like sound effects) are meant to be thrown away after each use.

Instead, we should create a separate node for every time we want to play a sound. Every time, we must also connect it to the audio graph:

oscillator = context.createOscillator();
oscillator.frequency.value = 440;
oscillator.connect(context.destination);
currentTime = context.currentTime;
oscillator.start(currentTime);
oscillator.stop(currentTime + 1);

oscillator2 = context.createOscillator(); //create 2nd oscillator
oscillator2.frequency.value = 440;
oscillator2.connect(context.destination);
oscillator2.start(currentTime + 2);
oscillator2.stop(currentTime + 3);

ChannelMergerNode inputs don’t map to channels

Warning: This will be fixed in the next Working Draft of the W3C spec; the below text will eventually become obsolete when browsers implement the new spec.

What do you do when you have two mono sources – like OscillatorNodes, which are always mono, or AudioBufferSourceNodes connected to a mono buffer – and you want to mix them into a stereo signal, for example, play one sample in the left channel, and the other in the right? You use a ChannelMergerNode.

A ChannelMergerNode has a number of inputs, but only one output. It takes the input audio signals and mixes them into a single multichannel signal. Sounds pretty simple, but it’s easy to fall into the trap of assuming that inputs correspond to channels in the output signal. For example, take a look at the following code, which tries to play a tone on the right channel only:

oscillatorR = context.createOscillator();
oscillatorR.frequency.value = 440;
mergerNode = context.createChannelMerger(2);
//create mergerNode with 2 inputs
mergerNode.connect(context.destination);

oscillatorR.connect(mergerNode, 0, 1);
//connect output #0 of the oscillator to input #1 of the mergerNode
//we're leaving input #0 of the mergerNode empty
currentTime = context.currentTime;
oscillatorR.start(currentTime);
oscillatorR.stop(currentTime + 2);

The result of running this code is a tone playing in both channels at the same time. Why? Because inputs of a ChannelMergerNode do not map to channels in the output signal. If an input is not connected, ChannelMergerNode will ignore it. In this case, the first input (numbered 0) is not connected. The only connected input is #1, and it has a mono signal. ChannelMerger merges all the channels on all the connected inputs into a single output. Here, it receives only a single mono signal, so it will output a mono signal, which you will hear coming from both speakers, as you always do with mono sounds.

The right way to have a sound playing only in one channel is to create a “dummy” source node and connect it to the ChannelMergerNode:

context = makeAudioContext();
oscillatorR = context.createOscillator();
oscillatorR.frequency.value = 440;
mergerNode = context.createChannelMerger(2); //create mergerNode with 2 inputs
mergerNode.connect(context.destination);

silence = context.createBufferSource();
silence.connect(mergerNode, 0, 0);
//connect dummy source to input #0 of the mergerNode
oscillatorR.connect(mergerNode, 0, 1);
//connect output #0 of the oscillator to input #1 of the mergerNode
currentTime = context.currentTime;
oscillatorR.start(currentTime);
oscillatorR.stop(currentTime + 2);

You create a silence node by creating an AudioBufferSourceNode, just like you would for any sample, and then not initializing the buffer property. The W3C spec guarantees that this produces a single channel of silence. (As of April 2014, this works in Chrome, but does not work in Firefox 28. In Firefox, the input is ignored and the result is the tone playing on both channels.)

Update: I’m happy to say that my feedback to the W3C Audio Working Group has resulted in changes to the spec. Per the latest Editor’s Draft, ChannelMergerNodes accept up to 6 mono inputs (other types of inputs will be downmixed to mono), with empty inputs treated as silence rather than omitted. Now the changes have to be published in the next Working Draft, and then the browsers have to implement them.

Unused nodes get removed automatically

You might think that if you want to have two sounds playing in different channels – one sound in left, another in right – you don’t need to create dummy nodes. After all, the ChannelMergerNode will have two input channels.

In the code below, we want to play a 440 Hz tone in the left channel for 2 seconds, and a 2400 Hz tone in the right channel for 4 seconds. Both tones start at the same time.

oscillatorL = context.createOscillator();
oscillatorL.frequency.value = 440;
oscillatorR = context.createOscillator();
oscillatorR.frequency.value = 2400;
mergerNode = context.createChannelMerger(2); //create mergerNode with 2 inputs
mergerNode.connect(context.destination);

oscillatorL.connect(mergerNode, 0, 0);
//connect output #0 of the oscillator to input #0 of the mergerNode
oscillatorR.connect(mergerNode, 0, 1);
//connect output #0 of the oscillator to input #1 of the mergerNode
currentTime = context.currentTime;
oscillatorL.start(currentTime);
oscillatorL.stop(currentTime + 2); //stop "left" tone after 2 s
oscillatorR.start(currentTime);
oscillatorR.stop(currentTime + 4); //stop "right" tone after 4 s

This code works as expected for the first 2 seconds – each tone is audible only on one channel. But then the left tone stops playing, and the right tone starts playing on both channels. What’s going on?

  1. When oscillatorL stops playing, it gets disconnected from mergerNode and deleted. The browser is allowed to do this because – as you recall – an OscillatorNode or AudioBufferSourceNode can only be used once, so after we call oscillatorL.stop(), oscillatorL becomes unusable.
  2. The ChannelMergerNode notices that it is left with only one channel of input, and starts outputting a mono signal.

As you can see, the most stable solution, if you want to access individual audio channels, is to always have a dummy node (or several, if you’re dealing with 5.1 or 7.1 audio) connected to your ChannelMergerNode. What’s more, it’s probably best to make sure the dummy nodes remain referenceable for as long as you need them. If you assign them to local variables in a function, and that function returns, the browser may remove those nodes from the audio graph:

function playRight()
{
    var oscillatorR = context.createOscillator();
    oscillatorR.frequency.value = 440;
    var mergerNode = context.createChannelMerger(2);
    mergerNode.connect(context.destination);
    var silence = context.createBufferSource();
    silence.connect(mergerNode, 0, 0);
    oscillatorR.connect(mergerNode, 0, 1);
    currentTime = context.currentTime;
    oscillatorR.start(currentTime);
    oscillatorR.stop(currentTime + 2);    
}

playRight();

Consider what happens at the time playRight() finishes. oscillatorR won’t get removed because it’s playing (scheduled to stop in 2 seconds). But the silence node is not doing anything and when the function exits, it won’t be referenceable, so the browser might decide to get rid of it. This would of course switch the output of the ChannelMergerNode into mono mode.

It’s worth noting that the above code currently works in Chrome, but it might not in the future. The W3C spec gives browsers a lot of leeway when it comes to removing AudioNodes:

An implementation may choose any method to avoid unnecessary resource usage and unbounded memory growth of unused/finished nodes. (source)

In Firefox, You cannot modify an AudioBuffer after you’ve assigned it to AudioBufferSourceNode.buffer

The following code attempts to generate and play a 440 Hz tone over a single channel:

SAMPLE_RATE = 44100;
buffer = context.createBuffer(1, 44100*2, SAMPLE_RATE);
//create a mono 44.1 kHz buffer, 2 seconds length
bufferSource = context.createBufferSource();
bufferSource.buffer = buffer;

soundData = buffer.getChannelData(0);
for (var i = 0; i < soundData.length; i++)
  soundData[i] = Math.sin(2*Math.PI*i*440/SAMPLE_RATE);
bufferSource.connect(context.destination);
bufferSource.start(0);

It works in Chrome, but fails in Firefox (28) without any error message. Why? The moment you assign buffer to bufferSource.buffer, Firefox makes the buffer immutable. Further attempts to write to the buffer are ignored.

This behavior is not covered by the W3C spec (at least I couldn’t find any relevant passage), but here’s a Mozilla dev explaining it on StackOverflow.

→ 8 CommentsTags:

Windows bug: AltGr key stops working after you open a “Save As” or “Open File” window

While working on the next release of my Windows app for typing foreign characters and phonetic symbols, I stumbled on a pretty serious bug that affects the use of multiple keyboard layouts on Windows Vista, Windows 7 and (to a lesser extent) Windows 8.

What the bug looks like to the end user

Suppose your default Windows keyboard layout is US English, but you also want to use other keyboard layouts occasionally – maybe you’re an American learning French or a Pole who lives in the US, but wants to write in Polish every now and then. The Language Bar in Windows allows you to set a separate layout for each window, so let’s say you fire up Microsoft Word and change your layout to Polish.

Quick note: The Polish keyboard layout, like most non-English keyboard layouts, makes use of the right-hand Alt key, also known as “AltGr”, which is short for Alternate Graving. For example, to type the letter ł (pronounced like English w), you press AltGr+L.

After typing for a while, you decide to save your document. You bring up the Save As dialog box, type up a filename, and press OK. When you start typing again, you notice that you can no longer type any AltGr characters.

What’s going on? The act of opening the default Windows “Save As” (or “Open File”) dialog disables the AltGr key. The AltGr characters are not accessible in the dialog (you cannot use them in file names). More seriously, once you close the dialog, AltGr will remain broken in your application, even though the Language Bar will report that you are using the correct layout. At first, I thought it was lying, but it’s not – technically, the layout is still in effect. It’s just that the AltGr key is no longer working; it becomes a regular Alt key.

The same happens if your default Windows layout uses AltGr and you set just one window to a non-AltGr layout such as US English. If you open the “Save As” or “Open File” dialog, the right Alt key will turn into AltGr. This means, for example, that hitting right-Alt+F will no longer bring up the File menu.

Which versions of Windows are affected?

I’ve reproduced this bug on Windows Vista, Windows 7, and Windows 8. Windows XP seems immune.

Note that the default setting in Windows 8 is to have a single keyboard layout for all applications. This bug will affect you only if you specifically go to the language settings and choose the option to enable per-app keyboard layouts.

→ 5 CommentsTags:

The right way to stress-test an overclocked PC

Consider the following situation: You’ve overclocked your CPU, set the core voltage (Vcore) to some reasonable number, and then it’s time for some stress testing to make sure your rig is stable. You follow all the standard recommendations that you can find on overclocking forums: you run Prime95 for 12-24 hours, do a few hours of FurMark, and a few hours of IntelBurnTest for good measure. All the tests complete without a hitch. Congratulations! Your system is now considered stable.

But then you run Crysis or Battlefield 3 and you get random lockups and reboots. What’s going on?

The problem is that you stress-tested the CPU and GPU separately. That doesn’t guarantee that your system will be stable when both the CPU and the GPU are under load. Interestingly, loading the GPU can make your CPU unstable!

In other words, to be stable under combined CPU+GPU loads, your CPU may need a higher Vcore than it does for isolated CPU loads. That’s why the Vcore you arrived at using Prime95 or IBT may be too low to guarantee CPU stability when the GPU is under stress.

Here’s the story of how I realized it:

I had overclocked an i5 3570K to 4.3 GHz at 1.25 Vcore. The system had successfully completed the following stress tests:

  1. Prime95 Blend (all cores) for 14 hours
  2. Prime95 Small FFT (all cores) for 8.5 hours
  3. FurMark for 3 hours
  4. IntelBurnTest on Standard for 2 hours
  5. IntelBurnTest on High for 1 hour

Most overclockers would agree that these results look rock-solid. However, when I ran IntelBurnTest and FurMark simultaneously, I was shocked to see FurMark fail almost immediately. I repeated the experiment several times and the time to failure was always between 5 and 30 minutes. I started coming up with hypotheses:

Hypothesis #1: The PSU can’t supply enough power for the combined CPU+GPU load. The Corsair HX520W supplies 480 watts on the 12V line; an overclocked 3570K + HD7850 shouldn’t draw more than 300 W, but there’s also the motherboard, and the PSU is kind of old – who knows, maybe the capacitors have aged?

Refutation: After replacing the PSU with the Be Quiet! Straight Power E9 580 W (564 W on the 12 V line), the symptoms were exactly the same. It wasn’t a PSU problem!

Hypothesis #2: The increased heat production is causing the GPU, CPU, or video card VRMs to overheat.

Refutation: (1) GPU and CPU core temperatures were carefully monitored during stress testing and did not exceed 90°C. (2) During isolated CPU/GPU stress testing, CPU/GPU core temps were the same, yet there were no crashes. (3) With an open case and all fans set to maximum, the CPU+GPU test failed just as quickly. It was not a heat issue.

That left me with only one hypothesis.

Hypothesis #3: Loading the GPU is somehow causing the CPU to lose enough power to become unstable. In other words, the CPU Vcore is set high enough for isolated CPU load, but not high enough for combined CPU+GPU load. This was a novel hypothesis; I hadn’t seen it discussed in any of the overclocking resources that I had read.

Confirmation: In the words of Colonel Hans Landa, that’s a bingo! Upping the Vcore from 1.25 V to 1.275 V improved the stability by a large margin. Instead of failing after 5-30 minutes (as verified in multiple tests), IBT+FurMark failed after 108 minutes. (Notice that if the crashes had been due to overheating, the test would have failed more quickly than before, as increasing the CPU Vcore made the CPU hotter.)

Still, the system was not fully stable. In order to make it IBT+Furmark stable for several hours, I would have probably had to increase Vcore to around 1.3 V. Incidentally, this is close to the Vcore that the CPU chooses automatically for a 4.3 GHz clock speed, if you select the so-called “offset mode” instead of forcing a fixed Vcore. The lesson here would be that Intel knows what they’re doing when choosing these automatic settings.

The right way to ensure your overclock is fully stable

Run FurMark and IntelBurnTest at the same time for a few hours – at least as long as you expect to operate with combined CPU+GPU load. For example, if your typical gaming session is 3 hours, you should run IBT+FurMark for at least 3 hours. Of course more is better.

One tricky part to combined CPU+GPU stress testing is that FurMark needs some free CPU cycles in order to stress the GPU properly. If you fully load the CPU with IBT, Furmark will be bottlenecked and the GPU load will be much less than 100% – on my system it was around 75%.

The solution is to find the right settings for IntelBurnTest that will result in stressing the CPU while leaving just enough free CPU cycles to allow FurMark to get GPU load above 95%. In my case, the highest combined load was produced with IBT set to “High” and 3 threads.

Another piece of advice is to stick to “offset mode”, i.e. let the CPU set the Vcore automatically depending on the clock frequency. This may result in rather high voltages and high power draw (for example, a 3570K @ 4.3 GHz and full load has a Vcore of 1.32 V, which is higher than usually reported by overclockers at this clock speed), but at least you’re using a Vcore that has been blessed (and presumably extensively tested) by Intel.

My personal choice was to scale back my overclock to 4.1 GHz and choose offset mode. This translates to a Vcore of only 1.192 volts under load and, as far as I can tell, complete stability (IBT+Furmark 5 hours with no error) – though of course you can never be 100% sure…

FAQ

Isn’t it overkill to stress-test the CPU and GPU at the same time? That depends. If you’re absolutely sure you’re never going to reach full or near-full CPU+GPU load, then I guess you can stick to standard, isolated stress testing. However, bear in mind that there are games which can place a very high load on the CPU and the GPU at the same time.

Are you saying that most overclocked systems out there are not truly stable? It would seem so. Most overclockers determine a “stable” CPU Vcore based on isolated CPU testing with something like Prime95 or IntelBurnTest. My experience shows that you need a much higher Vcore to ensure stability under combined CPU+GPU load. I suspect most OC’d systems would fail the IBT+Furmark test outlined here rather quickly; they might also crash when running certain games. Of course, my findings would be more trustworthy if someone replicated them – please post your experiences in the comments!

Why would loading the GPU make the CPU unstable? I’m no hardware engineer, but here’s a wild guess: Loading the GPU drains some of the power away from the CPU (or causes small voltage dips from time to time). Therefore, when the GPU is loaded, the CPU will need a higher Vcore to remain stable.

What was your exact setup?

  • Motherboard: Asus P8Z77-V Pro
  • CPU: Intel i5 3570K
  • CPU cooling: Noctua NH-U12P SE2, 120mm Enermax T.B. Silence fan
  • Video card: AMD Radeon HD7850 (MSI Twin Frozr III, 2 GB)
  • GPU cooling: Accelero S1 Plus, 120mm Enermax T.B. Silence fan
  • 16 GB RAM (two 8 GB sticks, Kingston HyperX)
  • SSD: Crucial M4 256 GB, HDD: Western Digital Red 2 TB (WD20EFRX)
  • Case: Fractal Design Define R4
  • Case cooling: 1 rear 140mm Fractal Design Silent Series R2 fan
  • PSUs tested: Corsair HX520W / Be Quiet! Straight Power E9 580W

→ 24 CommentsTags: