Juan Lang wrote:
- Is there some central place in dsound for enforcing the
invariant instead of identical code in the half dozen OSS/ALSA/CoreAudio/Jack etc. drivers?
No, or, not to my knowledge.
This is unfortunate. Wine's dsound needs a channel back from winmm (which eventually calls wineoss/winealsa etc. via wodOpen) to obtain the correct format data. The OSS hardware mode does this (in wineoss.drv/audio.c) by updating the supplied structure. My patch does it for the OSS emulation mode.
However, testing on MS-Windows reveals that waveOutOpen() does not modify the supplied WAVEFORMATEX structure. Windows' wave*() seems to completely ignore the incorrect nBlockAlign and nAvgBytesPerSample. Apps can submit bogus data and still work. So must Wine.
If Wine would not update the structure, there would be no channel back to dsound. So I'm wondering whether dsound/dsound.c can itself fix the values. Sadly I don't understand where the mapper and all these adpcm/mp3/gsm drivers comes into play in dsound: Where can Wine set nBlockAlign == nChannels * wBitsPerSample/8 and nAvgBytesPerSec == nSamplesPerSec * nBlockAlign? MSDN says in http://msdn.microsoft.com/en-us/library/bb669161(VS.85).aspx "For non-PCM formats, this member must be computed according to the manufacturer's specification for the format tag." *Who* computes? The app? The mapper?
Note that msacm32.drv/wavemap.c:wodOpenHelper sets lpwfx->nBlockAlign and nAvgBytesPerSec The line wodOpen:TRY: ... case MMSYSERR_NOERROR: wom->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; shows that nAvgBytesPerSec is considered an output variable after wodOpen(). The value need be correct, or crashes will likely follow.
In any case, I'm going to submit patches (in-place update) soon for OSS and CoreAudio (ALSA later). A cleaner solution is awaiting ideas.
Regards, Jörg Höhle PS: While I've verified that MS-Windows' waveOutOpen does not modify the format structure (given PCM), I've not tested what the dsound interface does.