audio_win_int.c 3.1 KB

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