winealsa 24/32 bit sample size and 4/6 channel support
Robert Reif
reif at earthlink.net
Wed Aug 18 18:43:48 CDT 2004
Adds 24/32 bit sample size and 4/6 channel support.
Adds dsound capture wine specific message support.
-------------- next part --------------
Index: dlls/winmm/winealsa/audio.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/winealsa/audio.c,v
retrieving revision 1.50
diff -u -r1.50 audio.c
--- dlls/winmm/winealsa/audio.c 12 Aug 2004 23:00:52 -0000 1.50
+++ dlls/winmm/winealsa/audio.c 18 Aug 2004 23:36:45 -0000
@@ -52,8 +52,12 @@
#include "winnls.h"
#include "winreg.h"
#include "mmddk.h"
+#include "mmreg.h"
#include "dsound.h"
#include "dsdriver.h"
+#include "ks.h"
+#include "ksguid.h"
+#include "ksmedia.h"
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include "alsa.h"
@@ -145,7 +149,7 @@
volatile int state; /* one of the WINE_WS_ manifest constants */
WAVEOPENDESC waveDesc;
WORD wFlags;
- PCMWAVEFORMAT format;
+ WAVEFORMATPCMEX format;
WAVEOUTCAPSA caps;
/* ALSA information (ALSA 0.9/1.x uses two different devices for playback/capture) */
@@ -192,7 +196,7 @@
volatile int state; /* one of the WINE_WS_ manifest constants */
WAVEOPENDESC waveDesc;
WORD wFlags;
- PCMWAVEFORMAT format;
+ WAVEFORMATPCMEX format;
WAVEOUTCAPSA caps;
/* ALSA information (ALSA 0.9/1.x uses two different devices for playback/capture) */
@@ -244,48 +248,54 @@
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid);
/* These strings used only for tracing */
-#if 1
-static const char *wodPlayerCmdString[] = {
- "WINE_WM_PAUSING",
- "WINE_WM_RESTARTING",
- "WINE_WM_RESETTING",
- "WINE_WM_HEADER",
- "WINE_WM_UPDATE",
- "WINE_WM_BREAKLOOP",
- "WINE_WM_CLOSING",
- "WINE_WM_STARTING",
- "WINE_WM_STOPPING",
-};
-#endif
+static const char * getCmdString(enum win_wm_message msg)
+{
+ static char unknown[32];
+#define MSG_TO_STR(x) case x: return #x
+ switch(msg) {
+ MSG_TO_STR(WINE_WM_PAUSING);
+ MSG_TO_STR(WINE_WM_RESTARTING);
+ MSG_TO_STR(WINE_WM_RESETTING);
+ MSG_TO_STR(WINE_WM_HEADER);
+ MSG_TO_STR(WINE_WM_UPDATE);
+ MSG_TO_STR(WINE_WM_BREAKLOOP);
+ MSG_TO_STR(WINE_WM_CLOSING);
+ MSG_TO_STR(WINE_WM_STARTING);
+ MSG_TO_STR(WINE_WM_STOPPING);
+ }
+#undef MSG_TO_STR
+ sprintf(unknown, "UNKNOWN(0x%08x)", msg);
+ return unknown;
+}
static DWORD bytes_to_mmtime(LPMMTIME lpTime, DWORD position,
- PCMWAVEFORMAT* format)
+ WAVEFORMATPCMEX* format)
{
TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%lu nChannels=%u nAvgBytesPerSec=%lu\n",
- lpTime->wType, format->wBitsPerSample, format->wf.nSamplesPerSec,
- format->wf.nChannels, format->wf.nAvgBytesPerSec);
+ lpTime->wType, format->Format.wBitsPerSample, format->Format.nSamplesPerSec,
+ format->Format.nChannels, format->Format.nAvgBytesPerSec);
TRACE("Position in bytes=%lu\n", position);
switch (lpTime->wType) {
case TIME_SAMPLES:
- lpTime->u.sample = position / (format->wBitsPerSample / 8 * format->wf.nChannels);
+ lpTime->u.sample = position / (format->Format.wBitsPerSample / 8 * format->Format.nChannels);
TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
break;
case TIME_MS:
- lpTime->u.ms = 1000.0 * position / (format->wBitsPerSample / 8 * format->wf.nChannels * format->wf.nSamplesPerSec);
+ lpTime->u.ms = 1000.0 * position / (format->Format.wBitsPerSample / 8 * format->Format.nChannels * format->Format.nSamplesPerSec);
TRACE("TIME_MS=%lu\n", lpTime->u.ms);
break;
case TIME_SMPTE:
- position = position / (format->wBitsPerSample / 8 * format->wf.nChannels);
- lpTime->u.smpte.sec = position / format->wf.nSamplesPerSec;
- position -= lpTime->u.smpte.sec * format->wf.nSamplesPerSec;
+ position = position / (format->Format.wBitsPerSample / 8 * format->Format.nChannels);
+ lpTime->u.smpte.sec = position / format->Format.nSamplesPerSec;
+ position -= lpTime->u.smpte.sec * format->Format.nSamplesPerSec;
lpTime->u.smpte.min = lpTime->u.smpte.sec / 60;
lpTime->u.smpte.sec -= 60 * lpTime->u.smpte.min;
lpTime->u.smpte.hour = lpTime->u.smpte.min / 60;
lpTime->u.smpte.min -= 60 * lpTime->u.smpte.hour;
lpTime->u.smpte.fps = 30;
- lpTime->u.smpte.frame = position * lpTime->u.smpte.fps / format->wf.nSamplesPerSec;
- position -= lpTime->u.smpte.frame * format->wf.nSamplesPerSec / lpTime->u.smpte.fps;
+ lpTime->u.smpte.frame = position * lpTime->u.smpte.fps / format->Format.nSamplesPerSec;
+ position -= lpTime->u.smpte.frame * format->Format.nSamplesPerSec / lpTime->u.smpte.fps;
if (position != 0)
{
/* Round up */
@@ -307,6 +317,61 @@
return MMSYSERR_NOERROR;
}
+static BOOL supportedFormat(LPWAVEFORMATEX wf)
+{
+ TRACE("(%p)\n",wf);
+
+ if (wf->nSamplesPerSec<DSBFREQUENCY_MIN||wf->nSamplesPerSec>DSBFREQUENCY_MAX)
+ return FALSE;
+
+ if (wf->wFormatTag == WAVE_FORMAT_PCM) {
+ if (wf->nChannels==1||wf->nChannels==2) {
+ if (wf->wBitsPerSample==8||wf->wBitsPerSample==16)
+ return TRUE;
+ }
+ } else if (wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
+ WAVEFORMATEXTENSIBLE * wfex = (WAVEFORMATEXTENSIBLE *)wf;
+
+ if (wf->cbSize == 22 && IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
+ if (wf->nChannels>=1 && wf->nChannels<=6) {
+ if (wf->wBitsPerSample==wfex->Samples.wValidBitsPerSample) {
+ if (wf->wBitsPerSample==8||wf->wBitsPerSample==16||
+ wf->wBitsPerSample==24||wf->wBitsPerSample==32) {
+ return TRUE;
+ }
+ } else
+ WARN("wBitsPerSample != wValidBitsPerSample not supported yet\n");
+ }
+ } else
+ WARN("only KSDATAFORMAT_SUBTYPE_PCM supported\n");
+ } else if (wf->wFormatTag == WAVE_FORMAT_MULAW || wf->wFormatTag == WAVE_FORMAT_ALAW) {
+ if (wf->wBitsPerSample==8)
+ return TRUE;
+ else
+ ERR("WAVE_FORMAT_MULAW and WAVE_FORMAT_ALAW wBitsPerSample must = 8\n");
+
+ } else if (wf->wFormatTag == WAVE_FORMAT_ADPCM) {
+ if (wf->wBitsPerSample==4)
+ return TRUE;
+ else
+ ERR("WAVE_FORMAT_ADPCM wBitsPerSample must = 4\n");
+ } else
+ WARN("only WAVE_FORMAT_PCM and WAVE_FORMAT_EXTENSIBLE supported\n");
+
+ return FALSE;
+}
+
+static void copy_format(LPWAVEFORMATEX wf1, LPWAVEFORMATPCMEX wf2)
+{
+ ZeroMemory(wf2, sizeof(wf2));
+ if (wf1->wFormatTag == WAVE_FORMAT_PCM)
+ memcpy(wf2, wf1, sizeof(PCMWAVEFORMAT));
+ else if (wf1->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ memcpy(wf2, wf1, sizeof(WAVEFORMATPCMEX));
+ else
+ memcpy(wf2, wf1, sizeof(WAVEFORMATEX) + wf1->cbSize);
+}
+
/*======================================================================*
* Low level WAVE implementation *
*======================================================================*/
@@ -717,7 +782,7 @@
}
if ( chmin > 1) FIXME("-\n");
- wwo->caps.wChannels = (chmax >= 2) ? 2 : 1;
+ wwo->caps.wChannels = chmax;
if (chmin <= 2 && 2 <= chmax)
wwo->caps.dwSupport |= WAVECAPS_LRVOLUME;
@@ -826,7 +891,7 @@
}
if ( chmin > 1) FIXME("-\n");
- wwi->caps.wChannels = (chmax >= 2) ? 2 : 1;
+ wwi->caps.wChannels = chmax;
if (chmin <= 2 && 2 <= chmax)
wwi->caps.dwSupport |= WAVECAPS_LRVOLUME;
@@ -839,8 +904,11 @@
snd_pcm_hw_params_get_access_mask(hw_params, acmask);
/* FIXME: NONITERLEAVED and COMPLEX are not supported right now */
- if ( snd_pcm_access_mask_test( acmask, SND_PCM_ACCESS_MMAP_INTERLEAVED ) )
+ if ( snd_pcm_access_mask_test( acmask, SND_PCM_ACCESS_MMAP_INTERLEAVED ) ) {
+#if 0
wwi->caps.dwSupport |= WAVECAPS_DIRECTSOUND;
+#endif
+ }
}
TRACE("Configured with dwFmts=%08lx dwSupport=%08lx\n",
@@ -933,7 +1001,9 @@
return 0;
}
if (omr->msg_toget != omr->msg_tosave && omr->messages[omr->msg_toget].msg != WINE_WM_HEADER)
- FIXME("two fast messages in the queue!!!!\n");
+ FIXME("two fast messages in the queue!!!! toget = %d(%s), tosave=%d(%s)\n",
+ omr->msg_toget,getCmdString(omr->messages[omr->msg_toget].msg),
+ omr->msg_tosave,getCmdString(omr->messages[omr->msg_tosave].msg));
/* fast messages have to be added at the start of the queue */
omr->msg_toget = (omr->msg_toget + omr->ring_buffer_size - 1) % omr->ring_buffer_size;
@@ -1147,7 +1217,7 @@
if (lpWaveHdr->reserved < wwo->dwPlayedTotal) {
dwMillis = 1;
} else {
- dwMillis = (lpWaveHdr->reserved - wwo->dwPlayedTotal) * 1000 / wwo->format.wf.nAvgBytesPerSec;
+ dwMillis = (lpWaveHdr->reserved - wwo->dwPlayedTotal) * 1000 / wwo->format.Format.nAvgBytesPerSec;
if (!dwMillis) dwMillis = 1;
}
@@ -1342,7 +1412,7 @@
int err;
while (ALSA_RetrieveRingMessage(&wwo->msgRing, &msg, ¶m, &ev)) {
- TRACE("Received %s %lx\n", wodPlayerCmdString[msg - WM_USER - 1], param);
+ TRACE("Received %s %lx\n", getCmdString(msg), param);
switch (msg) {
case WINE_WM_PAUSING:
@@ -1520,7 +1590,7 @@
snd_pcm_hw_params_t * hw_params;
snd_pcm_sw_params_t * sw_params;
snd_pcm_access_t access;
- snd_pcm_format_t format;
+ snd_pcm_format_t format = -1;
unsigned int rate;
unsigned int buffer_time = 500000;
unsigned int period_time = 10000;
@@ -1545,11 +1615,7 @@
}
/* only PCM format is supported so far... */
- if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
- lpDesc->lpFormat->nChannels == 0 ||
- lpDesc->lpFormat->nSamplesPerSec < DSBFREQUENCY_MIN ||
- lpDesc->lpFormat->nSamplesPerSec > DSBFREQUENCY_MAX ||
- (lpDesc->lpFormat->wBitsPerSample!=8 && lpDesc->lpFormat->wBitsPerSample!=16)) {
+ if (!supportedFormat(lpDesc->lpFormat)) {
WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%ld !\n",
lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
lpDesc->lpFormat->nSamplesPerSec);
@@ -1582,15 +1648,15 @@
wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
- memcpy(&wwo->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
- memcpy(&wwo->format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
+ memcpy(&wwo->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
+ copy_format(lpDesc->lpFormat, &wwo->format);
- if (wwo->format.wBitsPerSample == 0) {
+ if (wwo->format.Format.wBitsPerSample == 0) {
WARN("Resetting zeroed wBitsPerSample\n");
- wwo->format.wBitsPerSample = 8 *
- (wwo->format.wf.nAvgBytesPerSec /
- wwo->format.wf.nSamplesPerSec) /
- wwo->format.wf.nChannels;
+ wwo->format.Format.wBitsPerSample = 8 *
+ (wwo->format.Format.nAvgBytesPerSec /
+ wwo->format.Format.nSamplesPerSec) /
+ wwo->format.Format.nChannels;
}
snd_pcm_hw_params_any(pcm, hw_params);
@@ -1616,21 +1682,45 @@
else
wwo->write = snd_pcm_mmap_writei;
- EXIT_ON_ERROR( snd_pcm_hw_params_set_channels(pcm, hw_params, wwo->format.wf.nChannels), MMSYSERR_INVALPARAM, "unable to set required channels");
+ EXIT_ON_ERROR( snd_pcm_hw_params_set_channels(pcm, hw_params, wwo->format.Format.nChannels), MMSYSERR_INVALPARAM, "unable to set required channels");
+
+ if ((wwo->format.Format.wFormatTag == WAVE_FORMAT_PCM) ||
+ ((wwo->format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
+ IsEqualGUID(&wwo->format.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) {
+ format = (wwo->format.Format.wBitsPerSample == 8) ? SND_PCM_FORMAT_U8 :
+ (wwo->format.Format.wBitsPerSample == 16) ? SND_PCM_FORMAT_S16_LE :
+ (wwo->format.Format.wBitsPerSample == 24) ? SND_PCM_FORMAT_S24_LE :
+ (wwo->format.Format.wBitsPerSample == 32) ? SND_PCM_FORMAT_S32_LE : -1;
+ } else if (wwo->format.Format.wFormatTag == WAVE_FORMAT_MULAW) {
+ FIXME("unimplemented format: WAVE_FORMAT_MULAW\n");
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ } else if (wwo->format.Format.wFormatTag == WAVE_FORMAT_ALAW) {
+ FIXME("unimplemented format: WAVE_FORMAT_ALAW\n");
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ } else if (wwo->format.Format.wFormatTag == WAVE_FORMAT_ADPCM) {
+ FIXME("unimplemented format: WAVE_FORMAT_ADPCM\n");
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ } else {
+ ERR("invalid format: %0x04x\n", wwo->format.Format.wFormatTag);
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ }
- format = (wwo->format.wBitsPerSample == 16) ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U8;
EXIT_ON_ERROR( snd_pcm_hw_params_set_format(pcm, hw_params, format), MMSYSERR_INVALPARAM, "unable to set required format");
- rate = wwo->format.wf.nSamplesPerSec;
+ rate = wwo->format.Format.nSamplesPerSec;
dir=0;
err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, &dir);
if (err < 0) {
- ERR("Rate %ld Hz not available for playback: %s\n", wwo->format.wf.nSamplesPerSec, snd_strerror(rate));
+ ERR("Rate %ld Hz not available for playback: %s\n", wwo->format.Format.nSamplesPerSec, snd_strerror(rate));
snd_pcm_close(pcm);
return WAVERR_BADFORMAT;
}
- if (rate != wwo->format.wf.nSamplesPerSec) {
- ERR("Rate doesn't match (requested %ld Hz, got %d Hz)\n", wwo->format.wf.nSamplesPerSec, rate);
+ if (rate != wwo->format.Format.nSamplesPerSec) {
+ ERR("Rate doesn't match (requested %ld Hz, got %d Hz)\n", wwo->format.Format.nSamplesPerSec, rate);
snd_pcm_close(pcm);
return WAVERR_BADFORMAT;
}
@@ -1700,13 +1790,13 @@
wwo->hStartUpEvent = INVALID_HANDLE_VALUE;
TRACE("handle=%08lx \n", (DWORD)wwo->p_handle);
-/* if (wwo->dwFragmentSize % wwo->format.wf.nBlockAlign)
+/* if (wwo->dwFragmentSize % wwo->format.Format.nBlockAlign)
ERR("Fragment doesn't contain an integral number of data blocks\n");
*/
TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n",
- wwo->format.wBitsPerSample, wwo->format.wf.nAvgBytesPerSec,
- wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
- wwo->format.wf.nBlockAlign);
+ wwo->format.Format.wBitsPerSample, wwo->format.Format.nAvgBytesPerSec,
+ wwo->format.Format.nSamplesPerSec, wwo->format.Format.nChannels,
+ wwo->format.Format.nBlockAlign);
return wodNotifyClient(wwo, WOM_OPEN, 0L, 0L);
}
@@ -2748,7 +2838,7 @@
SetEvent(wwi->hStartUpEvent);
/* make sleep time to be # of ms to output a period */
- dwSleepTime = (1024/*wwi-dwPeriodSize => overrun!*/ * 1000) / wwi->format.wf.nAvgBytesPerSec;
+ dwSleepTime = (1024/*wwi-dwPeriodSize => overrun!*/ * 1000) / wwi->format.Format.nAvgBytesPerSec;
frames_per_period = snd_pcm_bytes_to_frames(wwi->p_handle, wwi->dwPeriodSize);
TRACE("sleeptime=%ld ms\n", dwSleepTime);
@@ -2803,6 +2893,10 @@
widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
lpWaveHdr = lpNext;
}
+ } else {
+ TRACE("read(%s, %p, %ld) failed (%s)\n", wwi->device,
+ lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded,
+ frames_per_period, strerror(errno));
}
}
else
@@ -2814,6 +2908,12 @@
TRACE("bytesRead=%ld (local)\n", bytesRead);
+ if (bytesRead == (DWORD) -1) {
+ TRACE("read(%s, %p, %ld) failed (%s)\n", wwi->device,
+ buffer, frames_per_period, strerror(errno));
+ continue;
+ }
+
/* copy data in client buffers */
while (bytesRead != (DWORD) -1 && bytesRead > 0)
{
@@ -2853,7 +2953,7 @@
LPWAVEHDR hdr;
ALSA_RetrieveRingMessage(&wwi->msgRing, &msg, ¶m, &ev);
hdr = ((LPWAVEHDR)param);
- TRACE("msg = %s, hdr = %p, ev = %p\n", wodPlayerCmdString[msg - WM_USER - 1], hdr, ev);
+ TRACE("msg = %s, hdr = %p, ev = %p\n", getCmdString(msg), hdr, ev);
hdr->lpNext = 0;
if (lpWaveHdr == 0) {
/* new head of queue */
@@ -2887,7 +2987,7 @@
while (ALSA_RetrieveRingMessage(&wwi->msgRing, &msg, ¶m, &ev))
{
- TRACE("msg=%s param=0x%lx\n", wodPlayerCmdString[msg - WM_USER - 1], param);
+ TRACE("msg=%s param=0x%lx\n", getCmdString(msg), param);
switch (msg) {
case WINE_WM_PAUSING:
wwi->state = WINE_WS_PAUSED;
@@ -3012,11 +3112,7 @@
}
/* only PCM format is supported so far... */
- if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
- lpDesc->lpFormat->nChannels == 0 ||
- lpDesc->lpFormat->nSamplesPerSec < DSBFREQUENCY_MIN ||
- lpDesc->lpFormat->nSamplesPerSec > DSBFREQUENCY_MAX ||
- (lpDesc->lpFormat->wBitsPerSample!=8 && lpDesc->lpFormat->wBitsPerSample!=16)) {
+ if (!supportedFormat(lpDesc->lpFormat)) {
WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%ld !\n",
lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
lpDesc->lpFormat->nSamplesPerSec);
@@ -3049,15 +3145,15 @@
wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
- memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
- memcpy(&wwi->format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
+ memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
+ copy_format(lpDesc->lpFormat, &wwi->format);
- if (wwi->format.wBitsPerSample == 0) {
+ if (wwi->format.Format.wBitsPerSample == 0) {
WARN("Resetting zeroed wBitsPerSample\n");
- wwi->format.wBitsPerSample = 8 *
- (wwi->format.wf.nAvgBytesPerSec /
- wwi->format.wf.nSamplesPerSec) /
- wwi->format.wf.nChannels;
+ wwi->format.Format.wBitsPerSample = 8 *
+ (wwi->format.Format.nAvgBytesPerSec /
+ wwi->format.Format.nSamplesPerSec) /
+ wwi->format.Format.nChannels;
}
snd_pcm_hw_params_any(pcm, hw_params);
@@ -3083,21 +3179,45 @@
else
wwi->read = snd_pcm_mmap_readi;
- EXIT_ON_ERROR( snd_pcm_hw_params_set_channels(pcm, hw_params, wwi->format.wf.nChannels), MMSYSERR_INVALPARAM, "unable to set required channels");
+ EXIT_ON_ERROR( snd_pcm_hw_params_set_channels(pcm, hw_params, wwi->format.Format.nChannels), MMSYSERR_INVALPARAM, "unable to set required channels");
+
+ if ((wwi->format.Format.wFormatTag == WAVE_FORMAT_PCM) ||
+ ((wwi->format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
+ IsEqualGUID(&wwi->format.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) {
+ format = (wwi->format.Format.wBitsPerSample == 8) ? SND_PCM_FORMAT_U8 :
+ (wwi->format.Format.wBitsPerSample == 16) ? SND_PCM_FORMAT_S16_LE :
+ (wwi->format.Format.wBitsPerSample == 24) ? SND_PCM_FORMAT_S24_LE :
+ (wwi->format.Format.wBitsPerSample == 32) ? SND_PCM_FORMAT_S32_LE : -1;
+ } else if (wwi->format.Format.wFormatTag == WAVE_FORMAT_MULAW) {
+ FIXME("unimplemented format: WAVE_FORMAT_MULAW\n");
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ } else if (wwi->format.Format.wFormatTag == WAVE_FORMAT_ALAW) {
+ FIXME("unimplemented format: WAVE_FORMAT_ALAW\n");
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ } else if (wwi->format.Format.wFormatTag == WAVE_FORMAT_ADPCM) {
+ FIXME("unimplemented format: WAVE_FORMAT_ADPCM\n");
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ } else {
+ ERR("invalid format: %0x04x\n", wwi->format.Format.wFormatTag);
+ snd_pcm_close(pcm);
+ return WAVERR_BADFORMAT;
+ }
- format = (wwi->format.wBitsPerSample == 16) ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U8;
EXIT_ON_ERROR( snd_pcm_hw_params_set_format(pcm, hw_params, format), MMSYSERR_INVALPARAM, "unable to set required format");
- rate = wwi->format.wf.nSamplesPerSec;
+ rate = wwi->format.Format.nSamplesPerSec;
dir = 0;
err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, &dir);
if (err < 0) {
- ERR("Rate %ld Hz not available for playback: %s\n", wwi->format.wf.nSamplesPerSec, snd_strerror(rate));
+ ERR("Rate %ld Hz not available for playback: %s\n", wwi->format.Format.nSamplesPerSec, snd_strerror(rate));
snd_pcm_close(pcm);
return WAVERR_BADFORMAT;
}
- if (rate != wwi->format.wf.nSamplesPerSec) {
- ERR("Rate doesn't match (requested %ld Hz, got %d Hz)\n", wwi->format.wf.nSamplesPerSec, rate);
+ if (rate != wwi->format.Format.nSamplesPerSec) {
+ ERR("Rate doesn't match (requested %ld Hz, got %d Hz)\n", wwi->format.Format.nSamplesPerSec, rate);
snd_pcm_close(pcm);
return WAVERR_BADFORMAT;
}
@@ -3156,14 +3276,14 @@
}
wwi->dwPeriodSize = period_size;
- /*if (wwi->dwFragmentSize % wwi->format.wf.nBlockAlign)
+ /*if (wwi->dwFragmentSize % wwi->format.Format.nBlockAlign)
ERR("Fragment doesn't contain an integral number of data blocks\n");
*/
TRACE("dwPeriodSize=%lu\n", wwi->dwPeriodSize);
TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n",
- wwi->format.wBitsPerSample, wwi->format.wf.nAvgBytesPerSec,
- wwi->format.wf.nSamplesPerSec, wwi->format.wf.nChannels,
- wwi->format.wf.nBlockAlign);
+ wwi->format.Format.wBitsPerSample, wwi->format.Format.nAvgBytesPerSec,
+ wwi->format.Format.nSamplesPerSec, wwi->format.Format.nChannels,
+ wwi->format.Format.nBlockAlign);
if (!(dwFlags & WAVE_DIRECTSOUND)) {
wwi->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
@@ -3349,13 +3469,17 @@
{
WINE_WAVEIN* wwi;
- FIXME("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
+ TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
WARN("can't get pos !\n");
return MMSYSERR_INVALHANDLE;
}
- if (lpTime == NULL) return MMSYSERR_INVALPARAM;
+
+ if (lpTime == NULL) {
+ WARN("invalid parameter: lpTime = NULL\n");
+ return MMSYSERR_INVALPARAM;
+ }
wwi = &WInDev[wDevID];
ALSA_AddRingMessage(&wwi->msgRing, WINE_WM_UPDATE, 0, TRUE);
@@ -3377,7 +3501,7 @@
static DWORD widDevInterfaceSize(UINT wDevID, LPDWORD dwParam1)
{
TRACE("(%u, %p)\n", wDevID, dwParam1);
-
+
*dwParam1 = MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
NULL, 0 ) * sizeof(WCHAR);
return MMSYSERR_NOERROR;
@@ -3399,6 +3523,40 @@
}
/**************************************************************************
+ * widDsCreate [internal]
+ */
+static DWORD widDsCreate(UINT wDevID, PIDSCDRIVER* drv)
+{
+ TRACE("(%d,%p)\n",wDevID,drv);
+
+ /* the HAL isn't much better than the HEL if we can't do mmap() */
+ FIXME("DirectSoundCapture not implemented\n");
+ MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
+ return MMSYSERR_NOTSUPPORTED;
+}
+
+/**************************************************************************
+ * widDsDesc [internal]
+ */
+static DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc)
+{
+ memcpy(desc, &(WInDev[wDevID].ds_desc), sizeof(DSDRIVERDESC));
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+ * widDsGuid [internal]
+ */
+static DWORD widDsGuid(UINT wDevID, LPGUID pGuid)
+{
+ TRACE("(%d,%p)\n",wDevID,pGuid);
+
+ memcpy(pGuid, &(WInDev[wDevID].ds_guid), sizeof(GUID));
+
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
* widMessage (WINEALSA.@)
*/
DWORD WINAPI ALSA_widMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
@@ -3427,9 +3585,9 @@
case WIDM_STOP: return widStop (wDevID, (LPWAVEHDR)dwParam1, dwParam2);
case DRV_QUERYDEVICEINTERFACESIZE: return widDevInterfaceSize (wDevID, (LPDWORD)dwParam1);
case DRV_QUERYDEVICEINTERFACE: return widDevInterface (wDevID, (PWCHAR)dwParam1, dwParam2);
- /*case DRV_QUERYDSOUNDIFACE: return widDsCreate (wDevID, (PIDSCDRIVER*)dwParam1);
+ case DRV_QUERYDSOUNDIFACE: return widDsCreate (wDevID, (PIDSCDRIVER*)dwParam1);
case DRV_QUERYDSOUNDDESC: return widDsDesc (wDevID, (PDSDRIVERDESC)dwParam1);
- case DRV_QUERYDSOUNDGUID: return widDsGuid (wDevID, (LPGUID)dwParam1);*/
+ case DRV_QUERYDSOUNDGUID: return widDsGuid (wDevID, (LPGUID)dwParam1);
default:
FIXME("unknown message %d!\n", wMsg);
}
More information about the wine-patches
mailing list