null.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 2010 by Chris Robinson
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  17. * Boston, MA 02111-1307, USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <stdlib.h>
  22. #include "alMain.h"
  23. #include "AL/al.h"
  24. #include "AL/alc.h"
  25. typedef struct {
  26. ALvoid *buffer;
  27. ALuint size;
  28. volatile int killNow;
  29. ALvoid *thread;
  30. } null_data;
  31. static const ALCchar nullDevice[] = "Null Output";
  32. static ALuint NullProc(ALvoid *ptr)
  33. {
  34. ALCdevice *Device = (ALCdevice*)ptr;
  35. null_data *data = (null_data*)Device->ExtraData;
  36. ALuint frameSize;
  37. ALuint now, last;
  38. ALuint avail;
  39. frameSize = aluFrameSizeFromFormat(Device->Format);
  40. last = timeGetTime()<<8;
  41. while(!data->killNow && Device->Connected)
  42. {
  43. now = timeGetTime()<<8;
  44. avail = (ALuint64)(now-last) * Device->Frequency / (1000<<8);
  45. if(avail < Device->UpdateSize)
  46. {
  47. Sleep(1);
  48. continue;
  49. }
  50. while(avail >= Device->UpdateSize)
  51. {
  52. aluMixData(Device, data->buffer, Device->UpdateSize);
  53. avail -= Device->UpdateSize;
  54. last += (ALuint64)Device->UpdateSize * (1000<<8) / Device->Frequency;
  55. }
  56. }
  57. return 0;
  58. }
  59. static ALCboolean null_open_playback(ALCdevice *device, const ALCchar *deviceName)
  60. {
  61. null_data *data;
  62. if(!deviceName)
  63. deviceName = nullDevice;
  64. else if(strcmp(deviceName, nullDevice) != 0)
  65. return ALC_FALSE;
  66. data = (null_data*)calloc(1, sizeof(*data));
  67. device->szDeviceName = strdup(deviceName);
  68. device->ExtraData = data;
  69. return ALC_TRUE;
  70. }
  71. static void null_close_playback(ALCdevice *device)
  72. {
  73. null_data *data = (null_data*)device->ExtraData;
  74. free(data);
  75. device->ExtraData = NULL;
  76. }
  77. static ALCboolean null_reset_playback(ALCdevice *device)
  78. {
  79. null_data *data = (null_data*)device->ExtraData;
  80. data->size = device->UpdateSize * aluFrameSizeFromFormat(device->Format);
  81. data->buffer = malloc(data->size);
  82. if(!data->buffer)
  83. {
  84. AL_PRINT("buffer malloc failed\n");
  85. return ALC_FALSE;
  86. }
  87. SetDefaultWFXChannelOrder(device);
  88. data->thread = StartThread(NullProc, device);
  89. if(data->thread == NULL)
  90. {
  91. free(data->buffer);
  92. data->buffer = NULL;
  93. return ALC_FALSE;
  94. }
  95. return ALC_TRUE;
  96. }
  97. static void null_stop_playback(ALCdevice *device)
  98. {
  99. null_data *data = (null_data*)device->ExtraData;
  100. if(!data->thread)
  101. return;
  102. data->killNow = 1;
  103. StopThread(data->thread);
  104. data->thread = NULL;
  105. data->killNow = 0;
  106. free(data->buffer);
  107. data->buffer = NULL;
  108. }
  109. static ALCboolean null_open_capture(ALCdevice *device, const ALCchar *deviceName)
  110. {
  111. (void)device;
  112. (void)deviceName;
  113. return ALC_FALSE;
  114. }
  115. BackendFuncs null_funcs = {
  116. null_open_playback,
  117. null_close_playback,
  118. null_reset_playback,
  119. null_stop_playback,
  120. null_open_capture,
  121. NULL,
  122. NULL,
  123. NULL,
  124. NULL,
  125. NULL
  126. };
  127. void alc_null_init(BackendFuncs *func_list)
  128. {
  129. *func_list = null_funcs;
  130. }
  131. void alc_null_deinit(void)
  132. {
  133. }
  134. void alc_null_probe(int type)
  135. {
  136. if(type == DEVICE_PROBE)
  137. AppendDeviceList(nullDevice);
  138. else if(type == ALL_DEVICE_PROBE)
  139. AppendAllDeviceList(nullDevice);
  140. }