{"id":1188,"date":"2010-07-10T16:00:16","date_gmt":"2010-07-10T23:00:16","guid":{"rendered":"https:\/\/www.reenigne.org\/blog\/?p=1188"},"modified":"2010-07-05T22:10:09","modified_gmt":"2010-07-06T05:10:09","slug":"what-happened-to-directsound","status":"publish","type":"post","link":"https:\/\/www.reenigne.org\/blog\/what-happened-to-directsound\/","title":{"rendered":"What happened to DirectSound?"},"content":{"rendered":"<p>Some years ago, I was tinkering about with some sound synthesis code in Windows. This was in the pre-Vista days, and the officially recommended way of doing sound output was using DirectSound. My application was interactive, so I wanted to make it as low latency as possible without having too much overhead. I set it up with a buffer size of 40ms (3,528 bytes). I then set up IDirectSoundNotify with two pointers, one at the middle of the buffer and one at the end. Whenever one was triggered I would fill the other half of the buffer. This all worked great.<\/p>\n<p>At least, it did until I came back to the code some years later, after having upgraded the OS on my laptop to Windows Vista (the hardware hadn&#8217;t changed). Suddenly this code which worked great before sounded horrible &#8211; the sound was all choppy as if only half of the buffers were being played. What happened?<\/p>\n<p>After some experimentation, I discovered that the jittering happened with a buffer of less than 7,056 bytes (80ms) but not with larger buffers. Armed with this evidence and a bit of pondering, I have a good theory about what happened.<\/p>\n<p>The Windows audio system was <a href=\"http:\/\/blogs.msdn.com\/b\/larryosterman\/archive\/2005\/09\/19\/471346.aspx\">drastically rewritten<\/a> in Windows Vista and DirectSound was re-implemented &#8211; instead of a thin layer over the driver, it became a high level API implemented on top of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Technical_features_new_to_Windows_Vista#Audio_stack_architecture\">Windows Audio Session API (WASAPI)<\/a>. In doing so, it lost some performance (it&#8217;s no long hardware accelerated) and, it seems, suffered an increase in latency &#8211; the DirectSound implementation uses a 40ms buffer (I think). That&#8217;s all very well, but there&#8217;s a bug in the implementation &#8211; IDirectSoundNotify fails to trigger if the positions are more closely spaced than this.<\/p>\n<p>The preferred API for this kind of thing is now XAudio2 which is actually a little bit nicer (the code to do the same thing is slightly shorter) and works on both XP and Vista (unlike WASAPI). I can&#8217;t really fault Microsoft too much since apparently this particular use of IDirectSoundNotify is rather unusual (or they would have made it work) but still it&#8217;s annoying that DirectSound went from being the recommended API to buggy and (practically if not technically) deprecated in a single Windows version. Still, I understand that the world of Linux audio is even worse (albeit getting slowly better).<\/p>\n<p>I wonder why audio APIs seem to go through so much churn relative to graphics (given that audio is that much less complicated, and that the hardware isn&#8217;t really changing much any more). I sometimes wish all the audio APIs were as simple as a &#8220;get the next sample&#8221; callback API but I guess this is too CPU intensive, or at least was when the APIs were designed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some years ago, I was tinkering about with some sound synthesis code in Windows. This was in the pre-Vista days, and the officially recommended way of doing sound output was using DirectSound. My application was interactive, so I wanted to make it as low latency as possible without having too much overhead. I set it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1188","post","type-post","status-publish","format-standard","hentry","category-computer"],"_links":{"self":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/1188","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/comments?post=1188"}],"version-history":[{"count":1,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/1188\/revisions"}],"predecessor-version":[{"id":1189,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/1188\/revisions\/1189"}],"wp:attachment":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/media?parent=1188"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/categories?post=1188"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/tags?post=1188"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}