qemu/audio/audio_win_int.c
<<
>>
Prefs
   1/* public domain */
   2
   3#include "qemu/osdep.h"
   4
   5#define AUDIO_CAP "win-int"
   6#include <windows.h>
   7#include <mmreg.h>
   8#include <mmsystem.h>
   9
  10#include "audio.h"
  11#include "audio_int.h"
  12#include "audio_win_int.h"
  13
  14int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
  15                                    struct audsettings *as)
  16{
  17    memset (wfx, 0, sizeof (*wfx));
  18
  19    wfx->nChannels = as->nchannels;
  20    wfx->nSamplesPerSec = as->freq;
  21    wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
  22    wfx->nBlockAlign = 1 << (as->nchannels == 2);
  23    wfx->cbSize = 0;
  24
  25    switch (as->fmt) {
  26    case AUDIO_FORMAT_S8:
  27    case AUDIO_FORMAT_U8:
  28        wfx->wFormatTag = WAVE_FORMAT_PCM;
  29        wfx->wBitsPerSample = 8;
  30        break;
  31
  32    case AUDIO_FORMAT_S16:
  33    case AUDIO_FORMAT_U16:
  34        wfx->wFormatTag = WAVE_FORMAT_PCM;
  35        wfx->wBitsPerSample = 16;
  36        wfx->nAvgBytesPerSec <<= 1;
  37        wfx->nBlockAlign <<= 1;
  38        break;
  39
  40    case AUDIO_FORMAT_S32:
  41    case AUDIO_FORMAT_U32:
  42        wfx->wFormatTag = WAVE_FORMAT_PCM;
  43        wfx->wBitsPerSample = 32;
  44        wfx->nAvgBytesPerSec <<= 2;
  45        wfx->nBlockAlign <<= 2;
  46        break;
  47
  48    case AUDIO_FORMAT_F32:
  49        wfx->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
  50        wfx->wBitsPerSample = 32;
  51        wfx->nAvgBytesPerSec <<= 2;
  52        wfx->nBlockAlign <<= 2;
  53        break;
  54
  55    default:
  56        dolog("Internal logic error: Bad audio format %d\n", as->fmt);
  57        return -1;
  58    }
  59
  60    return 0;
  61}
  62
  63int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
  64                                  struct audsettings *as)
  65{
  66    if (!wfx->nSamplesPerSec) {
  67        dolog ("Invalid wave format, frequency is zero\n");
  68        return -1;
  69    }
  70    as->freq = wfx->nSamplesPerSec;
  71
  72    switch (wfx->nChannels) {
  73    case 1:
  74        as->nchannels = 1;
  75        break;
  76
  77    case 2:
  78        as->nchannels = 2;
  79        break;
  80
  81    default:
  82        dolog (
  83            "Invalid wave format, number of channels is not 1 or 2, but %d\n",
  84            wfx->nChannels
  85            );
  86        return -1;
  87    }
  88
  89    if (wfx->wFormatTag == WAVE_FORMAT_PCM) {
  90        switch (wfx->wBitsPerSample) {
  91        case 8:
  92            as->fmt = AUDIO_FORMAT_U8;
  93            break;
  94
  95        case 16:
  96            as->fmt = AUDIO_FORMAT_S16;
  97            break;
  98
  99        case 32:
 100            as->fmt = AUDIO_FORMAT_S32;
 101            break;
 102
 103        default:
 104            dolog("Invalid PCM wave format, bits per sample is not "
 105                  "8, 16 or 32, but %d\n",
 106                  wfx->wBitsPerSample);
 107            return -1;
 108        }
 109    } else if (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
 110        switch (wfx->wBitsPerSample) {
 111        case 32:
 112            as->fmt = AUDIO_FORMAT_F32;
 113            break;
 114
 115        default:
 116            dolog("Invalid IEEE_FLOAT wave format, bits per sample is not "
 117                  "32, but %d\n",
 118                  wfx->wBitsPerSample);
 119            return -1;
 120        }
 121    } else {
 122        dolog("Invalid wave format, tag is not PCM and not IEEE_FLOAT, "
 123              "but %d\n",
 124              wfx->wFormatTag);
 125        return -1;
 126    }
 127
 128    return 0;
 129}
 130
 131