multi channel sound with winmm, many WaveOutOpen?
Asked Answered
L

3

6

I am trying to play a sound on Windows XP in multi-channel (parallel) manner. I had read somewhere that playing parallel sounds with WinMM is maybe not possible, but here is what I observe:

When I call WaveOutOpen() once, and then call many WaveOutWrite() many times then sounds are not parallel - they are queued.

But when I call WaveOutOpen say nine times (and then store nine handles to it) and then call nine times WaveOutWrite() with nine different sounds they are played in parallel (multi-channel) - that is they are mixed.

It seems to work but I am not sure if it is okay because I don't find it stated clearly in any tutorial or documentation.

It is okay to play sound in such 'many WaveOutOpen' way??

Landward answered 6/10, 2011 at 14:47 Comment(3)
Tidied up your question. Hope you don't mind.Etesian
dont care too much ;-) (I see that 'meaning' is maybe slightly changed, but not too much)Landward
Note that some audio drivers are not able to WaveOutOpen multiple times.Franck
T
3

When I call WaveOutOpen() once, and then call many WaveOutWrite() many times then sounds are not parallel - they are queued.

That's exactly what is supposed to happen. WaveOutWrite queues the next buffer. It allows you to send the audio you want to play in small chunks.

But when I call WaveOutOpen say nine times (and then store nine handles to it) and then call nine times WaveOutWrite() with nine different sounds they are played in parallel (multi-channel) - that is they are mixed.

Again, this is correct and expected. This is the simplest way to play back many simultaneous sounds. If you want sample accurate mixing however, you should mix the audio samples yourself into one stream of samples and play that through a single WaveOut device.

Truthful answered 7/10, 2011 at 9:22 Comment(9)
The second part is incorrect. No mixing is taking place. The behavior is that one of the waveOutOpens is satisfied and this feed is played. Other sounds are consumed on the wave handle, but discarded and they are not reaching actual device. Hence, no mixing takes place.Minos
According to the OP they are being played similtaneously and hence can appear to be mixed.Etesian
As I mentioned, you don't need to write a single line of code to check this out. With Windows SDK graphedt.exe you can try it yourself with Default WaveOut Device and see that if it works or not. Even if it works for OP, the answer to his question is this is expected behavior is "No".Minos
We'll have to disagree then as I am convinced it does work. I have a test program that easily proves this, and the product I work on is installed in thousands of locations worldwide and makes use of this capability on a regular basis. Read up on KMixer to find out how windows does this.Truthful
I checked on my desktop and laptop (both Win 7 x64 though) and it worked on neither of those. I suppose it might be working out for you if you hold device open and you don't queue new buffers - then another device becomes playable. But if you play two simultaneously without gaps - it just does not work. I have systems that easily prove it does not work - enough for me.Minos
Mark, FYI KMixer no longer exist starting Vista. As I was quite puzzled by your comment, I checked this in two more XP systems - none of those worked.Minos
Yes KMixer is gone, but it has been replaced by the new Vista audio subsystem. Windows has had the ability for as long as I can remember for two different applications to be playing sound at the same time and you can hear both. Have you actually written code that plays audio using WaveOutOpen?Truthful
Wrote some code - you are correct, the mixing takes place. Updated my post above too.Minos
I can assure the writers that It works/(seem to work) for me (got only simple test, of starting play different tunes, from under the keyboard events - and when i press two or thre keys i hear mixed/added waves) No dirrerent threads it is just many WaveOutWrite called in reactions of keyboard keys pressedLandward
M
1

I stand corrected with ability of waveOut* API to play sounds simultaneously and mixed.

Here is test code for the curious: http://www.alax.info/trac/public/browser/trunk/Utilities/WaveOutMultiPlay An application started with arguments abc plays on different threads sounds at 1, 5 and 15 kHz respectively and they mix well.

At the same time DirectShow Audio Renderer (WaveOut) Filter built on top of the same API is unable to play anything more that a single stream, for no visible reason.

FYI waveOutOpen API is retired since long ago and currently is wrapper on top of newer APIs. waveOutOpen assumes that audio output device is opened for exclusive use so there is no guarantee that multiply opened devices simultanesouly would produce mixed audio output. To achieve such behavior you would be better off with a newer audio API: DirectSound, DirectShow on top of DirectSound or WASAPI.

Minos answered 6/10, 2011 at 16:3 Comment(15)
but it seem to work, and is system (no libs - it much matters for me) and easy. I do not want to cope with directx, I write with pure c and pure winapiLandward
Good for you - works for you, does not work for me on my audio hardware. It is actually easy to check with GraphEdit tool from Windows SDK.Minos
if so you bring me bad news, I need (want) to play multichanel sound with pure system (no libs).Landward
i have found such info "MME supports sharing the audio device for playback between multiple applications starting with Windows XP, up to two channels of recording, 16-bit audio bit depth and sampling rates of up to 44.1 kHz with all the audio being mixed and sampled to 44.1 kHz." So it probably means that when i openWaveOut nine times is such like i would open 9 applications each one with its own sound and it is mixed by windows mixer :-/ hmm, maybe it is not so efficient latent and heavy?Landward
You're possibly looking up for justification of your simple solution. I just quick-tried how it worked for me, and it worked weirdly. Within single process 2 waveOutOpen started, but only one actually played, second was muted but no error came up. When waveOutOpens are on different processes, first was good and second failed to start playback.Minos
i do " waveOutOpen (&hWaveOut9, WAVE_MAPPER, &waveformat, NULL, 0, CALLBACK_WINDOW) " nine times, store nine handles (not tested if can use only one handle for nine open's) then do "waveOutPrepareHeader (hWaveOut9, &waveHdr9, sizeof (WAVEHDR)) ; waveOutWrite (hWaveOut9, &waveHdr9, sizeof (WAVEHDR)) ;" This would be good for me, but if not this, i can also try to use asio, openal, or wasapi (if supported on xp) but is not perfect because i strongly prefer no external libs [possibly I can try almost everything and compare results,Landward
WASAPI is supported Vista+. If you play from file, then with DirectShow it would be easy to do. If you generate sound, you will perhaps be easily able to do it with DirectSound. Both are core Windows APIs, with real time multiple source mixing support built in.Minos
usualy i write opengl+winapi+pure c apps; should i mix directsound with it? dont like directx api calls, looks extraordinary ugly for me, bu eventually i will lok at itLandward
Not true, waveOutOpen is perfectly well supported despite being an old Windows API. You can have multiple instances of it running at once.Truthful
@Mark just try it out first. It's well supported, but it is not offering mixing, which is in question.Minos
@Roman I have often made use of multiple concurrent WaveOut instances and I've never seen them fail to mix sound properly. As I understand it, when you use multiple WaveOutOpens, Windows does the mixing (and Sample Rate Conversion) for you. In Windows XP days it used KMixer but I suspect Vista/Win7 use the WASAPI framework underneath. This is part of the reason why the latency is poor with WaveOut.Truthful
@roman i fired the waveoutwrite example, it works for me likeLandward
I did check before posting original answer, but I gave too much credit to DirectShow WaveOut rednerer. It is definitely built on top of waveOut API and it's unable to play more than 1 audio at a time. I assumed it was a limitation of waveOut, and it appears that it was not. The code shows mixing takes place. GraphEdit shows you can't play 2+ files via DirectShow waveOut.Minos
@roman i fired the waveoutwrite example, it works for me similiar; (So finaly there was stated that it can be used;) personally i need/want to play very often (more than 50 fired sounds/second) many very short (10 milisecond maybe) sounds in parralel (maybe 10 chanells or more) and will test if i can gain such efect with this;Landward
tnx Mark Heath, much tnx guysLandward
E
0

I suggest going with DirectSound if your product is for consumers.

From DirectX8 onwards the API is at the point where it is actually quite painless and most consumer machines will have it installed.

Etesian answered 7/10, 2011 at 9:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.