malc | d563163 | 2009-10-10 01:13:41 +0400 | [diff] [blame] | 1 | /* public domain */ |
| 2 | |
Peter Maydell | 6086a56 | 2016-01-18 17:33:52 +0000 | [diff] [blame] | 3 | #include "qemu/osdep.h" |
malc | d563163 | 2009-10-10 01:13:41 +0400 | [diff] [blame] | 4 | #include "qemu-common.h" |
malc | d563163 | 2009-10-10 01:13:41 +0400 | [diff] [blame] | 5 | |
| 6 | #define AUDIO_CAP "win-int" |
| 7 | #include <windows.h> |
| 8 | #include <mmsystem.h> |
| 9 | |
| 10 | #include "audio.h" |
| 11 | #include "audio_int.h" |
| 12 | #include "audio_win_int.h" |
| 13 | |
| 14 | int waveformat_from_audio_settings (WAVEFORMATEX *wfx, |
| 15 | struct audsettings *as) |
| 16 | { |
| 17 | memset (wfx, 0, sizeof (*wfx)); |
| 18 | |
| 19 | wfx->wFormatTag = WAVE_FORMAT_PCM; |
| 20 | wfx->nChannels = as->nchannels; |
| 21 | wfx->nSamplesPerSec = as->freq; |
| 22 | wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2); |
| 23 | wfx->nBlockAlign = 1 << (as->nchannels == 2); |
| 24 | wfx->cbSize = 0; |
| 25 | |
| 26 | switch (as->fmt) { |
| 27 | case AUD_FMT_S8: |
| 28 | case AUD_FMT_U8: |
| 29 | wfx->wBitsPerSample = 8; |
| 30 | break; |
| 31 | |
| 32 | case AUD_FMT_S16: |
| 33 | case AUD_FMT_U16: |
| 34 | wfx->wBitsPerSample = 16; |
| 35 | wfx->nAvgBytesPerSec <<= 1; |
| 36 | wfx->nBlockAlign <<= 1; |
| 37 | break; |
| 38 | |
| 39 | case AUD_FMT_S32: |
| 40 | case AUD_FMT_U32: |
| 41 | wfx->wBitsPerSample = 32; |
| 42 | wfx->nAvgBytesPerSec <<= 2; |
| 43 | wfx->nBlockAlign <<= 2; |
| 44 | break; |
| 45 | |
| 46 | default: |
| 47 | dolog ("Internal logic error: Bad audio format %d\n", as->freq); |
| 48 | return -1; |
| 49 | } |
| 50 | |
| 51 | return 0; |
| 52 | } |
| 53 | |
| 54 | int waveformat_to_audio_settings (WAVEFORMATEX *wfx, |
| 55 | struct audsettings *as) |
| 56 | { |
| 57 | if (wfx->wFormatTag != WAVE_FORMAT_PCM) { |
| 58 | dolog ("Invalid wave format, tag is not PCM, but %d\n", |
| 59 | wfx->wFormatTag); |
| 60 | return -1; |
| 61 | } |
| 62 | |
| 63 | if (!wfx->nSamplesPerSec) { |
| 64 | dolog ("Invalid wave format, frequency is zero\n"); |
| 65 | return -1; |
| 66 | } |
| 67 | as->freq = wfx->nSamplesPerSec; |
| 68 | |
| 69 | switch (wfx->nChannels) { |
| 70 | case 1: |
| 71 | as->nchannels = 1; |
| 72 | break; |
| 73 | |
| 74 | case 2: |
| 75 | as->nchannels = 2; |
| 76 | break; |
| 77 | |
| 78 | default: |
| 79 | dolog ( |
| 80 | "Invalid wave format, number of channels is not 1 or 2, but %d\n", |
| 81 | wfx->nChannels |
| 82 | ); |
| 83 | return -1; |
| 84 | } |
| 85 | |
| 86 | switch (wfx->wBitsPerSample) { |
| 87 | case 8: |
| 88 | as->fmt = AUD_FMT_U8; |
| 89 | break; |
| 90 | |
| 91 | case 16: |
| 92 | as->fmt = AUD_FMT_S16; |
| 93 | break; |
| 94 | |
| 95 | case 32: |
| 96 | as->fmt = AUD_FMT_S32; |
| 97 | break; |
| 98 | |
| 99 | default: |
| 100 | dolog ("Invalid wave format, bits per sample is not " |
| 101 | "8, 16 or 32, but %d\n", |
| 102 | wfx->wBitsPerSample); |
| 103 | return -1; |
| 104 | } |
| 105 | |
| 106 | return 0; |
| 107 | } |
| 108 | |