{"id":1291,"date":"2011-10-12T19:15:50","date_gmt":"2011-10-12T17:15:50","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1291"},"modified":"2011-10-12T20:36:48","modified_gmt":"2011-10-12T18:36:48","slug":"sample-simultaneous-audio-playback-via-waveform-audio-waveout-api","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1291","title":{"rendered":"Sample: Simultaneous Audio Playback via Waveform Audio (waveOut) API"},"content":{"rendered":"<p>The minimalistic sample demonstrates support of [deprecated] <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd757715%28v=VS.85%29.aspx\">Waveform Audio API<\/a> for multiple playback streams.<\/p>\n<p>Depending on command line parameters, the application starts threads to open audio hardware using separate <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd743866%28v=VS.85%29.aspx\">waveOutOpen<\/a> call and stream one or more generated sine waves:<\/p>\n<ul>\n<li>1,000 Hz sine wave as 22,050 Hz, Mono, 16-bit PCM (command line parameter &#8220;a&#8221;)<\/li>\n<li>5,000 Hz sine wave as 32,000 Hz, Mono, 16-bit PCM (command line parameter &#8220;b&#8221;)<\/li>\n<li>15,000 Hz sine wave as 44,100 Hz, Mono, 16-bit PCM (command line parameter &#8220;c&#8221;)<\/li>\n<\/ul>\n<pre style=\"color: #000000; background: #ffffff;\">Check<span style=\"color: #808030;\">(<\/span><span style=\"color: #400000;\">waveOutOpen<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">&amp;<\/span>hWaveOut<span style=\"color: #808030;\">,<\/span> WAVE_MAPPER<span style=\"color: #808030;\">,<\/span> <span style=\"color: #808030;\">&amp;<\/span>WaveFormatEx<span style=\"color: #808030;\">,<\/span> <span style=\"color: #7d0045;\">NULL<\/span><span style=\"color: #808030;\">,<\/span> <span style=\"color: #7d0045;\">NULL<\/span><span style=\"color: #808030;\">,<\/span> CALLBACK_NULL<span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\nATLASSERT<span style=\"color: #808030;\">(<\/span>hWaveOut<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\nWAVEHDR<span style=\"color: #808030;\">*<\/span> pWaveHeader<span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #603000;\">HGLOBAL<\/span> hWaveHeader <span style=\"color: #808030;\">=<\/span> <span style=\"color: #808030;\">(<\/span>WAVEHDR<span style=\"color: #808030;\">*<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #400000;\">GlobalAlloc<\/span><span style=\"color: #808030;\">(<\/span>GMEM_MOVEABLE <span style=\"color: #808030;\">|<\/span> GMEM_SHARE<span style=\"color: #808030;\">,<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> <span style=\"color: #808030;\">*<\/span>pWaveHeader <span style=\"color: #808030;\">+<\/span> WaveFormatEx<span style=\"color: #808030;\">.<\/span>nAvgBytesPerSec <span style=\"color: #808030;\">*<\/span> <span style=\"color: #008c00;\">10<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\npWaveHeader <span style=\"color: #808030;\">=<\/span> <span style=\"color: #808030;\">(<\/span>WAVEHDR<span style=\"color: #808030;\">*<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #400000;\">GlobalLock<\/span><span style=\"color: #808030;\">(<\/span>hWaveHeader<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\nATLENSURE_THROW<span style=\"color: #808030;\">(<\/span>pWaveHeader<span style=\"color: #808030;\">,<\/span> E_OUTOFMEMORY<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\npWaveHeader<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>lpData <span style=\"color: #808030;\">=<\/span> <span style=\"color: #808030;\">(<\/span><span style=\"color: #603000;\">LPSTR<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">(<\/span><span style=\"color: #603000;\">BYTE<\/span><span style=\"color: #808030;\">*<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">(<\/span>pWaveHeader <span style=\"color: #808030;\">+<\/span> <span style=\"color: #008c00;\">1<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\npWaveHeader<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>dwBufferLength <span style=\"color: #808030;\">=<\/span> WaveFormatEx<span style=\"color: #808030;\">.<\/span>nAvgBytesPerSec <span style=\"color: #808030;\">*<\/span> <span style=\"color: #008c00;\">10<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #696969;\">\/\/pWaveHeader-&gt;dwUser = <\/span>\r\npWaveHeader<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>dwFlags <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008c00;\">0<\/span><span style=\"color: #800080;\">;<\/span>\r\npWaveHeader<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>dwLoops <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008c00;\">0<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #004a43;\">#<\/span><span style=\"color: #004a43; font-weight: bold;\">pragma <\/span><span style=\"color: #bb7977; font-weight: bold;\">region Generate Actual Data<\/span>\r\n<span style=\"color: #800080;\">{<\/span>\r\n    <span style=\"color: #603000;\">SHORT<\/span><span style=\"color: #808030;\">*<\/span> pnData <span style=\"color: #808030;\">=<\/span> <span style=\"color: #808030;\">(<\/span><span style=\"color: #603000;\">SHORT<\/span><span style=\"color: #808030;\">*<\/span><span style=\"color: #808030;\">)<\/span> pWaveHeader<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>lpData<span style=\"color: #800080;\">;<\/span>\r\n    SIZE_T nDataCount <span style=\"color: #808030;\">=<\/span> pWaveHeader<span style=\"color: #808030;\">-<\/span><span style=\"color: #808030;\">&gt;<\/span>dwBufferLength <span style=\"color: #808030;\">\/<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> <span style=\"color: #808030;\">*<\/span>pnData<span style=\"color: #800080;\">;<\/span>\r\n    <span style=\"color: #800000; font-weight: bold;\">for<\/span><span style=\"color: #808030;\">(<\/span>SIZE_T nIndex <span style=\"color: #808030;\">=<\/span> <span style=\"color: #008c00;\">0<\/span><span style=\"color: #800080;\">;<\/span> nIndex <span style=\"color: #808030;\">&lt;<\/span> nDataCount<span style=\"color: #800080;\">;<\/span> nIndex<span style=\"color: #808030;\">+<\/span><span style=\"color: #808030;\">+<\/span><span style=\"color: #808030;\">)<\/span>\r\n    pnData<span style=\"color: #808030;\">[<\/span>nIndex<span style=\"color: #808030;\">]<\/span> <span style=\"color: #808030;\">=<\/span> <span style=\"color: #808030;\">(<\/span><span style=\"color: #603000;\">SHORT<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">(<\/span><span style=\"color: #008c00;\">32000<\/span> <span style=\"color: #808030;\">*<\/span> <span style=\"color: #603000;\">sin<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #008000;\">1.0<\/span> <span style=\"color: #808030;\">*<\/span> nIndex <span style=\"color: #808030;\">\/<\/span> WaveFormatEx<span style=\"color: #808030;\">.<\/span>nSamplesPerSec <span style=\"color: #808030;\">*<\/span> nFrequency <span style=\"color: #808030;\">*<\/span> <span style=\"color: #008c00;\">2<\/span> <span style=\"color: #808030;\">*<\/span> M_PI<span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #800080;\">}<\/span>\r\n<span style=\"color: #004a43;\">#<\/span><span style=\"color: #004a43; font-weight: bold;\">pragma <\/span><span style=\"color: #bb7977; font-weight: bold;\">endregion <\/span>\r\nCheck<span style=\"color: #808030;\">(<\/span>waveOutPrepareHeader<span style=\"color: #808030;\">(<\/span>hWaveOut<span style=\"color: #808030;\">,<\/span> pWaveHeader<span style=\"color: #808030;\">,<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> <span style=\"color: #808030;\">*<\/span>pWaveHeader<span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span> \r\nCheck<span style=\"color: #808030;\">(<\/span>waveOutWrite<span style=\"color: #808030;\">(<\/span>hWaveOut<span style=\"color: #808030;\">,<\/span> pWaveHeader<span style=\"color: #808030;\">,<\/span> <span style=\"color: #800000; font-weight: bold;\">sizeof<\/span> <span style=\"color: #808030;\">*<\/span>pWaveHeader<span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span> \r\n<span style=\"color: #400000;\">GlobalUnlock<\/span><span style=\"color: #808030;\">(<\/span>hWaveHeader<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span><\/pre>\n<p>The operating system is supposed to mix the waves, which can be easily perceived taking place. It is possible to run the application with multiple waveforms within a process, e.g. &#8220;abc&#8221; command line parameter, and\/or start multiple instances of the application.<\/p>\n<p>A binary [<a href=\"https:\/\/www.alax.info\/svn\/public\/trunk\/Utilities\/WaveOutMultiPlay\/Release\/WaveOutMultiPlay.exe\">Win32<\/a>] and partial Visual C++ .NET 2010 <a href=\"https:\/\/www.alax.info\/trac\/public\/browser\/trunk\/Utilities\/WaveOutMultiPlay\">source code<\/a> are available from SVN.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The minimalistic sample demonstrates support of [deprecated] Waveform Audio API for multiple playback streams. Depending on command line parameters, the application starts threads to open audio hardware using separate waveOutOpen call and stream one or more generated sine waves: 1,000 Hz sine wave as 22,050 Hz, Mono, 16-bit PCM (command line parameter &#8220;a&#8221;) 5,000 Hz&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1291\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,13],"tags":[485,38,380,488,381],"class_list":["post-1291","post","type-post","status-publish","format-standard","hentry","category-audio","category-source","tag-audio","tag-c","tag-playback","tag-source","tag-waveout"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1291","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1291"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1291\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}