module-waveout: Query device for supported samplerate

Instead of using a fixed list list of supported rates,
ask the wave subsystem whether the rate can be used.
This commit is contained in:
Maarten Bosmans 2011-03-12 19:41:07 +01:00
parent b599d3c836
commit 030f32fe6f

View file

@ -159,12 +159,11 @@ static void do_write(struct userdata *u) {
memchunk.memblock = NULL; memchunk.memblock = NULL;
} }
/* Insufficient data in sink buffer? */ /* Underflow detection */
if (hdr->dwBufferLength == 0) { if (hdr->dwBufferLength == 0) {
u->sink_underflow = 1; u->sink_underflow = 1;
break; break;
} }
u->sink_underflow = 0; u->sink_underflow = 0;
res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR)); res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR));
@ -294,6 +293,10 @@ finish:
static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) { static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
struct userdata *u = (struct userdata*) inst; struct userdata *u = (struct userdata*) inst;
if (msg == WOM_OPEN)
pa_log_debug("WaveOut subsystem opened.");
if (msg == WOM_CLOSE)
pa_log_debug("WaveOut subsystem closed.");
if (msg != WOM_DONE) if (msg != WOM_DONE)
return; return;
@ -306,6 +309,10 @@ static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD
static void CALLBACK chunk_ready_cb(HWAVEIN hwi, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) { static void CALLBACK chunk_ready_cb(HWAVEIN hwi, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
struct userdata *u = (struct userdata*) inst; struct userdata *u = (struct userdata*) inst;
if (msg == WIM_OPEN)
pa_log_debug("WaveIn subsystem opened.");
if (msg == WIM_CLOSE)
pa_log_debug("WaveIn subsystem closed.");
if (msg != WIM_DATA) if (msg != WIM_DATA)
return; return;
@ -433,17 +440,6 @@ static int ss_to_waveformat(pa_sample_spec *ss, LPWAVEFORMATEX wf) {
wf->nChannels = ss->channels; wf->nChannels = ss->channels;
switch (ss->rate) {
case 8000:
case 11025:
case 22005:
case 44100:
break;
default:
pa_log_error("Unsupported sample rate.");
return -1;
}
wf->nSamplesPerSec = ss->rate; wf->nSamplesPerSec = ss->rate;
if (ss->format == PA_SAMPLE_U8) if (ss->format == PA_SAMPLE_U8)
@ -451,7 +447,7 @@ static int ss_to_waveformat(pa_sample_spec *ss, LPWAVEFORMATEX wf) {
else if (ss->format == PA_SAMPLE_S16NE) else if (ss->format == PA_SAMPLE_S16NE)
wf->wBitsPerSample = 16; wf->wBitsPerSample = 16;
else { else {
pa_log_error("Unsupported sample format."); pa_log_error("Unsupported sample format, only u8 and s16 are supported.");
return -1; return -1;
} }
@ -479,6 +475,7 @@ int pa__init(pa_module *m) {
HWAVEIN hwi = INVALID_HANDLE_VALUE; HWAVEIN hwi = INVALID_HANDLE_VALUE;
WAVEFORMATEX wf; WAVEFORMATEX wf;
WAVEOUTCAPS pwoc; WAVEOUTCAPS pwoc;
MMRESULT result;
int nfrags, frag_size; int nfrags, frag_size;
pa_bool_t record = TRUE, playback = TRUE; pa_bool_t record = TRUE, playback = TRUE;
unsigned int device; unsigned int device;
@ -551,23 +548,39 @@ int pa__init(pa_module *m) {
u = pa_xmalloc(sizeof(struct userdata)); u = pa_xmalloc(sizeof(struct userdata));
if (record) { if (record) {
if (waveInOpen(&hwi, device, &wf, (DWORD_PTR)chunk_ready_cb, (DWORD_PTR)u, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { result = waveInOpen(&hwi, device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
pa_log("failed to open waveIn"); if (result != MMSYSERR_NOERROR) {
pa_log_warn("Sample spec not supported by WaveIn, falling back to default sample rate.");
ss.rate = wf.nSamplesPerSec = m->core->default_sample_spec.rate;
}
result = waveInOpen(&hwi, device, &wf, (DWORD_PTR) chunk_ready_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
if (result != MMSYSERR_NOERROR) {
char errortext[MAXERRORLENGTH];
pa_log("Failed to open WaveIn.");
if (waveInGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
pa_log("Error: %s", errortext);
goto fail; goto fail;
} }
if (waveInStart(hwi) != MMSYSERR_NOERROR) { if (waveInStart(hwi) != MMSYSERR_NOERROR) {
pa_log("failed to start waveIn"); pa_log("failed to start waveIn");
goto fail; goto fail;
} }
pa_log_debug("Opened waveIn subsystem.");
} }
if (playback) { if (playback) {
if (waveOutOpen(&hwo, device, &wf, (DWORD_PTR)chunk_done_cb, (DWORD_PTR)u, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { result = waveOutOpen(&hwo, device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
pa_log("failed to open waveOut"); if (result != MMSYSERR_NOERROR) {
pa_log_warn("Sample spec not supported by WaveOut, falling back to default sample rate.");
ss.rate = wf.nSamplesPerSec = m->core->default_sample_spec.rate;
}
result = waveOutOpen(&hwo, device, &wf, (DWORD_PTR) chunk_done_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
if (result != MMSYSERR_NOERROR) {
char errortext[MAXERRORLENGTH];
pa_log("Failed to open WaveOut.");
if (waveOutGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
pa_log("Error: %s", errortext);
goto fail; goto fail;
} }
pa_log_debug("Opened waveOut subsystem.");
} }
InitializeCriticalSection(&u->crit); InitializeCriticalSection(&u->crit);