Skip to content

Commit

Permalink
Windows Waveform Audio driver (no ADC support yet)
Browse files Browse the repository at this point in the history
Signed-off-by: malc <[email protected]>
  • Loading branch information
malc committed Oct 9, 2009
1 parent ad32308 commit d563163
Show file tree
Hide file tree
Showing 7 changed files with 449 additions and 97 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
audio-obj-$(CONFIG_FMOD) += fmodaudio.o
audio-obj-$(CONFIG_ESD) += esdaudio.o
audio-obj-$(CONFIG_PA) += paaudio.o
audio-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
audio-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
audio-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
audio-obj-y += wavcapture.o
obj-y += $(addprefix audio/, $(audio-obj-y))

Expand Down
1 change: 1 addition & 0 deletions audio/audio_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ extern struct audio_driver coreaudio_audio_driver;
extern struct audio_driver dsound_audio_driver;
extern struct audio_driver esd_audio_driver;
extern struct audio_driver pa_audio_driver;
extern struct audio_driver winwave_audio_driver;
extern struct mixeng_volume nominal_volume;

void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
Expand Down
108 changes: 108 additions & 0 deletions audio/audio_win_int.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* public domain */

#include "qemu-common.h"
#include "audio.h"

#define AUDIO_CAP "win-int"
#include <windows.h>
#include <mmsystem.h>

#include "audio.h"
#include "audio_int.h"
#include "audio_win_int.h"

int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as)
{
memset (wfx, 0, sizeof (*wfx));

wfx->wFormatTag = WAVE_FORMAT_PCM;
wfx->nChannels = as->nchannels;
wfx->nSamplesPerSec = as->freq;
wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
wfx->nBlockAlign = 1 << (as->nchannels == 2);
wfx->cbSize = 0;

switch (as->fmt) {
case AUD_FMT_S8:
case AUD_FMT_U8:
wfx->wBitsPerSample = 8;
break;

case AUD_FMT_S16:
case AUD_FMT_U16:
wfx->wBitsPerSample = 16;
wfx->nAvgBytesPerSec <<= 1;
wfx->nBlockAlign <<= 1;
break;

case AUD_FMT_S32:
case AUD_FMT_U32:
wfx->wBitsPerSample = 32;
wfx->nAvgBytesPerSec <<= 2;
wfx->nBlockAlign <<= 2;
break;

default:
dolog ("Internal logic error: Bad audio format %d\n", as->freq);
return -1;
}

return 0;
}

int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as)
{
if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
dolog ("Invalid wave format, tag is not PCM, but %d\n",
wfx->wFormatTag);
return -1;
}

if (!wfx->nSamplesPerSec) {
dolog ("Invalid wave format, frequency is zero\n");
return -1;
}
as->freq = wfx->nSamplesPerSec;

switch (wfx->nChannels) {
case 1:
as->nchannels = 1;
break;

case 2:
as->nchannels = 2;
break;

default:
dolog (
"Invalid wave format, number of channels is not 1 or 2, but %d\n",
wfx->nChannels
);
return -1;
}

switch (wfx->wBitsPerSample) {
case 8:
as->fmt = AUD_FMT_U8;
break;

case 16:
as->fmt = AUD_FMT_S16;
break;

case 32:
as->fmt = AUD_FMT_S32;
break;

default:
dolog ("Invalid wave format, bits per sample is not "
"8, 16 or 32, but %d\n",
wfx->wBitsPerSample);
return -1;
}

return 0;
}

10 changes: 10 additions & 0 deletions audio/audio_win_int.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef AUDIO_WIN_INT_H
#define AUDIO_WIN_INT_H

int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as);

int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as);

#endif /* AUDIO_WIN_INT_H */
97 changes: 2 additions & 95 deletions audio/dsoundaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include <objbase.h>
#include <dsound.h>

#include "audio_win_int.h"

/* #define DEBUG_DSOUND */

static struct {
Expand Down Expand Up @@ -304,101 +306,6 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
return -1;
}

static int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as)
{
memset (wfx, 0, sizeof (*wfx));

wfx->wFormatTag = WAVE_FORMAT_PCM;
wfx->nChannels = as->nchannels;
wfx->nSamplesPerSec = as->freq;
wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
wfx->nBlockAlign = 1 << (as->nchannels == 2);
wfx->cbSize = 0;

switch (as->fmt) {
case AUD_FMT_S8:
case AUD_FMT_U8:
wfx->wBitsPerSample = 8;
break;

case AUD_FMT_S16:
case AUD_FMT_U16:
wfx->wBitsPerSample = 16;
wfx->nAvgBytesPerSec <<= 1;
wfx->nBlockAlign <<= 1;
break;

case AUD_FMT_S32:
case AUD_FMT_U32:
wfx->wBitsPerSample = 32;
wfx->nAvgBytesPerSec <<= 2;
wfx->nBlockAlign <<= 2;
break;

default:
dolog ("Internal logic error: Bad audio format %d\n", as->freq);
return -1;
}

return 0;
}

static int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
struct audsettings *as)
{
if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
dolog ("Invalid wave format, tag is not PCM, but %d\n",
wfx->wFormatTag);
return -1;
}

if (!wfx->nSamplesPerSec) {
dolog ("Invalid wave format, frequency is zero\n");
return -1;
}
as->freq = wfx->nSamplesPerSec;

switch (wfx->nChannels) {
case 1:
as->nchannels = 1;
break;

case 2:
as->nchannels = 2;
break;

default:
dolog (
"Invalid wave format, number of channels is not 1 or 2, but %d\n",
wfx->nChannels
);
return -1;
}

switch (wfx->wBitsPerSample) {
case 8:
as->fmt = AUD_FMT_U8;
break;

case 16:
as->fmt = AUD_FMT_S16;
break;

case 32:
as->fmt = AUD_FMT_S32;
break;

default:
dolog ("Invalid wave format, bits per sample is not "
"8, 16 or 32, but %d\n",
wfx->wBitsPerSample);
return -1;
}

return 0;
}

#include "dsound_template.h"
#define DSBTYPE_IN
#include "dsound_template.h"
Expand Down
Loading

0 comments on commit d563163

Please sign in to comment.